45 source_type(source_type),
46 first_station(first_station)
62 periods_in_transit(periods_in_transit),
63 feeder_share(feeder_share),
65 first_station(first_station)
79 periods_in_transit(original.periods_in_transit),
80 feeder_share(feeder_share),
81 source_xy(original.source_xy),
82 travelled(original.travelled),
83 source_id(original.source_id),
84 source_type(original.source_type),
86 in_vehicle(original.in_vehicle),
88 first_station(original.first_station),
89 next_hop(original.next_hop)
106 this->
count -= new_size;
127 assert(count < this->
count);
129 this->count -=
count;
140 if (cp->source_type == src_type && cp->source_id == src) cp->source_id =
INVALID_SOURCE;
151 if (cp->first_station == sid) cp->first_station = INVALID_STATION;
164template <
class Tinst,
class Tcont>
167 for (
Iterator it(this->packets.begin()); it != this->packets.end(); ++it) {
176template <
class Tinst,
class Tcont>
179 this->packets.clear();
188template <
class Tinst,
class Tcont>
191 assert(count <= cp->count);
192 this->count -= count;
193 this->cargo_periods_in_transit -=
static_cast<uint64_t
>(cp->
periods_in_transit) * count;
201template <
class Tinst,
class Tcont>
204 this->count += cp->
count;
209template <
class Tinst,
class Tcont>
213 this->cargo_periods_in_transit = 0;
215 for (
ConstIterator it(this->packets.begin()); it != this->packets.end(); it++) {
216 static_cast<Tinst *
>(
this)->AddToCache(*it);
227template <
class Tinst,
class Tcont>
230 if (Tinst::AreMergable(icp, cp) &&
262 assert(cp !=
nullptr);
272 uint sum = cp->
count;
294template<
class Taction>
298 while (it != this->
packets.end() && action.MaxMove() > 0) {
316template<
class Taction>
319 if (this->
packets.empty())
return;
322 while (action.MaxMove() > 0) {
393 for (
const auto &cp : this->
packets) {
412 StationID current_station,
bool accepted,
StationIDStack next_station)
414 if (cargo_next == INVALID_STATION) {
416 }
else if (cargo_next == current_station) {
418 }
else if (next_station.
Contains(cargo_next)) {
450 bool force_unload = (order_flags &
OUFB_UNLOAD) != 0;
453 while (sum < this->
count) {
457 StationID cargo_next = INVALID_STATION;
461 }
else if (force_unload && accepted && cp->
first_station != current_station) {
463 }
else if (force_transfer) {
468 if (flow_it == ge->
flows.end()) {
469 cargo_next = INVALID_STATION;
471 FlowStat new_shares = flow_it->second;
478 cargo_next = INVALID_STATION;
480 cargo_next = new_shares.
GetVia();
489 bool restricted =
false;
491 if (flow_it == ge->
flows.end()) {
492 cargo_next = INVALID_STATION;
494 cargo_next = flow_it->second.GetViaWithRestricted(restricted);
500 cargo_next = flow_it->second.GetVia();
508 if (deliver == this->
packets.end()) --deliver;
511 this->
packets.insert(deliver, cp);
550template<VehicleCargoList::MoveToAction Tfrom, VehicleCargoList::MoveToAction Tto>
554 static_assert(Tfrom - Tto == 1 || Tto - Tfrom == 1);
568uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_TRANSFER>(uint max_move)
570 max_move = std::min(this->action_counts[MTA_DELIVER], max_move);
573 for (Iterator it(this->packets.begin()); sum < this->action_counts[MTA_TRANSFER] + max_move;) {
576 if (sum <= this->action_counts[MTA_TRANSFER])
continue;
577 if (sum > this->action_counts[MTA_TRANSFER] + max_move) {
578 CargoPacket *cp_split = cp->
Split(sum - this->action_counts[MTA_TRANSFER] + max_move);
579 sum -= cp_split->
Count();
580 this->packets.insert(it, cp_split);
585 this->action_counts[MTA_DELIVER] -= max_move;
586 this->action_counts[MTA_TRANSFER] += max_move;
613 max_move = std::min(this->
count, max_move);
652 max_move = std::min(this->
count, max_move);
688 assert(cp !=
nullptr);
691 StationCargoPacketMap::List &list = this->
packets[next];
692 for (StationCargoPacketMap::List::reverse_iterator it(list.rbegin());
693 it != list.rend(); it++) {
713template <
class Taction>
717 for (
Iterator it(range.first); it != range.second && it.GetKey() == next;) {
718 if (action.MaxMove() == 0)
return false;
743template <
class Taction>
746 uint max_move = action.MaxMove();
749 if (action.MaxMove() == 0)
break;
751 if (include_invalid && action.MaxMove() > 0) {
754 return max_move - action.MaxMove();
767 max_move = std::min(max_move, this->
count);
768 uint prev_count = this->
count;
771 bool do_count = cargo_per_source !=
nullptr;
772 while (max_move > moved) {
775 if (prev_count > max_move &&
RandomRange(prev_count) < prev_count - max_move) {
776 if (do_count && loop == 0) {
782 uint diff = max_move - moved;
783 if (cp->
count > diff) {
790 if (do_count) (*cargo_per_source)[cp->
first_station] -= diff;
798 if (do_count && loop > 0) {
844 return this->
ShiftCargo(
CargoLoad(
this, dest, max_move, current_tile), next_station,
true);
866template uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_KEEP>(uint);
uint8_t CargoID
Cargo slots to indicate a cargo type within a game.
uint16_t SourceID
Contains either industry ID, town ID or company ID (or INVALID_SOURCE)
static const SourceID INVALID_SOURCE
Invalid/unknown index of source.
SourceType
Types of cargo source and destination.
@ Industry
Source/destination is an industry.
Actions to be applied to cargo packets.
Action of final delivery of cargo.
Simple collection class for a list of cargo packets.
Tcont::reverse_iterator ReverseIterator
The reverse iterator for our container.
void OnCleanPool()
Empty the cargo list, but don't free the cargo packets; the cargo packets are cleaned by CargoPacket'...
MoveToAction
Kind of actions that could be done with packets on move.
@ MTA_KEEP
Keep the cargo in the vehicle.
@ MTA_DELIVER
Deliver the cargo to some town or industry.
@ MTA_LOAD
Load the cargo from the station.
@ MTA_TRANSFER
Transfer the cargo to the station.
CargoPacketList packets
The cargo packets in this list.
~CargoList()
Destroy the cargolist ("frees" all cargo packets).
Tcont::const_iterator ConstIterator
The const iterator for our container.
uint count
Cache for the number of cargo entities.
uint64_t cargo_periods_in_transit
Cache for the sum of number of cargo aging periods in transit of each entity; comparable to man-hours...
static bool TryMerge(CargoPacket *cp, CargoPacket *icp)
Tries to merge the second packet into the first and return if that was successful.
Tcont::iterator Iterator
The iterator for our container.
void AddToCache(const CargoPacket *cp)
Update the cache to reflect adding of this packet.
void InvalidateCache()
Invalidates the cached data and rebuilds it.
void RemoveFromCache(const CargoPacket *cp, uint count)
Update the cached values to reflect the removal of this packet or part of it.
Action of loading cargo from a station onto a vehicle.
Abstract action of removing cargo from a vehicle or a station.
Action of reserving cargo from a station to be loaded onto a vehicle.
Action of returning previously reserved cargo from the vehicle to the station.
Action of shifting cargo from one vehicle to another.
Action of transferring cargo from a vehicle to a station.
Flow statistics telling how much flow should be sent along a link.
StationID GetVia() const
Get a station a package can be routed to.
const SharesMap * GetShares() const
Get the actual shares as a const pointer so that they can be iterated over.
void ChangeShare(StationID st, int flow)
Change share for specified station.
iterator erase(iterator it)
Erase the value pointed to by an iterator.
std::pair< iterator, iterator > equal_range(const Tkey &key)
Get a pair of iterators specifying a range of items with equal keys.
Minimal stack that uses a pool to avoid pointers.
bool Contains(const Titem &item) const
Check if the given item is contained in the stack.
Titem Pop()
Pop an item from the stack.
bool IsEmpty() const
Check if the stack is empty.
CargoList that is used for stations.
uint Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
Routes packets with station "avoid" as next hop to a different place.
void Append(CargoPacket *cp, StationID next)
Appends the given cargo packet to the range of packets with the same next station.
uint Reserve(uint max_move, VehicleCargoList *dest, StationIDStack next, TileIndex current_tile)
Reserves cargo for loading onto the vehicle.
uint Truncate(uint max_move=UINT_MAX, StationCargoAmountMap *cargo_per_source=nullptr)
Truncates where each destination loses roughly the same percentage of its cargo.
bool ShiftCargo(Taction &action, StationID next)
Shifts cargo from the front of the packet list for a specific station and applies some action to it.
uint reserved_count
Amount of cargo being reserved for loading.
uint Load(uint max_move, VehicleCargoList *dest, StationIDStack next, TileIndex current_tile)
Loads cargo onto a vehicle.
Action of rerouting cargo in a station.
CargoList that is used for vehicles.
uint Shift(uint max_move, VehicleCargoList *dest)
Shifts cargo between two vehicles.
void AddToMeta(const CargoPacket *cp, MoveToAction action)
Adds a packet to the metadata.
bool Stage(bool accepted, StationID current_station, StationIDStack next_station, uint8_t order_flags, const GoodsEntry *ge, CargoID cargo, CargoPayment *payment, TileIndex current_tile)
Stages cargo for unloading.
void PopCargo(Taction action)
Pops cargo from the back of the packet list and applies some action to it.
uint Reroute(uint max_move, VehicleCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
Routes packets with station "avoid" as next hop to a different place.
uint ActionCount(MoveToAction action) const
Returns the amount of cargo designated for a given purpose.
uint Truncate(uint max_move=UINT_MAX)
Truncates the cargo in this list to the given amount.
uint Unload(uint max_move, StationCargoList *dest, CargoID cargo, CargoPayment *payment, TileIndex current_tile)
Unloads cargo at the given station.
void AssertCountConsistency() const
Assert that the designation counts add up.
void RemoveFromMeta(const CargoPacket *cp, MoveToAction action, uint count)
Removes a packet or part of it from the metadata.
uint Return(uint max_move, StationCargoList *dest, StationID next_station, TileIndex current_tile)
Returns reserved cargo to the station and removes it from the cache.
uint action_counts[NUM_MOVE_TO_ACTION]
Counts of cargo to be transferred, delivered, kept and loaded.
static MoveToAction ChooseAction(const CargoPacket *cp, StationID cargo_next, StationID current_station, bool accepted, StationIDStack next_station)
Choose action to be performed with the given cargo packet.
Money feeder_share
Cache for the feeder share.
void Append(CargoPacket *cp, MoveToAction action=MTA_KEEP)
Appends the given cargo packet.
void RemoveFromCache(const CargoPacket *cp, uint count)
Update the cached values to reflect the removal of this packet or part of it.
uint Reassign(uint max_move)
Moves some cargo from one designation to another.
void InvalidateCache()
Invalidates the cached data and rebuild it.
void AddToCache(const CargoPacket *cp)
Update the cache to reflect adding of this packet.
void AgeCargo()
Ages the all cargo in this list.
void ShiftCargo(Taction action)
Shifts cargo from the front of the packet list and applies some action to it.
Action of rerouting cargo staged for transfer in a vehicle.
Base classes related to the economy.
@ OUFB_TRANSFER
Transfer all cargo onto the platform.
@ OUFB_NO_UNLOAD
Totally no unloading will be done.
@ OUFB_UNLOAD
Force unloading all cargo onto the platform, possibly not getting paid.
Some methods of Pool are placed here in order to reduce compilation time and binary size.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
Pseudo random number generator.
uint32_t RandomRange(uint32_t limit, const std::source_location location=std::source_location::current())
Pick a random number between 0 and limit - 1, inclusive.
A number of safeguards to prevent using unsafe methods.
Base classes/functions for stations.
Definition of base types and functions in a cross-platform compatible way.
Container for cargo from the same location and time.
void Reduce(uint count)
Reduce the packet by the given amount and remove the feeder share.
uint16_t Count() const
Gets the number of 'items' in this packet.
void Merge(CargoPacket *cp)
Merge another packet into this one.
Money feeder_share
Value of feeder pickup to be paid for on delivery of cargo.
static const uint16_t MAX_COUNT
Maximum number of items in a single cargo packet.
CargoPacket * Split(uint new_size)
Split this packet in two and return the split off part.
StationID next_hop
Station where the cargo wants to go next.
void AddFeederShare(Money new_share)
Adds some feeder share to the packet.
uint16_t count
The amount of cargo in this packet.
CargoPacket()
Create a new packet for savegame loading.
Money GetFeederShare() const
Gets the amount of money already paid to earlier vehicles in the feeder chain.
StationID first_station
The station where the cargo came from first.
static void InvalidateAllFrom(SourceType src_type, SourceID src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
uint16_t periods_in_transit
Amount of cargo aging periods this packet has been in transit.
Helper class to perform the cargo payment.
Money PayTransfer(CargoID cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
Handle payment for transfer of the given cargo packet.
Stores station stats for a single cargo.
FlowStatMap flows
Planned flows through this station.
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Base class for all pools.