OpenTTD Source: src/cargopacket.cpp Source File

OpenTTD Source 15.3

cargopacket.cpp
Go to the documentation of this file.
1/*
2 * This file is part of OpenTTD.
3 * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
4 * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
5 * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <https://www.gnu.org/licenses/old-licenses/gpl-2.0>.
6 */
7
10#include "stdafx.h"
11#include "station_base.h"
12#include "core/pool_func.hpp"
13#include "core/random_func.hpp"
14#include "economy_base.h"
15#include "cargoaction.h"
16#include "order_type.h"
17
18#include "safeguards.h"
19
20/* Initialize the cargopacket-pool */
21 CargoPacketPool _cargopacket_pool("CargoPacket");
22 INSTANTIATE_POOL_METHODS(CargoPacket)
23
24
27 CargoPacket::CargoPacket()
28{
29}
30
39 CargoPacket::CargoPacket(StationID first_station,uint16_t count, Source source) :
40 count(count),
41 source(source),
42 first_station(first_station)
43{
44 assert(count != 0);
45}
46
56 CargoPacket::CargoPacket(uint16_t count, uint16_t periods_in_transit, StationID first_station, TileIndex source_xy, Money feeder_share) :
57 count(count),
58 periods_in_transit(periods_in_transit),
59 feeder_share(feeder_share),
60 source_xy(source_xy),
61 first_station(first_station)
62{
63 assert(count != 0);
64}
65
73 CargoPacket::CargoPacket(uint16_t count, Money feeder_share, CargoPacket &original) :
74 count(count),
75 periods_in_transit(original.periods_in_transit),
76 feeder_share(feeder_share),
77 source_xy(original.source_xy),
78 travelled(original.travelled),
79 source(original.source),
80#ifdef WITH_ASSERT
81 in_vehicle(original.in_vehicle),
82#endif /* WITH_ASSERT */
83 first_station(original.first_station),
84 next_hop(original.next_hop)
85{
86 assert(count != 0);
87}
88
94 CargoPacket *CargoPacket::Split(uint new_size)
95{
96 if (!CargoPacket::CanAllocateItem()) return nullptr;
97
98 Money fs = this->GetFeederShare(new_size);
99 CargoPacket *cp_new = new CargoPacket(new_size, fs, *this);
100 this->feeder_share -= fs;
101 this->count -= new_size;
102 return cp_new;
103}
104
109 void CargoPacket::Merge(CargoPacket *cp)
110{
111 this->count += cp->count;
112 this->feeder_share += cp->feeder_share;
113 delete cp;
114}
115
120 void CargoPacket::Reduce(uint count)
121{
122 assert(count < this->count);
123 this->feeder_share -= this->GetFeederShare(count);
124 this->count -= count;
125}
126
132/* static */ void CargoPacket::InvalidateAllFrom(Source src)
133{
134 for (CargoPacket *cp : CargoPacket::Iterate()) {
135 if (cp->source == src) cp->source.MakeInvalid();
136 }
137}
138
143/* static */ void CargoPacket::InvalidateAllFrom(StationID sid)
144{
145 for (CargoPacket *cp : CargoPacket::Iterate()) {
146 if (cp->first_station == sid) cp->first_station = StationID::Invalid();
147 }
148}
149
150/*
151 *
152 * Cargo list implementation
153 *
154 */
155
159template <class Tinst, class Tcont>
160CargoList<Tinst, Tcont>::~CargoList()
161{
162 for (Iterator it(this->packets.begin()); it != this->packets.end(); ++it) {
163 delete *it;
164 }
165}
166
171template <class Tinst, class Tcont>
172 void CargoList<Tinst, Tcont>::OnCleanPool()
173{
174 this->packets.clear();
175}
176
183template <class Tinst, class Tcont>
184 void CargoList<Tinst, Tcont>::RemoveFromCache(const CargoPacket *cp, uint count)
185{
186 assert(count <= cp->count);
187 this->count -= count;
188 this->cargo_periods_in_transit -= static_cast<uint64_t>(cp->periods_in_transit) * count;
189}
190
196template <class Tinst, class Tcont>
197 void CargoList<Tinst, Tcont>::AddToCache(const CargoPacket *cp)
198{
199 this->count += cp->count;
200 this->cargo_periods_in_transit += static_cast<uint64_t>(cp->periods_in_transit) * cp->count;
201}
202
204template <class Tinst, class Tcont>
205 void CargoList<Tinst, Tcont>::InvalidateCache()
206{
207 this->count = 0;
208 this->cargo_periods_in_transit = 0;
209
210 for (ConstIterator it(this->packets.begin()); it != this->packets.end(); it++) {
211 static_cast<Tinst *>(this)->AddToCache(*it);
212 }
213}
214
222template <class Tinst, class Tcont>
223/* static */ bool CargoList<Tinst, Tcont>::TryMerge(CargoPacket *icp, CargoPacket *cp)
224{
225 if (Tinst::AreMergable(icp, cp) &&
226 icp->count + cp->count <= CargoPacket::MAX_COUNT) {
227 icp->Merge(cp);
228 return true;
229 } else {
230 return false;
231 }
232}
233
234/*
235 *
236 * Vehicle cargo list implementation.
237 *
238 */
239
255 void VehicleCargoList::Append(CargoPacket *cp, MoveToAction action)
256{
257 assert(cp != nullptr);
258 assert(action == MTA_LOAD ||
259 (action == MTA_KEEP && this->action_counts[MTA_LOAD] == 0));
260 this->AddToMeta(cp, action);
261
262 if (this->count == cp->count) {
263 this->packets.push_back(cp);
264 return;
265 }
266
267 uint sum = cp->count;
268 for (ReverseIterator it(this->packets.rbegin()); it != this->packets.rend(); it++) {
269 CargoPacket *icp = *it;
270 if (VehicleCargoList::TryMerge(icp, cp)) return;
271 sum += icp->count;
272 if (sum >= this->action_counts[action]) {
273 this->packets.push_back(cp);
274 return;
275 }
276 }
277
278 NOT_REACHED();
279}
280
289template <class Taction>
290 void VehicleCargoList::ShiftCargo(Taction action)
291{
292 Iterator it(this->packets.begin());
293 while (it != this->packets.end() && action.MaxMove() > 0) {
294 CargoPacket *cp = *it;
295 if (action(cp)) {
296 it = this->packets.erase(it);
297 } else {
298 break;
299 }
300 }
301}
302
311template <class Taction>
312 void VehicleCargoList::PopCargo(Taction action)
313{
314 if (this->packets.empty()) return;
315 Iterator it(--(this->packets.end()));
316 Iterator begin(this->packets.begin());
317 while (action.MaxMove() > 0) {
318 CargoPacket *cp = *it;
319 if (action(cp)) {
320 if (it != begin) {
321 this->packets.erase(it--);
322 } else {
323 this->packets.erase(it);
324 break;
325 }
326 } else {
327 break;
328 }
329 }
330}
331
338 void VehicleCargoList::RemoveFromCache(const CargoPacket *cp, uint count)
339{
340 this->feeder_share -= cp->GetFeederShare(count);
341 this->Parent::RemoveFromCache(cp, count);
342}
343
349 void VehicleCargoList::AddToCache(const CargoPacket *cp)
350{
351 this->feeder_share += cp->feeder_share;
352 this->Parent::AddToCache(cp);
353}
354
361 void VehicleCargoList::RemoveFromMeta(const CargoPacket *cp, MoveToAction action, uint count)
362{
363 assert(count <= this->action_counts[action]);
364 this->AssertCountConsistency();
365 this->RemoveFromCache(cp, count);
366 this->action_counts[action] -= count;
367 this->AssertCountConsistency();
368}
369
375 void VehicleCargoList::AddToMeta(const CargoPacket *cp, MoveToAction action)
376{
377 this->AssertCountConsistency();
378 this->AddToCache(cp);
379 this->action_counts[action] += cp->count;
380 this->AssertCountConsistency();
381}
382
386 void VehicleCargoList::AgeCargo()
387{
388 for (const auto &cp : this->packets) {
389 /* If we're at the maximum, then we can't increase no more. */
390 if (cp->periods_in_transit == UINT16_MAX) continue;
391
392 cp->periods_in_transit++;
393 this->cargo_periods_in_transit += cp->count;
394 }
395}
396
406/* static */ VehicleCargoList::MoveToAction VehicleCargoList::ChooseAction(const CargoPacket *cp, StationID cargo_next,
407 StationID current_station, bool accepted, std::span<const StationID> next_station)
408{
409 if (cargo_next == StationID::Invalid()) {
410 return (accepted && cp->first_station != current_station) ? MTA_DELIVER : MTA_KEEP;
411 } else if (cargo_next == current_station) {
412 return MTA_DELIVER;
413 } else if (std::ranges::find(next_station, cargo_next) != std::end(next_station)) {
414 return MTA_KEEP;
415 } else {
416 return MTA_TRANSFER;
417 }
418}
419
435 bool VehicleCargoList::Stage(bool accepted, StationID current_station, std::span<const StationID> next_station, OrderUnloadType unload_type, const GoodsEntry *ge, CargoType cargo, CargoPayment *payment, TileIndex current_tile)
436{
437 this->AssertCountConsistency();
438 assert(this->action_counts[MTA_LOAD] == 0);
439 this->action_counts[MTA_TRANSFER] = this->action_counts[MTA_DELIVER] = this->action_counts[MTA_KEEP] = 0;
440 Iterator deliver = this->packets.end();
441 Iterator it = this->packets.begin();
442 uint sum = 0;
443
444 static const FlowStatMap EMPTY_FLOW_STAT_MAP = {};
445 const FlowStatMap &flows = ge->HasData() ? ge->GetData().flows : EMPTY_FLOW_STAT_MAP;
446
447 bool force_keep = unload_type == OrderUnloadType::NoUnload;
448 bool force_unload = unload_type == OrderUnloadType::Unload;
449 bool force_transfer = unload_type == OrderUnloadType::Transfer || unload_type == OrderUnloadType::Unload;
450 assert(this->count > 0 || it == this->packets.end());
451 while (sum < this->count) {
452 CargoPacket *cp = *it;
453
454 this->packets.erase(it++);
455 StationID cargo_next = StationID::Invalid();
456 MoveToAction action = MTA_LOAD;
457 if (force_keep) {
458 action = MTA_KEEP;
459 } else if (force_unload && accepted && cp->first_station != current_station) {
460 action = MTA_DELIVER;
461 } else if (force_transfer) {
462 action = MTA_TRANSFER;
463 /* We cannot send the cargo to any of the possible next hops and
464 * also not to the current station. */
465 FlowStatMap::const_iterator flow_it(flows.find(cp->first_station));
466 if (flow_it == flows.end()) {
467 cargo_next = StationID::Invalid();
468 } else {
469 FlowStat new_shares = flow_it->second;
470 new_shares.ChangeShare(current_station, INT_MIN);
471 for (auto station_it = next_station.rbegin(); station_it != next_station.rend(); ++station_it) {
472 if (new_shares.GetShares()->empty()) break;
473 new_shares.ChangeShare(*station_it, INT_MIN);
474 }
475 if (new_shares.GetShares()->empty()) {
476 cargo_next = StationID::Invalid();
477 } else {
478 cargo_next = new_shares.GetVia();
479 }
480 }
481 } else {
482 /* Rewrite an invalid source station to some random other one to
483 * avoid keeping the cargo in the vehicle forever. */
484 if (cp->first_station == StationID::Invalid() && !flows.empty()) {
485 cp->first_station = flows.begin()->first;
486 }
487 bool restricted = false;
488 FlowStatMap::const_iterator flow_it(flows.find(cp->first_station));
489 if (flow_it == flows.end()) {
490 cargo_next = StationID::Invalid();
491 } else {
492 cargo_next = flow_it->second.GetViaWithRestricted(restricted);
493 }
494 action = VehicleCargoList::ChooseAction(cp, cargo_next, current_station, accepted, next_station);
495 if (restricted && action == MTA_TRANSFER) {
496 /* If the flow is restricted we can't transfer to it. Choose an
497 * unrestricted one instead. */
498 cargo_next = flow_it->second.GetVia();
499 action = VehicleCargoList::ChooseAction(cp, cargo_next, current_station, accepted, next_station);
500 }
501 }
502 Money share;
503 switch (action) {
504 case MTA_KEEP:
505 this->packets.push_back(cp);
506 if (deliver == this->packets.end()) --deliver;
507 break;
508 case MTA_DELIVER:
509 this->packets.insert(deliver, cp);
510 break;
511 case MTA_TRANSFER:
512 this->packets.push_front(cp);
513 /* Add feeder share here to allow reusing field for next station. */
514 share = payment->PayTransfer(cargo, cp, cp->count, current_tile);
515 cp->AddFeederShare(share);
516 this->feeder_share += share;
517 cp->next_hop = cargo_next;
518 break;
519 default:
520 NOT_REACHED();
521 }
522 this->action_counts[action] += cp->count;
523 sum += cp->count;
524 }
525 this->AssertCountConsistency();
526 return this->action_counts[MTA_DELIVER] > 0 || this->action_counts[MTA_TRANSFER] > 0;
527}
528
530 void VehicleCargoList::InvalidateCache()
531{
532 this->feeder_share = 0;
533 this->Parent::InvalidateCache();
534}
535
548template <VehicleCargoList::MoveToAction Tfrom, VehicleCargoList::MoveToAction Tto>
549uint VehicleCargoList::Reassign(uint max_move)
550{
551 static_assert(Tfrom != MTA_TRANSFER && Tto != MTA_TRANSFER);
552 static_assert(Tfrom - Tto == 1 || Tto - Tfrom == 1);
553 max_move = std::min(this->action_counts[Tfrom], max_move);
554 this->action_counts[Tfrom] -= max_move;
555 this->action_counts[Tto] += max_move;
556 return max_move;
557}
558
565template <>
566uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_TRANSFER>(uint max_move)
567{
568 max_move = std::min(this->action_counts[MTA_DELIVER], max_move);
569
570 uint sum = 0;
571 for (Iterator it(this->packets.begin()); sum < this->action_counts[MTA_TRANSFER] + max_move;) {
572 CargoPacket *cp = *it++;
573 sum += cp->Count();
574 if (sum <= this->action_counts[MTA_TRANSFER]) continue;
575 if (sum > this->action_counts[MTA_TRANSFER] + max_move) {
576 CargoPacket *cp_split = cp->Split(sum - this->action_counts[MTA_TRANSFER] + max_move);
577 sum -= cp_split->Count();
578 this->packets.insert(it, cp_split);
579 }
580 cp->next_hop = StationID::Invalid();
581 }
582
583 this->action_counts[MTA_DELIVER] -= max_move;
584 this->action_counts[MTA_TRANSFER] += max_move;
585 return max_move;
586}
587
596uint VehicleCargoList::Return(uint max_move, StationCargoList *dest, StationID next, TileIndex current_tile)
597{
598 max_move = std::min(this->action_counts[MTA_LOAD], max_move);
599 this->PopCargo(CargoReturn(this, dest, max_move, next, current_tile));
600 return max_move;
601}
602
609uint VehicleCargoList::Shift(uint max_move, VehicleCargoList *dest)
610{
611 max_move = std::min(this->count, max_move);
612 this->PopCargo(CargoShift(this, dest, max_move));
613 return max_move;
614}
615
626uint VehicleCargoList::Unload(uint max_move, StationCargoList *dest, CargoType cargo, CargoPayment *payment, TileIndex current_tile)
627{
628 uint moved = 0;
629 if (this->action_counts[MTA_TRANSFER] > 0) {
630 uint move = std::min(this->action_counts[MTA_TRANSFER], max_move);
631 this->ShiftCargo(CargoTransfer(this, dest, move, current_tile));
632 moved += move;
633 }
634 if (this->action_counts[MTA_TRANSFER] == 0 && this->action_counts[MTA_DELIVER] > 0 && moved < max_move) {
635 uint move = std::min(this->action_counts[MTA_DELIVER], max_move - moved);
636 this->ShiftCargo(CargoDelivery(this, move, cargo, payment, current_tile));
637 moved += move;
638 }
639 return moved;
640}
641
648uint VehicleCargoList::Truncate(uint max_move)
649{
650 max_move = std::min(this->count, max_move);
651 this->PopCargo(CargoRemoval<VehicleCargoList>(this, max_move));
652 return max_move;
653}
654
663uint VehicleCargoList::Reroute(uint max_move, VehicleCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
664{
665 max_move = std::min(this->action_counts[MTA_TRANSFER], max_move);
666 this->ShiftCargo(VehicleCargoReroute(this, dest, max_move, avoid, avoid2, ge));
667 return max_move;
668}
669
670/*
671 *
672 * Station cargo list implementation.
673 *
674 */
675
684 void StationCargoList::Append(CargoPacket *cp, StationID next)
685{
686 assert(cp != nullptr);
687 this->AddToCache(cp);
688
689 StationCargoPacketMap::List &list = this->packets[next];
690 for (StationCargoPacketMap::List::reverse_iterator it(list.rbegin());
691 it != list.rend(); it++) {
692 if (StationCargoList::TryMerge(*it, cp)) return;
693 }
694
695 /* The packet could not be merged with another one */
696 list.push_back(cp);
697}
698
711template <class Taction>
712 bool StationCargoList::ShiftCargo(Taction &action, StationID next)
713{
714 std::pair<Iterator, Iterator> range(this->packets.equal_range(next));
715 for (Iterator it(range.first); it != range.second && it.GetKey() == next;) {
716 if (action.MaxMove() == 0) return false;
717 CargoPacket *cp = *it;
718 if (action(cp)) {
719 it = this->packets.erase(it);
720 } else {
721 return false;
722 }
723 }
724 return true;
725}
726
741template <class Taction>
742uint StationCargoList::ShiftCargo(Taction action, std::span<const StationID> next, bool include_invalid)
743{
744 uint max_move = action.MaxMove();
745 for (auto it = next.rbegin(); it != next.rend(); ++it) {
746 this->ShiftCargo(action, *it);
747 if (action.MaxMove() == 0) break;
748 }
749 if (include_invalid && action.MaxMove() > 0) {
750 this->ShiftCargo(action, StationID::Invalid());
751 }
752 return max_move - action.MaxMove();
753}
754
763uint StationCargoList::Truncate(uint max_move, StationCargoAmountMap *cargo_per_source)
764{
765 max_move = std::min(max_move, this->count);
766 uint prev_count = this->count;
767 uint moved = 0;
768 uint loop = 0;
769 bool do_count = cargo_per_source != nullptr;
770 while (max_move > moved) {
771 for (Iterator it(this->packets.begin()); it != this->packets.end();) {
772 CargoPacket *cp = *it;
773 if (prev_count > max_move && RandomRange(prev_count) < prev_count - max_move) {
774 if (do_count && loop == 0) {
775 (*cargo_per_source)[cp->first_station] += cp->count;
776 }
777 ++it;
778 continue;
779 }
780 uint diff = max_move - moved;
781 if (cp->count > diff) {
782 if (diff > 0) {
783 this->RemoveFromCache(cp, diff);
784 cp->Reduce(diff);
785 moved += diff;
786 }
787 if (loop > 0) {
788 if (do_count) (*cargo_per_source)[cp->first_station] -= diff;
789 return moved;
790 } else {
791 if (do_count) (*cargo_per_source)[cp->first_station] += cp->count;
792 ++it;
793 }
794 } else {
795 it = this->packets.erase(it);
796 if (do_count && loop > 0) {
797 (*cargo_per_source)[cp->first_station] -= cp->count;
798 }
799 moved += cp->count;
800 this->RemoveFromCache(cp, cp->count);
801 delete cp;
802 }
803 }
804 loop++;
805 }
806 return moved;
807}
808
817uint StationCargoList::Reserve(uint max_move, VehicleCargoList *dest, std::span<const StationID> next_station, TileIndex current_tile)
818{
819 return this->ShiftCargo(CargoReservation(this, dest, max_move, current_tile), next_station, true);
820}
821
834uint StationCargoList::Load(uint max_move, VehicleCargoList *dest, std::span<const StationID> next_station, TileIndex current_tile)
835{
836 uint move = std::min(dest->ActionCount(VehicleCargoList::MTA_LOAD), max_move);
837 if (move > 0) {
838 this->reserved_count -= move;
839 dest->Reassign<VehicleCargoList::MTA_LOAD, VehicleCargoList::MTA_KEEP>(move);
840 return move;
841 } else {
842 return this->ShiftCargo(CargoLoad{this, dest, max_move, current_tile}, next_station, true);
843 }
844}
845
854uint StationCargoList::Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
855{
856 return this->ShiftCargo(StationCargoReroute(this, dest, max_move, avoid, avoid2, ge), {&avoid, 1}, false);
857}
858
859/*
860 * We have to instantiate everything we want to be usable.
861 */
862template class CargoList<VehicleCargoList, CargoPacketList>;
863template class CargoList<StationCargoList, StationCargoPacketMap>;
864template uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_KEEP>(uint);
CargoType
uint8_t CargoType
Cargo slots to indicate a cargo type within a game.
Definition cargo_type.h:21
cargoaction.h
Actions to be applied to cargo packets.
CargoDelivery
Action of final delivery of cargo.
Definition cargoaction.h:39
CargoList
Simple collection class for a list of cargo packets.
Definition cargopacket.h:274
CargoList< VehicleCargoList, CargoPacketList >::ReverseIterator
Tcont::reverse_iterator ReverseIterator
The reverse iterator for our container.
Definition cargopacket.h:279
CargoList::OnCleanPool
void OnCleanPool()
Empty the cargo list, but don't free the cargo packets; the cargo packets are cleaned by CargoPacket'...
Definition cargopacket.cpp:172
CargoList< VehicleCargoList, CargoPacketList >::packets
CargoPacketList packets
The cargo packets in this list.
Definition cargopacket.h:300
CargoList::~CargoList
~CargoList()
Destroy the cargolist ("frees" all cargo packets).
Definition cargopacket.cpp:160
CargoList::ConstIterator
Tcont::const_iterator ConstIterator
The const iterator for our container.
Definition cargopacket.h:281
CargoList< VehicleCargoList, CargoPacketList >::count
uint count
Cache for the number of cargo entities.
Definition cargopacket.h:297
CargoList< VehicleCargoList, CargoPacketList >::cargo_periods_in_transit
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...
Definition cargopacket.h:298
CargoList::TryMerge
static bool TryMerge(CargoPacket *cp, CargoPacket *icp)
Tries to merge the second packet into the first and return if that was successful.
Definition cargopacket.cpp:223
CargoList::Iterator
Tcont::iterator Iterator
The iterator for our container.
Definition cargopacket.h:277
CargoList< VehicleCargoList, CargoPacketList >::MoveToAction
MoveToAction
Kind of actions that could be done with packets on move.
Definition cargopacket.h:286
CargoList< VehicleCargoList, CargoPacketList >::MTA_KEEP
@ MTA_KEEP
Keep the cargo in the vehicle.
Definition cargopacket.h:290
CargoList< VehicleCargoList, CargoPacketList >::MTA_DELIVER
@ MTA_DELIVER
Deliver the cargo to some town or industry.
Definition cargopacket.h:289
CargoList< VehicleCargoList, CargoPacketList >::MTA_LOAD
@ MTA_LOAD
Load the cargo from the station.
Definition cargopacket.h:291
CargoList< VehicleCargoList, CargoPacketList >::MTA_TRANSFER
@ MTA_TRANSFER
Transfer the cargo to the station.
Definition cargopacket.h:288
CargoList::AddToCache
void AddToCache(const CargoPacket *cp)
Update the cache to reflect adding of this packet.
Definition cargopacket.cpp:197
CargoList::InvalidateCache
void InvalidateCache()
Invalidates the cached data and rebuilds it.
Definition cargopacket.cpp:205
CargoList::RemoveFromCache
void RemoveFromCache(const CargoPacket *cp, uint count)
Update the cached values to reflect the removal of this packet or part of it.
Definition cargopacket.cpp:184
CargoLoad
Action of loading cargo from a station onto a vehicle.
Definition cargoaction.h:83
CargoRemoval
Abstract action of removing cargo from a vehicle or a station.
Definition cargoaction.h:20
CargoReservation
Action of reserving cargo from a station to be loaded onto a vehicle.
Definition cargoaction.h:93
CargoReturn
Action of returning previously reserved cargo from the vehicle to the station.
Definition cargoaction.h:101
CargoShift
Action of shifting cargo from one vehicle to another.
Definition cargoaction.h:112
CargoTransfer
Action of transferring cargo from a vehicle to a station.
Definition cargoaction.h:73
FlowStatMap
Flow descriptions by origin stations.
Definition station_base.h:149
FlowStat
Flow statistics telling how much flow should be sent along a link.
Definition station_base.h:33
FlowStat::GetVia
StationID GetVia() const
Get a station a package can be routed to.
Definition station_base.h:131
FlowStat::GetShares
const SharesMap * GetShares() const
Get the actual shares as a const pointer so that they can be iterated over.
Definition station_base.h:89
FlowStat::ChangeShare
void ChangeShare(StationID st, int flow)
Change share for specified station.
Definition station_cmd.cpp:5077
MultiMap::erase
iterator erase(iterator it)
Erase the value pointed to by an iterator.
Definition multimap.hpp:243
MultiMap::equal_range
std::pair< iterator, iterator > equal_range(const Tkey &key)
Get a pair of iterators specifying a range of items with equal keys.
Definition multimap.hpp:301
OverflowSafeInt< int64_t >
StationCargoList
CargoList that is used for stations.
Definition cargopacket.h:519
StationCargoList::Reroute
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.
Definition cargopacket.cpp:854
StationCargoList::Load
uint Load(uint max_move, VehicleCargoList *dest, std::span< const StationID > next, TileIndex current_tile)
Loads cargo onto a vehicle.
Definition cargopacket.cpp:834
StationCargoList::Append
void Append(CargoPacket *cp, StationID next)
Appends the given cargo packet to the range of packets with the same next station.
Definition cargopacket.cpp:684
StationCargoList::Truncate
uint Truncate(uint max_move=UINT_MAX, StationCargoAmountMap *cargo_per_source=nullptr)
Truncates where each destination loses roughly the same percentage of its cargo.
Definition cargopacket.cpp:763
StationCargoList::ShiftCargo
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.
Definition cargopacket.cpp:712
StationCargoList::reserved_count
uint reserved_count
Amount of cargo being reserved for loading.
Definition cargopacket.h:524
StationCargoList::Reserve
uint Reserve(uint max_move, VehicleCargoList *dest, std::span< const StationID > next, TileIndex current_tile)
Reserves cargo for loading onto the vehicle.
Definition cargopacket.cpp:817
StationCargoReroute
Action of rerouting cargo in a station.
Definition cargoaction.h:132
VehicleCargoList
CargoList that is used for vehicles.
Definition cargopacket.h:342
VehicleCargoList::Shift
uint Shift(uint max_move, VehicleCargoList *dest)
Shifts cargo between two vehicles.
Definition cargopacket.cpp:609
VehicleCargoList::AddToMeta
void AddToMeta(const CargoPacket *cp, MoveToAction action)
Adds a packet to the metadata.
Definition cargopacket.cpp:375
VehicleCargoList::PopCargo
void PopCargo(Taction action)
Pops cargo from the back of the packet list and applies some action to it.
Definition cargopacket.cpp:312
VehicleCargoList::Reroute
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.
Definition cargopacket.cpp:663
VehicleCargoList::ActionCount
uint ActionCount(MoveToAction action) const
Returns the amount of cargo designated for a given purpose.
Definition cargopacket.h:415
VehicleCargoList::ChooseAction
static MoveToAction ChooseAction(const CargoPacket *cp, StationID cargo_next, StationID current_station, bool accepted, std::span< const StationID > next_station)
Choose action to be performed with the given cargo packet.
Definition cargopacket.cpp:406
VehicleCargoList::Truncate
uint Truncate(uint max_move=UINT_MAX)
Truncates the cargo in this list to the given amount.
Definition cargopacket.cpp:648
VehicleCargoList::AssertCountConsistency
void AssertCountConsistency() const
Assert that the designation counts add up.
Definition cargopacket.h:359
VehicleCargoList::RemoveFromMeta
void RemoveFromMeta(const CargoPacket *cp, MoveToAction action, uint count)
Removes a packet or part of it from the metadata.
Definition cargopacket.cpp:361
VehicleCargoList::Return
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.
Definition cargopacket.cpp:596
VehicleCargoList::action_counts
uint action_counts[NUM_MOVE_TO_ACTION]
Counts of cargo to be transferred, delivered, kept and loaded.
Definition cargopacket.h:348
VehicleCargoList::feeder_share
Money feeder_share
Cache for the feeder share.
Definition cargopacket.h:347
VehicleCargoList::Append
void Append(CargoPacket *cp, MoveToAction action=MTA_KEEP)
Appends the given cargo packet.
Definition cargopacket.cpp:255
VehicleCargoList::RemoveFromCache
void RemoveFromCache(const CargoPacket *cp, uint count)
Update the cached values to reflect the removal of this packet or part of it.
Definition cargopacket.cpp:338
VehicleCargoList::Reassign
uint Reassign(uint max_move)
Moves some cargo from one designation to another.
Definition cargopacket.cpp:549
VehicleCargoList::InvalidateCache
void InvalidateCache()
Invalidates the cached data and rebuild it.
Definition cargopacket.cpp:530
VehicleCargoList::AddToCache
void AddToCache(const CargoPacket *cp)
Update the cache to reflect adding of this packet.
Definition cargopacket.cpp:349
VehicleCargoList::AgeCargo
void AgeCargo()
Ages the all cargo in this list.
Definition cargopacket.cpp:386
VehicleCargoList::Unload
uint Unload(uint max_move, StationCargoList *dest, CargoType cargo, CargoPayment *payment, TileIndex current_tile)
Unloads cargo at the given station.
Definition cargopacket.cpp:626
VehicleCargoList::Stage
bool Stage(bool accepted, StationID current_station, std::span< const StationID > next_station, OrderUnloadType unload_type, const GoodsEntry *ge, CargoType cargo, CargoPayment *payment, TileIndex current_tile)
Stages cargo for unloading.
Definition cargopacket.cpp:435
VehicleCargoList::ShiftCargo
void ShiftCargo(Taction action)
Shifts cargo from the front of the packet list and applies some action to it.
Definition cargopacket.cpp:290
VehicleCargoReroute
Action of rerouting cargo staged for transfer in a vehicle.
Definition cargoaction.h:140
economy_base.h
Base classes related to the economy.
order_type.h
Types related to orders.
OrderUnloadType
OrderUnloadType
Unloading order types.
Definition order_type.h:67
OrderUnloadType::Transfer
@ Transfer
Transfer all cargo onto the platform.
OrderUnloadType::NoUnload
@ NoUnload
Totally no unloading will be done.
OrderUnloadType::Unload
@ Unload
Force unloading all cargo onto the platform, possibly not getting paid.
pool_func.hpp
Some methods of Pool are placed here in order to reduce compilation time and binary size.
INSTANTIATE_POOL_METHODS
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don't get linker errors.
Definition pool_func.hpp:210
random_func.hpp
Pseudo random number generator.
RandomRange
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.
Definition random_func.hpp:88
safeguards.h
A number of safeguards to prevent using unsafe methods.
station_base.h
Base classes/functions for stations.
stdafx.h
Definition of base types and functions in a cross-platform compatible way.
CargoPacket
Container for cargo from the same location and time.
Definition cargopacket.h:41
CargoPacket::Reduce
void Reduce(uint count)
Reduce the packet by the given amount and remove the feeder share.
Definition cargopacket.cpp:120
CargoPacket::Count
uint16_t Count() const
Gets the number of 'items' in this packet.
Definition cargopacket.h:158
CargoPacket::Merge
void Merge(CargoPacket *cp)
Merge another packet into this one.
Definition cargopacket.cpp:109
CargoPacket::feeder_share
Money feeder_share
Value of feeder pickup to be paid for on delivery of cargo.
Definition cargopacket.h:52
CargoPacket::MAX_COUNT
static const uint16_t MAX_COUNT
Maximum number of items in a single cargo packet.
Definition cargopacket.h:74
CargoPacket::Split
CargoPacket * Split(uint new_size)
Split this packet in two and return the split off part.
Definition cargopacket.cpp:94
CargoPacket::next_hop
StationID next_hop
Station where the cargo wants to go next.
Definition cargopacket.h:64
CargoPacket::AddFeederShare
void AddFeederShare(Money new_share)
Adds some feeder share to the packet.
Definition cargopacket.h:149
CargoPacket::count
uint16_t count
The amount of cargo in this packet.
Definition cargopacket.h:49
CargoPacket::CargoPacket
CargoPacket()
Create a new packet for savegame loading.
Definition cargopacket.cpp:27
CargoPacket::GetFeederShare
Money GetFeederShare() const
Gets the amount of money already paid to earlier vehicles in the feeder chain.
Definition cargopacket.h:168
CargoPacket::first_station
StationID first_station
The station where the cargo came from first.
Definition cargopacket.h:63
CargoPacket::InvalidateAllFrom
static void InvalidateAllFrom(Source src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
Definition cargopacket.cpp:132
CargoPacket::periods_in_transit
uint16_t periods_in_transit
Amount of cargo aging periods this packet has been in transit.
Definition cargopacket.h:50
CargoPayment
Helper class to perform the cargo payment.
Definition economy_base.h:23
CargoPayment::PayTransfer
Money PayTransfer(CargoType cargo, const CargoPacket *cp, uint count, TileIndex current_tile)
Handle payment for transfer of the given cargo packet.
Definition economy.cpp:1235
GoodsEntry::GoodsEntryData::flows
FlowStatMap flows
Planned flows through this station.
Definition station_base.h:214
GoodsEntry
Stores station stats for a single cargo.
Definition station_base.h:167
GoodsEntry::GetData
const GoodsEntryData & GetData() const
Get optional cargo packet/flow data.
Definition station_base.h:317
GoodsEntry::HasData
bool HasData() const
Test if this goods entry has optional cargo packet/flow data.
Definition station_base.h:305
PoolID< uint16_t, struct StationIDTag, 64000, 0xFFFF >
Pool::PoolItem<&_cargopacket_pool >::Iterate
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition pool_type.hpp:436
Pool::PoolItem<&_cargopacket_pool >::CanAllocateItem
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function()
Definition pool_type.hpp:357
Pool
Base class for all pools.
Definition pool_type.hpp:133
Source
A location from where cargo can come from (or go to).
Definition source_type.h:32
StrongType::Typedef< uint32_t, struct TileIndexTag, StrongType::Compare, StrongType::Integer, StrongType::Compatible< int32_t >, StrongType::Compatible< int64_t > >