OpenTTD
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 <http://www.gnu.org/licenses/>.
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");
23 
24 
28 {
29  this->source_type = ST_INDUSTRY;
30  this->source_id = INVALID_SOURCE;
31 }
32 
44 CargoPacket::CargoPacket(StationID source, TileIndex source_xy, uint16 count, SourceType source_type, SourceID source_id) :
45  feeder_share(0),
46  count(count),
47  days_in_transit(0),
48  source_id(source_id),
49  source(source),
50  source_xy(source_xy),
51  loaded_at_xy(0)
52 {
53  assert(count != 0);
54  this->source_type = source_type;
55 }
56 
72  feeder_share(feeder_share),
73  count(count),
74  days_in_transit(days_in_transit),
75  source_id(source_id),
76  source(source),
77  source_xy(source_xy),
78  loaded_at_xy(loaded_at_xy)
79 {
80  assert(count != 0);
81  this->source_type = source_type;
82 }
83 
90 {
91  if (!CargoPacket::CanAllocateItem()) return nullptr;
92 
93  Money fs = this->FeederShare(new_size);
94  CargoPacket *cp_new = new CargoPacket(new_size, this->days_in_transit, this->source, this->source_xy, this->loaded_at_xy, fs, this->source_type, this->source_id);
95  this->feeder_share -= fs;
96  this->count -= new_size;
97  return cp_new;
98 }
99 
105 {
106  this->count += cp->count;
107  this->feeder_share += cp->feeder_share;
108  delete cp;
109 }
110 
116 {
117  assert(count < this->count);
118  this->feeder_share -= this->FeederShare(count);
119  this->count -= count;
120 }
121 
127 /* static */ void CargoPacket::InvalidateAllFrom(SourceType src_type, SourceID src)
128 {
129  for (CargoPacket *cp : CargoPacket::Iterate()) {
130  if (cp->source_type == src_type && cp->source_id == src) cp->source_id = INVALID_SOURCE;
131  }
132 }
133 
138 /* static */ void CargoPacket::InvalidateAllFrom(StationID sid)
139 {
140  for (CargoPacket *cp : CargoPacket::Iterate()) {
141  if (cp->source == sid) cp->source = INVALID_STATION;
142  }
143 }
144 
145 /*
146  *
147  * Cargo list implementation
148  *
149  */
150 
154 template <class Tinst, class Tcont>
156 {
157  for (Iterator it(this->packets.begin()); it != this->packets.end(); ++it) {
158  delete *it;
159  }
160 }
161 
166 template <class Tinst, class Tcont>
168 {
169  this->packets.clear();
170 }
171 
178 template <class Tinst, class Tcont>
180 {
181  assert(count <= cp->count);
182  this->count -= count;
183  this->cargo_days_in_transit -= cp->days_in_transit * count;
184 }
185 
191 template <class Tinst, class Tcont>
193 {
194  this->count += cp->count;
195  this->cargo_days_in_transit += cp->days_in_transit * cp->count;
196 }
197 
199 template <class Tinst, class Tcont>
201 {
202  this->count = 0;
203  this->cargo_days_in_transit = 0;
204 
205  for (ConstIterator it(this->packets.begin()); it != this->packets.end(); it++) {
206  static_cast<Tinst *>(this)->AddToCache(*it);
207  }
208 }
209 
217 template <class Tinst, class Tcont>
219 {
220  if (Tinst::AreMergable(icp, cp) &&
221  icp->count + cp->count <= CargoPacket::MAX_COUNT) {
222  icp->Merge(cp);
223  return true;
224  } else {
225  return false;
226  }
227 }
228 
229 /*
230  *
231  * Vehicle cargo list implementation.
232  *
233  */
234 
250 void VehicleCargoList::Append(CargoPacket *cp, MoveToAction action)
251 {
252  assert(cp != nullptr);
253  assert(action == MTA_LOAD ||
254  (action == MTA_KEEP && this->action_counts[MTA_LOAD] == 0));
255  this->AddToMeta(cp, action);
256 
257  if (this->count == cp->count) {
258  this->packets.push_back(cp);
259  return;
260  }
261 
262  uint sum = cp->count;
263  for (ReverseIterator it(this->packets.rbegin()); it != this->packets.rend(); it++) {
264  CargoPacket *icp = *it;
265  if (VehicleCargoList::TryMerge(icp, cp)) return;
266  sum += icp->count;
267  if (sum >= this->action_counts[action]) {
268  this->packets.push_back(cp);
269  return;
270  }
271  }
272 
273  NOT_REACHED();
274 }
275 
284 template<class Taction>
285 void VehicleCargoList::ShiftCargo(Taction action)
286 {
287  Iterator it(this->packets.begin());
288  while (it != this->packets.end() && action.MaxMove() > 0) {
289  CargoPacket *cp = *it;
290  if (action(cp)) {
291  it = this->packets.erase(it);
292  } else {
293  break;
294  }
295  }
296 }
297 
306 template<class Taction>
307 void VehicleCargoList::PopCargo(Taction action)
308 {
309  if (this->packets.empty()) return;
310  Iterator it(--(this->packets.end()));
311  Iterator begin(this->packets.begin());
312  while (action.MaxMove() > 0) {
313  CargoPacket *cp = *it;
314  if (action(cp)) {
315  if (it != begin) {
316  this->packets.erase(it--);
317  } else {
318  this->packets.erase(it);
319  break;
320  }
321  } else {
322  break;
323  }
324  }
325 }
326 
334 {
335  this->feeder_share -= cp->FeederShare(count);
336  this->Parent::RemoveFromCache(cp, count);
337 }
338 
345 {
346  this->feeder_share += cp->feeder_share;
347  this->Parent::AddToCache(cp);
348 }
349 
356 void VehicleCargoList::RemoveFromMeta(const CargoPacket *cp, MoveToAction action, uint count)
357 {
358  assert(count <= this->action_counts[action]);
359  this->AssertCountConsistency();
360  this->RemoveFromCache(cp, count);
361  this->action_counts[action] -= count;
362  this->AssertCountConsistency();
363 }
364 
370 void VehicleCargoList::AddToMeta(const CargoPacket *cp, MoveToAction action)
371 {
372  this->AssertCountConsistency();
373  this->AddToCache(cp);
374  this->action_counts[action] += cp->count;
375  this->AssertCountConsistency();
376 }
377 
382 {
383  for (ConstIterator it(this->packets.begin()); it != this->packets.end(); it++) {
384  CargoPacket *cp = *it;
385  /* If we're at the maximum, then we can't increase no more. */
386  if (cp->days_in_transit == 0xFF) continue;
387 
388  cp->days_in_transit++;
389  this->cargo_days_in_transit += cp->count;
390  }
391 }
392 
401 {
402  uint sum = 0;
403  for (Iterator it = this->packets.begin(); sum < this->action_counts[MTA_TRANSFER]; ++it) {
404  CargoPacket *cp = *it;
405  cp->loaded_at_xy = xy;
406  sum += cp->count;
407  }
408 }
409 
419 /* static */ VehicleCargoList::MoveToAction VehicleCargoList::ChooseAction(const CargoPacket *cp, StationID cargo_next,
420  StationID current_station, bool accepted, StationIDStack next_station)
421 {
422  if (cargo_next == INVALID_STATION) {
423  return (accepted && cp->source != current_station) ? MTA_DELIVER : MTA_KEEP;
424  } else if (cargo_next == current_station) {
425  return MTA_DELIVER;
426  } else if (next_station.Contains(cargo_next)) {
427  return MTA_KEEP;
428  } else {
429  return MTA_TRANSFER;
430  }
431 }
432 
446 bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationIDStack next_station, uint8 order_flags, const GoodsEntry *ge, CargoPayment *payment)
447 {
448  this->AssertCountConsistency();
449  assert(this->action_counts[MTA_LOAD] == 0);
450  this->action_counts[MTA_TRANSFER] = this->action_counts[MTA_DELIVER] = this->action_counts[MTA_KEEP] = 0;
451  Iterator deliver = this->packets.end();
452  Iterator it = this->packets.begin();
453  uint sum = 0;
454 
455  bool force_keep = (order_flags & OUFB_NO_UNLOAD) != 0;
456  bool force_unload = (order_flags & OUFB_UNLOAD) != 0;
457  bool force_transfer = (order_flags & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0;
458  assert(this->count > 0 || it == this->packets.end());
459  while (sum < this->count) {
460  CargoPacket *cp = *it;
461 
462  this->packets.erase(it++);
463  StationID cargo_next = INVALID_STATION;
464  MoveToAction action = MTA_LOAD;
465  if (force_keep) {
466  action = MTA_KEEP;
467  } else if (force_unload && accepted && cp->source != current_station) {
468  action = MTA_DELIVER;
469  } else if (force_transfer) {
470  action = MTA_TRANSFER;
471  /* We cannot send the cargo to any of the possible next hops and
472  * also not to the current station. */
473  FlowStatMap::const_iterator flow_it(ge->flows.find(cp->source));
474  if (flow_it == ge->flows.end()) {
475  cargo_next = INVALID_STATION;
476  } else {
477  FlowStat new_shares = flow_it->second;
478  new_shares.ChangeShare(current_station, INT_MIN);
479  StationIDStack excluded = next_station;
480  while (!excluded.IsEmpty() && !new_shares.GetShares()->empty()) {
481  new_shares.ChangeShare(excluded.Pop(), INT_MIN);
482  }
483  if (new_shares.GetShares()->empty()) {
484  cargo_next = INVALID_STATION;
485  } else {
486  cargo_next = new_shares.GetVia();
487  }
488  }
489  } else {
490  /* Rewrite an invalid source station to some random other one to
491  * avoid keeping the cargo in the vehicle forever. */
492  if (cp->source == INVALID_STATION && !ge->flows.empty()) {
493  cp->source = ge->flows.begin()->first;
494  }
495  bool restricted = false;
496  FlowStatMap::const_iterator flow_it(ge->flows.find(cp->source));
497  if (flow_it == ge->flows.end()) {
498  cargo_next = INVALID_STATION;
499  } else {
500  cargo_next = flow_it->second.GetViaWithRestricted(restricted);
501  }
502  action = VehicleCargoList::ChooseAction(cp, cargo_next, current_station, accepted, next_station);
503  if (restricted && action == MTA_TRANSFER) {
504  /* If the flow is restricted we can't transfer to it. Choose an
505  * unrestricted one instead. */
506  cargo_next = flow_it->second.GetVia();
507  action = VehicleCargoList::ChooseAction(cp, cargo_next, current_station, accepted, next_station);
508  }
509  }
510  Money share;
511  switch (action) {
512  case MTA_KEEP:
513  this->packets.push_back(cp);
514  if (deliver == this->packets.end()) --deliver;
515  break;
516  case MTA_DELIVER:
517  this->packets.insert(deliver, cp);
518  break;
519  case MTA_TRANSFER:
520  this->packets.push_front(cp);
521  /* Add feeder share here to allow reusing field for next station. */
522  share = payment->PayTransfer(cp, cp->count);
523  cp->AddFeederShare(share);
524  this->feeder_share += share;
525  cp->next_station = cargo_next;
526  break;
527  default:
528  NOT_REACHED();
529  }
530  this->action_counts[action] += cp->count;
531  sum += cp->count;
532  }
533  this->AssertCountConsistency();
534  return this->action_counts[MTA_DELIVER] > 0 || this->action_counts[MTA_TRANSFER] > 0;
535 }
536 
539 {
540  this->feeder_share = 0;
541  this->Parent::InvalidateCache();
542 }
543 
556 template<VehicleCargoList::MoveToAction Tfrom, VehicleCargoList::MoveToAction Tto>
557 uint VehicleCargoList::Reassign(uint max_move, TileOrStationID)
558 {
559  assert_tcompile(Tfrom != MTA_TRANSFER && Tto != MTA_TRANSFER);
560  assert_tcompile(Tfrom - Tto == 1 || Tto - Tfrom == 1);
561  max_move = min(this->action_counts[Tfrom], max_move);
562  this->action_counts[Tfrom] -= max_move;
563  this->action_counts[Tto] += max_move;
564  return max_move;
565 }
566 
574 template<>
575 uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_TRANSFER>(uint max_move, TileOrStationID next_station)
576 {
577  max_move = min(this->action_counts[MTA_DELIVER], max_move);
578 
579  uint sum = 0;
580  for (Iterator it(this->packets.begin()); sum < this->action_counts[MTA_TRANSFER] + max_move;) {
581  CargoPacket *cp = *it++;
582  sum += cp->Count();
583  if (sum <= this->action_counts[MTA_TRANSFER]) continue;
584  if (sum > this->action_counts[MTA_TRANSFER] + max_move) {
585  CargoPacket *cp_split = cp->Split(sum - this->action_counts[MTA_TRANSFER] + max_move);
586  sum -= cp_split->Count();
587  this->packets.insert(it, cp_split);
588  }
590  }
591 
592  this->action_counts[MTA_DELIVER] -= max_move;
593  this->action_counts[MTA_TRANSFER] += max_move;
594  return max_move;
595 }
596 
604 uint VehicleCargoList::Return(uint max_move, StationCargoList *dest, StationID next)
605 {
606  max_move = min(this->action_counts[MTA_LOAD], max_move);
607  this->PopCargo(CargoReturn(this, dest, max_move, next));
608  return max_move;
609 }
610 
617 uint VehicleCargoList::Shift(uint max_move, VehicleCargoList *dest)
618 {
619  max_move = min(this->count, max_move);
620  this->PopCargo(CargoShift(this, dest, max_move));
621  return max_move;
622 }
623 
632 uint VehicleCargoList::Unload(uint max_move, StationCargoList *dest, CargoPayment *payment)
633 {
634  uint moved = 0;
635  if (this->action_counts[MTA_TRANSFER] > 0) {
636  uint move = min(this->action_counts[MTA_TRANSFER], max_move);
637  this->ShiftCargo(CargoTransfer(this, dest, move));
638  moved += move;
639  }
640  if (this->action_counts[MTA_TRANSFER] == 0 && this->action_counts[MTA_DELIVER] > 0 && moved < max_move) {
641  uint move = min(this->action_counts[MTA_DELIVER], max_move - moved);
642  this->ShiftCargo(CargoDelivery(this, move, payment));
643  moved += move;
644  }
645  return moved;
646 }
647 
654 uint VehicleCargoList::Truncate(uint max_move)
655 {
656  max_move = min(this->count, max_move);
657  this->PopCargo(CargoRemoval<VehicleCargoList>(this, max_move));
658  return max_move;
659 }
660 
669 uint VehicleCargoList::Reroute(uint max_move, VehicleCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
670 {
671  max_move = min(this->action_counts[MTA_TRANSFER], max_move);
672  this->ShiftCargo(VehicleCargoReroute(this, dest, max_move, avoid, avoid2, ge));
673  return max_move;
674 }
675 
676 /*
677  *
678  * Station cargo list implementation.
679  *
680  */
681 
690 void StationCargoList::Append(CargoPacket *cp, StationID next)
691 {
692  assert(cp != nullptr);
693  this->AddToCache(cp);
694 
695  StationCargoPacketMap::List &list = this->packets[next];
696  for (StationCargoPacketMap::List::reverse_iterator it(list.rbegin());
697  it != list.rend(); it++) {
698  if (StationCargoList::TryMerge(*it, cp)) return;
699  }
700 
701  /* The packet could not be merged with another one */
702  list.push_back(cp);
703 }
704 
717 template <class Taction>
718 bool StationCargoList::ShiftCargo(Taction &action, StationID next)
719 {
720  std::pair<Iterator, Iterator> range(this->packets.equal_range(next));
721  for (Iterator it(range.first); it != range.second && it.GetKey() == next;) {
722  if (action.MaxMove() == 0) return false;
723  CargoPacket *cp = *it;
724  if (action(cp)) {
725  it = this->packets.erase(it);
726  } else {
727  return false;
728  }
729  }
730  return true;
731 }
732 
747 template <class Taction>
748 uint StationCargoList::ShiftCargo(Taction action, StationIDStack next, bool include_invalid)
749 {
750  uint max_move = action.MaxMove();
751  while (!next.IsEmpty()) {
752  this->ShiftCargo(action, next.Pop());
753  if (action.MaxMove() == 0) break;
754  }
755  if (include_invalid && action.MaxMove() > 0) {
756  this->ShiftCargo(action, INVALID_STATION);
757  }
758  return max_move - action.MaxMove();
759 }
760 
769 uint StationCargoList::Truncate(uint max_move, StationCargoAmountMap *cargo_per_source)
770 {
771  max_move = min(max_move, this->count);
772  uint prev_count = this->count;
773  uint moved = 0;
774  uint loop = 0;
775  bool do_count = cargo_per_source != nullptr;
776  while (max_move > moved) {
777  for (Iterator it(this->packets.begin()); it != this->packets.end();) {
778  CargoPacket *cp = *it;
779  if (prev_count > max_move && RandomRange(prev_count) < prev_count - max_move) {
780  if (do_count && loop == 0) {
781  (*cargo_per_source)[cp->source] += cp->count;
782  }
783  ++it;
784  continue;
785  }
786  uint diff = max_move - moved;
787  if (cp->count > diff) {
788  if (diff > 0) {
789  this->RemoveFromCache(cp, diff);
790  cp->Reduce(diff);
791  moved += diff;
792  }
793  if (loop > 0) {
794  if (do_count) (*cargo_per_source)[cp->source] -= diff;
795  return moved;
796  } else {
797  if (do_count) (*cargo_per_source)[cp->source] += cp->count;
798  ++it;
799  }
800  } else {
801  it = this->packets.erase(it);
802  if (do_count && loop > 0) {
803  (*cargo_per_source)[cp->source] -= cp->count;
804  }
805  moved += cp->count;
806  this->RemoveFromCache(cp, cp->count);
807  delete cp;
808  }
809  }
810  loop++;
811  }
812  return moved;
813 }
814 
824 {
825  return this->ShiftCargo(CargoReservation(this, dest, max_move, load_place), next_station, true);
826 }
827 
841 {
842  uint move = min(dest->ActionCount(VehicleCargoList::MTA_LOAD), max_move);
843  if (move > 0) {
844  this->reserved_count -= move;
846  return move;
847  } else {
848  return this->ShiftCargo(CargoLoad(this, dest, max_move, load_place), next_station, true);
849  }
850 }
851 
860 uint StationCargoList::Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
861 {
862  return this->ShiftCargo(StationCargoReroute(this, dest, max_move, avoid, avoid2, ge), avoid, false);
863 }
864 
865 /*
866  * We have to instantiate everything we want to be usable.
867  */
870 template uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_KEEP>(uint, TileOrStationID);
SourceType
Types of cargo source and destination.
Definition: cargo_type.h:146
Action of rerouting cargo in a station.
Definition: cargoaction.h:126
void AddFeederShare(Money new_share)
Adds some feeder share to the packet.
Definition: cargopacket.h:93
CargoPacketList ::reverse_iterator ReverseIterator
The reverse iterator for our container.
Definition: cargopacket.h:205
Minimal stack that uses a pool to avoid pointers.
void Append(CargoPacket *cp, MoveToAction action=MTA_KEEP)
Appends the given cargo packet.
Types related to orders.
CargoPacketPool _cargopacket_pool("CargoPacket")
The actual pool with cargo packets.
CargoList that is used for stations.
Definition: cargopacket.h:448
void AddToCache(const CargoPacket *cp)
Update the cache to reflect adding of this packet.
void PopCargo(Taction action)
Pops cargo from the back of the packet list and applies some action to it.
void AddToMeta(const CargoPacket *cp, MoveToAction action)
Adds a packet to the metadata.
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.
CargoPacket()
Create a new packet for savegame loading.
Definition: cargopacket.cpp:27
void SetTransferLoadPlace(TileIndex xy)
Sets loaded_at_xy to the current station for all cargo to be transferred.
uint Truncate(uint max_move=UINT_MAX)
Truncates the cargo in this list to the given amount.
Money FeederShare() const
Gets the amount of money already paid to earlier vehicles in the feeder chain.
Definition: cargopacket.h:109
Action of shifting cargo from one vehicle to another.
Definition: cargoaction.h:106
Stores station stats for a single cargo.
Definition: station_base.h:170
Action of rerouting cargo staged for transfer in a vehicle.
Definition: cargoaction.h:134
static void InvalidateAllFrom(SourceType src_type, SourceID src)
Invalidates (sets source_id to INVALID_SOURCE) all cargo packets from given source.
uint Return(uint max_move, StationCargoList *dest, StationID next_station)
Returns reserved cargo to the station and removes it from the cache.
uint Load(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationIDStack next)
Loads cargo onto a vehicle.
static uint32 RandomRange(uint32 limit)
Pick a random number between 0 and limit - 1, inclusive.
Definition: random_func.hpp:81
static const SourceID INVALID_SOURCE
Invalid/unknown index of source.
Definition: cargo_type.h:153
uint16 count
The amount of cargo in this packet.
Definition: cargopacket.h:45
void RemoveFromCache(const CargoPacket *cp, uint count)
Update the cached values to reflect the removal of this packet or part of it.
void OnCleanPool()
Empty the cargo list, but don&#39;t free the cargo packets; the cargo packets are cleaned by CargoPacket&#39;...
Pseudo random number generator.
~CargoList()
Destroy the cargolist ("frees" all cargo packets).
bool IsEmpty() const
Check if the stack is empty.
Some methods of Pool are placed here in order to reduce compilation time and binary size...
SourceType source_type
Type of source_id.
Definition: cargopacket.h:47
void ShiftCargo(Taction action)
Shifts cargo from the front of the packet list and applies some action to it.
SourceID source_id
Index of source, INVALID_SOURCE if unknown/invalid.
Definition: cargopacket.h:48
Actions to be applied to cargo packets.
StationID GetVia() const
Get a station a package can be routed to.
Definition: station_base.h:134
uint Reassign(uint max_move, TileOrStationID update=INVALID_TILE)
Moves some cargo from one designation to another.
Money PayTransfer(const CargoPacket *cp, uint count)
Handle payment for transfer of the given cargo packet.
Definition: economy.cpp:1217
Container for cargo from the same location and time.
Definition: cargopacket.h:42
Definition of base types and functions in a cross-platform compatible way.
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.
A number of safeguards to prevent using unsafe methods.
TileOrStationID next_station
Station where the cargo wants to go next.
Definition: cargopacket.h:53
Titem Pop()
Pop an item from the stack.
bool Contains(const Titem &item) const
Check if the given item is contained in the stack.
uint ActionCount(MoveToAction action) const
Returns the amount of cargo designated for a given purpose.
Definition: cargopacket.h:341
void InvalidateCache()
Invalidates the cached data and rebuild it.
CargoPacket * Split(uint new_size)
Split this packet in two and return the split off part.
Definition: cargopacket.cpp:89
uint Reserve(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationIDStack next)
Reserves cargo for loading onto the vehicle.
static T min(const T a, const T b)
Returns the minimum of two values.
Definition: math_func.hpp:40
Helper class to perform the cargo payment.
Definition: economy_base.h:24
Action of transferring cargo from a vehicle to a station.
Definition: cargoaction.h:71
MoveToAction
Kind of actions that could be done with packets on move.
Definition: cargopacket.h:212
Transfer all cargo onto the platform.
Definition: order_type.h:55
Action of reserving cargo from a station to be loaded onto a vehicle.
Definition: cargoaction.h:89
Base class for all pools.
Definition: pool_type.hpp:82
FlowStatMap flows
Planned flows through this station.
Definition: station_base.h:259
uint Truncate(uint max_move=UINT_MAX, StationCargoAmountMap *cargo_per_source=nullptr)
Truncates where each destination loses roughly the same percentage of its cargo.
void ChangeShare(StationID st, int flow)
Change share for specified station.
#define INSTANTIATE_POOL_METHODS(name)
Force instantiation of pool methods so we don&#39;t get linker errors.
Definition: pool_func.hpp:224
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...
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
Definition: pool_type.hpp:340
CargoList that is used for vehicles.
Definition: cargopacket.h:268
StationCargoPacketMap ::const_iterator ConstIterator
The const iterator for our container.
Definition: cargopacket.h:207
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:78
Action of returning previously reserved cargo from the vehicle to the station.
Definition: cargoaction.h:97
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.
uint16 SourceID
Contains either industry ID, town ID or company ID (or INVALID_SOURCE)
Definition: cargo_type.h:152
const SharesMap * GetShares() const
Get the actual shares as a const pointer so that they can be iterated over.
Definition: station_base.h:92
TileIndex xy
Base tile of the station.
void AgeCargo()
Ages the all cargo in this list.
StationID source
The station where the cargo came from first.
Definition: cargopacket.h:49
uint Shift(uint max_move, VehicleCargoList *dest)
Shifts cargo between two vehicles.
Totally no unloading will be done.
Definition: order_type.h:56
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:261
Flow statistics telling how much flow should be sent along a link.
Definition: station_base.h:36
uint Unload(uint max_move, StationCargoList *dest, CargoPayment *payment)
Unloads cargo at the given station.
void Reduce(uint count)
Reduce the packet by the given amount and remove the feeder share.
Base classes related to the economy.
void RemoveFromMeta(const CargoPacket *cp, MoveToAction action, uint count)
Removes a packet or part of it from the metadata.
bool Stage(bool accepted, StationID current_station, StationIDStack next_station, uint8 order_flags, const GoodsEntry *ge, CargoPayment *payment)
Stages cargo for unloading.
void Merge(CargoPacket *cp)
Merge another packet into this one.
uint16 Count() const
Gets the number of &#39;items&#39; in this packet.
Definition: cargopacket.h:99
static const uint16 MAX_COUNT
Maximum number of items in a single cargo packet.
Definition: cargopacket.h:64
Money feeder_share
Value of feeder pickup to be paid for on delivery of cargo.
Definition: cargopacket.h:44
Action of final delivery of cargo.
Definition: cargoaction.h:39
void InvalidateCache()
Invalidates the cached data and rebuilds it.
TileOrStationID loaded_at_xy
Location where this cargo has been loaded into the vehicle.
Definition: cargopacket.h:52
TileIndex source_xy
The origin of the cargo (first station in feeder chain).
Definition: cargopacket.h:50
void RemoveFromCache(const CargoPacket *cp, uint count)
Update the cached values to reflect the removal of this packet or part of it.
Force unloading all cargo onto the platform, possibly not getting paid.
Definition: order_type.h:54
Action of loading cargo from a station onto a vehicle.
Definition: cargoaction.h:79
StationCargoPacketMap ::iterator Iterator
The iterator for our container.
Definition: cargopacket.h:203
Base classes/functions for stations.
void AddToCache(const CargoPacket *cp)
Update the cache to reflect adding of this packet.
byte days_in_transit
Amount of days this packet has been in transit.
Definition: cargopacket.h:46
void Append(CargoPacket *cp, StationID next)
Appends the given cargo packet to the range of packets with the same next station.
static bool TryMerge(CargoPacket *cp, CargoPacket *icp)
Tries to merge the second packet into the first and return if that was successful.
Source/destination is an industry.
Definition: cargo_type.h:147