OpenTTD
cargopacket.cpp
Go to the documentation of this file.
1 /* $Id: cargopacket.cpp 26575 2014-05-11 12:49:51Z fonsinchen $ */
2 
3 /*
4  * This file is part of OpenTTD.
5  * 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.
6  * 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.
7  * 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/>.
8  */
9 
12 #include "stdafx.h"
13 #include "station_base.h"
14 #include "core/pool_func.hpp"
15 #include "core/random_func.hpp"
16 #include "economy_base.h"
17 #include "cargoaction.h"
18 #include "order_type.h"
19 
20 #include "safeguards.h"
21 
22 /* Initialize the cargopacket-pool */
23 CargoPacketPool _cargopacket_pool("CargoPacket");
25 
26 
30 {
31  this->source_type = ST_INDUSTRY;
32  this->source_id = INVALID_SOURCE;
33 }
34 
46 CargoPacket::CargoPacket(StationID source, TileIndex source_xy, uint16 count, SourceType source_type, SourceID source_id) :
47  feeder_share(0),
48  count(count),
49  days_in_transit(0),
50  source_id(source_id),
51  source(source),
52  source_xy(source_xy),
53  loaded_at_xy(0)
54 {
55  assert(count != 0);
56  this->source_type = source_type;
57 }
58 
74  feeder_share(feeder_share),
75  count(count),
76  days_in_transit(days_in_transit),
77  source_id(source_id),
78  source(source),
79  source_xy(source_xy),
80  loaded_at_xy(loaded_at_xy)
81 {
82  assert(count != 0);
83  this->source_type = source_type;
84 }
85 
92 {
93  if (!CargoPacket::CanAllocateItem()) return NULL;
94 
95  Money fs = this->FeederShare(new_size);
96  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);
97  this->feeder_share -= fs;
98  this->count -= new_size;
99  return cp_new;
100 }
101 
107 {
108  this->count += cp->count;
109  this->feeder_share += cp->feeder_share;
110  delete cp;
111 }
112 
118 {
119  assert(count < this->count);
120  this->feeder_share -= this->FeederShare(count);
121  this->count -= count;
122 }
123 
129 /* static */ void CargoPacket::InvalidateAllFrom(SourceType src_type, SourceID src)
130 {
131  CargoPacket *cp;
133  if (cp->source_type == src_type && cp->source_id == src) cp->source_id = INVALID_SOURCE;
134  }
135 }
136 
141 /* static */ void CargoPacket::InvalidateAllFrom(StationID sid)
142 {
143  CargoPacket *cp;
145  if (cp->source == sid) cp->source = INVALID_STATION;
146  }
147 }
148 
149 /*
150  *
151  * Cargo list implementation
152  *
153  */
154 
158 template <class Tinst, class Tcont>
160 {
161  for (Iterator it(this->packets.begin()); it != this->packets.end(); ++it) {
162  delete *it;
163  }
164 }
165 
170 template <class Tinst, class Tcont>
172 {
173  this->packets.clear();
174 }
175 
182 template <class Tinst, class Tcont>
184 {
185  assert(count <= cp->count);
186  this->count -= count;
187  this->cargo_days_in_transit -= cp->days_in_transit * count;
188 }
189 
195 template <class Tinst, class Tcont>
197 {
198  this->count += cp->count;
199  this->cargo_days_in_transit += cp->days_in_transit * cp->count;
200 }
201 
203 template <class Tinst, class Tcont>
205 {
206  this->count = 0;
207  this->cargo_days_in_transit = 0;
208 
209  for (ConstIterator it(this->packets.begin()); it != this->packets.end(); it++) {
210  static_cast<Tinst *>(this)->AddToCache(*it);
211  }
212 }
213 
221 template <class Tinst, class Tcont>
223 {
224  if (Tinst::AreMergable(icp, cp) &&
225  icp->count + cp->count <= CargoPacket::MAX_COUNT) {
226  icp->Merge(cp);
227  return true;
228  } else {
229  return false;
230  }
231 }
232 
233 /*
234  *
235  * Vehicle cargo list implementation.
236  *
237  */
238 
254 void VehicleCargoList::Append(CargoPacket *cp, MoveToAction action)
255 {
256  assert(cp != NULL);
257  assert(action == MTA_LOAD ||
258  (action == MTA_KEEP && this->action_counts[MTA_LOAD] == 0));
259  this->AddToMeta(cp, action);
260 
261  if (this->count == cp->count) {
262  this->packets.push_back(cp);
263  return;
264  }
265 
266  uint sum = cp->count;
267  for (ReverseIterator it(this->packets.rbegin()); it != this->packets.rend(); it++) {
268  CargoPacket *icp = *it;
269  if (VehicleCargoList::TryMerge(icp, cp)) return;
270  sum += icp->count;
271  if (sum >= this->action_counts[action]) {
272  this->packets.push_back(cp);
273  return;
274  }
275  }
276 
277  NOT_REACHED();
278 }
279 
288 template<class Taction>
289 void VehicleCargoList::ShiftCargo(Taction action)
290 {
291  Iterator it(this->packets.begin());
292  while (it != this->packets.end() && action.MaxMove() > 0) {
293  CargoPacket *cp = *it;
294  if (action(cp)) {
295  it = this->packets.erase(it);
296  } else {
297  break;
298  }
299  }
300 }
301 
310 template<class Taction>
311 void VehicleCargoList::PopCargo(Taction action)
312 {
313  if (this->packets.empty()) return;
314  Iterator it(--(this->packets.end()));
315  Iterator begin(this->packets.begin());
316  while (action.MaxMove() > 0) {
317  CargoPacket *cp = *it;
318  if (action(cp)) {
319  if (it != begin) {
320  this->packets.erase(it--);
321  } else {
322  this->packets.erase(it);
323  break;
324  }
325  } else {
326  break;
327  }
328  }
329 }
330 
338 {
339  this->feeder_share -= cp->FeederShare(count);
340  this->Parent::RemoveFromCache(cp, count);
341 }
342 
349 {
350  this->feeder_share += cp->feeder_share;
351  this->Parent::AddToCache(cp);
352 }
353 
360 void VehicleCargoList::RemoveFromMeta(const CargoPacket *cp, MoveToAction action, uint count)
361 {
362  assert(count <= this->action_counts[action]);
363  this->AssertCountConsistency();
364  this->RemoveFromCache(cp, count);
365  this->action_counts[action] -= count;
366  this->AssertCountConsistency();
367 }
368 
374 void VehicleCargoList::AddToMeta(const CargoPacket *cp, MoveToAction action)
375 {
376  this->AssertCountConsistency();
377  this->AddToCache(cp);
378  this->action_counts[action] += cp->count;
379  this->AssertCountConsistency();
380 }
381 
386 {
387  for (ConstIterator it(this->packets.begin()); it != this->packets.end(); it++) {
388  CargoPacket *cp = *it;
389  /* If we're at the maximum, then we can't increase no more. */
390  if (cp->days_in_transit == 0xFF) continue;
391 
392  cp->days_in_transit++;
393  this->cargo_days_in_transit += cp->count;
394  }
395 }
396 
405 {
406  uint sum = 0;
407  for (Iterator it = this->packets.begin(); sum < this->action_counts[MTA_TRANSFER]; ++it) {
408  CargoPacket *cp = *it;
409  cp->loaded_at_xy = xy;
410  sum += cp->count;
411  }
412 }
413 
423 /* static */ VehicleCargoList::MoveToAction VehicleCargoList::ChooseAction(const CargoPacket *cp, StationID cargo_next,
424  StationID current_station, bool accepted, StationIDStack next_station)
425 {
426  if (cargo_next == INVALID_STATION) {
427  return (accepted && cp->source != current_station) ? MTA_DELIVER : MTA_KEEP;
428  } else if (cargo_next == current_station) {
429  return MTA_DELIVER;
430  } else if (next_station.Contains(cargo_next)) {
431  return MTA_KEEP;
432  } else {
433  return MTA_TRANSFER;
434  }
435 }
436 
450 bool VehicleCargoList::Stage(bool accepted, StationID current_station, StationIDStack next_station, uint8 order_flags, const GoodsEntry *ge, CargoPayment *payment)
451 {
452  this->AssertCountConsistency();
453  assert(this->action_counts[MTA_LOAD] == 0);
454  this->action_counts[MTA_TRANSFER] = this->action_counts[MTA_DELIVER] = this->action_counts[MTA_KEEP] = 0;
455  Iterator deliver = this->packets.end();
456  Iterator it = this->packets.begin();
457  uint sum = 0;
458 
459  bool force_keep = (order_flags & OUFB_NO_UNLOAD) != 0;
460  bool force_unload = (order_flags & OUFB_UNLOAD) != 0;
461  bool force_transfer = (order_flags & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0;
462  assert(this->count > 0 || it == this->packets.end());
463  while (sum < this->count) {
464  CargoPacket *cp = *it;
465 
466  this->packets.erase(it++);
467  StationID cargo_next = INVALID_STATION;
468  MoveToAction action = MTA_LOAD;
469  if (force_keep) {
470  action = MTA_KEEP;
471  } else if (force_unload && accepted && cp->source != current_station) {
472  action = MTA_DELIVER;
473  } else if (force_transfer) {
474  action = MTA_TRANSFER;
475  /* We cannot send the cargo to any of the possible next hops and
476  * also not to the current station. */
477  FlowStatMap::const_iterator flow_it(ge->flows.find(cp->source));
478  if (flow_it == ge->flows.end()) {
479  cargo_next = INVALID_STATION;
480  } else {
481  FlowStat new_shares = flow_it->second;
482  new_shares.ChangeShare(current_station, INT_MIN);
483  StationIDStack excluded = next_station;
484  while (!excluded.IsEmpty() && !new_shares.GetShares()->empty()) {
485  new_shares.ChangeShare(excluded.Pop(), INT_MIN);
486  }
487  if (new_shares.GetShares()->empty()) {
488  cargo_next = INVALID_STATION;
489  } else {
490  cargo_next = new_shares.GetVia();
491  }
492  }
493  } else {
494  /* Rewrite an invalid source station to some random other one to
495  * avoid keeping the cargo in the vehicle forever. */
496  if (cp->source == INVALID_STATION && !ge->flows.empty()) {
497  cp->source = ge->flows.begin()->first;
498  }
499  bool restricted = false;
500  FlowStatMap::const_iterator flow_it(ge->flows.find(cp->source));
501  if (flow_it == ge->flows.end()) {
502  cargo_next = INVALID_STATION;
503  } else {
504  cargo_next = flow_it->second.GetViaWithRestricted(restricted);
505  }
506  action = VehicleCargoList::ChooseAction(cp, cargo_next, current_station, accepted, next_station);
507  if (restricted && action == MTA_TRANSFER) {
508  /* If the flow is restricted we can't transfer to it. Choose an
509  * unrestricted one instead. */
510  cargo_next = flow_it->second.GetVia();
511  action = VehicleCargoList::ChooseAction(cp, cargo_next, current_station, accepted, next_station);
512  }
513  }
514  Money share;
515  switch (action) {
516  case MTA_KEEP:
517  this->packets.push_back(cp);
518  if (deliver == this->packets.end()) --deliver;
519  break;
520  case MTA_DELIVER:
521  this->packets.insert(deliver, cp);
522  break;
523  case MTA_TRANSFER:
524  this->packets.push_front(cp);
525  /* Add feeder share here to allow reusing field for next station. */
526  share = payment->PayTransfer(cp, cp->count);
527  cp->AddFeederShare(share);
528  this->feeder_share += share;
529  cp->next_station = cargo_next;
530  break;
531  default:
532  NOT_REACHED();
533  }
534  this->action_counts[action] += cp->count;
535  sum += cp->count;
536  }
537  this->AssertCountConsistency();
538  return this->action_counts[MTA_DELIVER] > 0 || this->action_counts[MTA_TRANSFER] > 0;
539 }
540 
543 {
544  this->feeder_share = 0;
545  this->Parent::InvalidateCache();
546 }
547 
560 template<VehicleCargoList::MoveToAction Tfrom, VehicleCargoList::MoveToAction Tto>
561 uint VehicleCargoList::Reassign(uint max_move, TileOrStationID)
562 {
563  assert_tcompile(Tfrom != MTA_TRANSFER && Tto != MTA_TRANSFER);
564  assert_tcompile(Tfrom - Tto == 1 || Tto - Tfrom == 1);
565  max_move = min(this->action_counts[Tfrom], max_move);
566  this->action_counts[Tfrom] -= max_move;
567  this->action_counts[Tto] += max_move;
568  return max_move;
569 }
570 
578 template<>
579 uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_TRANSFER>(uint max_move, TileOrStationID next_station)
580 {
581  max_move = min(this->action_counts[MTA_DELIVER], max_move);
582 
583  uint sum = 0;
584  for (Iterator it(this->packets.begin()); sum < this->action_counts[MTA_TRANSFER] + max_move;) {
585  CargoPacket *cp = *it++;
586  sum += cp->Count();
587  if (sum <= this->action_counts[MTA_TRANSFER]) continue;
588  if (sum > this->action_counts[MTA_TRANSFER] + max_move) {
589  CargoPacket *cp_split = cp->Split(sum - this->action_counts[MTA_TRANSFER] + max_move);
590  sum -= cp_split->Count();
591  this->packets.insert(it, cp_split);
592  }
594  }
595 
596  this->action_counts[MTA_DELIVER] -= max_move;
597  this->action_counts[MTA_TRANSFER] += max_move;
598  return max_move;
599 }
600 
608 uint VehicleCargoList::Return(uint max_move, StationCargoList *dest, StationID next)
609 {
610  max_move = min(this->action_counts[MTA_LOAD], max_move);
611  this->PopCargo(CargoReturn(this, dest, max_move, next));
612  return max_move;
613 }
614 
621 uint VehicleCargoList::Shift(uint max_move, VehicleCargoList *dest)
622 {
623  max_move = min(this->count, max_move);
624  this->PopCargo(CargoShift(this, dest, max_move));
625  return max_move;
626 }
627 
636 uint VehicleCargoList::Unload(uint max_move, StationCargoList *dest, CargoPayment *payment)
637 {
638  uint moved = 0;
639  if (this->action_counts[MTA_TRANSFER] > 0) {
640  uint move = min(this->action_counts[MTA_TRANSFER], max_move);
641  this->ShiftCargo(CargoTransfer(this, dest, move));
642  moved += move;
643  }
644  if (this->action_counts[MTA_TRANSFER] == 0 && this->action_counts[MTA_DELIVER] > 0 && moved < max_move) {
645  uint move = min(this->action_counts[MTA_DELIVER], max_move - moved);
646  this->ShiftCargo(CargoDelivery(this, move, payment));
647  moved += move;
648  }
649  return moved;
650 }
651 
658 uint VehicleCargoList::Truncate(uint max_move)
659 {
660  max_move = min(this->count, max_move);
661  this->PopCargo(CargoRemoval<VehicleCargoList>(this, max_move));
662  return max_move;
663 }
664 
673 uint VehicleCargoList::Reroute(uint max_move, VehicleCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
674 {
675  max_move = min(this->action_counts[MTA_TRANSFER], max_move);
676  this->ShiftCargo(VehicleCargoReroute(this, dest, max_move, avoid, avoid2, ge));
677  return max_move;
678 }
679 
680 /*
681  *
682  * Station cargo list implementation.
683  *
684  */
685 
694 void StationCargoList::Append(CargoPacket *cp, StationID next)
695 {
696  assert(cp != NULL);
697  this->AddToCache(cp);
698 
699  StationCargoPacketMap::List &list = this->packets[next];
700  for (StationCargoPacketMap::List::reverse_iterator it(list.rbegin());
701  it != list.rend(); it++) {
702  if (StationCargoList::TryMerge(*it, cp)) return;
703  }
704 
705  /* The packet could not be merged with another one */
706  list.push_back(cp);
707 }
708 
721 template <class Taction>
722 bool StationCargoList::ShiftCargo(Taction &action, StationID next)
723 {
724  std::pair<Iterator, Iterator> range(this->packets.equal_range(next));
725  for (Iterator it(range.first); it != range.second && it.GetKey() == next;) {
726  if (action.MaxMove() == 0) return false;
727  CargoPacket *cp = *it;
728  if (action(cp)) {
729  it = this->packets.erase(it);
730  } else {
731  return false;
732  }
733  }
734  return true;
735 }
736 
751 template <class Taction>
752 uint StationCargoList::ShiftCargo(Taction action, StationIDStack next, bool include_invalid)
753 {
754  uint max_move = action.MaxMove();
755  while (!next.IsEmpty()) {
756  this->ShiftCargo(action, next.Pop());
757  if (action.MaxMove() == 0) break;
758  }
759  if (include_invalid && action.MaxMove() > 0) {
760  this->ShiftCargo(action, INVALID_STATION);
761  }
762  return max_move - action.MaxMove();
763 }
764 
773 uint StationCargoList::Truncate(uint max_move, StationCargoAmountMap *cargo_per_source)
774 {
775  max_move = min(max_move, this->count);
776  uint prev_count = this->count;
777  uint moved = 0;
778  uint loop = 0;
779  bool do_count = cargo_per_source != NULL;
780  while (max_move > moved) {
781  for (Iterator it(this->packets.begin()); it != this->packets.end();) {
782  CargoPacket *cp = *it;
783  if (prev_count > max_move && RandomRange(prev_count) < prev_count - max_move) {
784  if (do_count && loop == 0) {
785  (*cargo_per_source)[cp->source] += cp->count;
786  }
787  ++it;
788  continue;
789  }
790  uint diff = max_move - moved;
791  if (cp->count > diff) {
792  if (diff > 0) {
793  this->RemoveFromCache(cp, diff);
794  cp->Reduce(diff);
795  moved += diff;
796  }
797  if (loop > 0) {
798  if (do_count) (*cargo_per_source)[cp->source] -= diff;
799  return moved;
800  } else {
801  if (do_count) (*cargo_per_source)[cp->source] += cp->count;
802  ++it;
803  }
804  } else {
805  it = this->packets.erase(it);
806  if (do_count && loop > 0) {
807  (*cargo_per_source)[cp->source] -= cp->count;
808  }
809  moved += cp->count;
810  this->RemoveFromCache(cp, cp->count);
811  delete cp;
812  }
813  }
814  loop++;
815  }
816  return moved;
817 }
818 
828 {
829  return this->ShiftCargo(CargoReservation(this, dest, max_move, load_place), next_station, true);
830 }
831 
845 {
846  uint move = min(dest->ActionCount(VehicleCargoList::MTA_LOAD), max_move);
847  if (move > 0) {
848  this->reserved_count -= move;
850  return move;
851  } else {
852  return this->ShiftCargo(CargoLoad(this, dest, max_move, load_place), next_station, true);
853  }
854 }
855 
864 uint StationCargoList::Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge)
865 {
866  return this->ShiftCargo(StationCargoReroute(this, dest, max_move, avoid, avoid2, ge), avoid, false);
867 }
868 
869 /*
870  * We have to instantiate everything we want to be usable.
871  */
874 template uint VehicleCargoList::Reassign<VehicleCargoList::MTA_DELIVER, VehicleCargoList::MTA_KEEP>(uint, TileOrStationID);
Action of rerouting cargo in a station.
Definition: cargoaction.h:128
void AddFeederShare(Money new_share)
Adds some feeder share to the packet.
Definition: cargopacket.h:95
CargoPacketList ::reverse_iterator ReverseIterator
The reverse iterator for our container.
Definition: cargopacket.h:220
Minimal stack that uses a pool to avoid pointers.
void Append(CargoPacket *cp, MoveToAction action=MTA_KEEP)
Appends the given cargo packet.
SourceTypeByte source_type
Type of source_id.
Definition: cargopacket.h:49
Types related to orders.
CargoPacketPool _cargopacket_pool("CargoPacket")
The actual pool with cargo packets.
CargoList that is used for stations.
Definition: cargopacket.h:463
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:29
void SetTransferLoadPlace(TileIndex xy)
Sets loaded_at_xy to the current station for all cargo to be transfered.
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:111
Action of shifting cargo from one vehicle to another.
Definition: cargoaction.h:108
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:136
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:83
static const SourceID INVALID_SOURCE
Invalid/unknown index of source.
Definition: cargo_type.h:147
uint16 count
The amount of cargo in this packet.
Definition: cargopacket.h:47
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...
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:50
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:1227
Container for cargo from the same location and time.
Definition: cargopacket.h:44
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:55
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:356
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:91
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:42
Helper class to perform the cargo payment.
Definition: economy_base.h:26
Action of transferring cargo from a vehicle to a station.
Definition: cargoaction.h:73
#define FOR_ALL_CARGOPACKETS(var)
Iterate over all valid cargo packets from the begin of the pool.
Definition: cargopacket.h:208
MoveToAction
Kind of actions that could be done with packets on move.
Definition: cargopacket.h:227
Transfer all cargo onto the platform.
Definition: order_type.h:61
Action of reserving cargo from a station to be loaded onto a vehicle.
Definition: cargoaction.h:91
uint Truncate(uint max_move=UINT_MAX, StationCargoAmountMap *cargo_per_source=NULL)
Truncates where each destination loses roughly the same percentage of its cargo.
Base class for all pools.
Definition: pool_type.hpp:83
FlowStatMap flows
Planned flows through this station.
Definition: station_base.h:259
SourceType
Types of cargo source and destination.
Definition: cargo_type.h:139
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...
CargoList that is used for vehicles.
Definition: cargopacket.h:283
StationCargoPacketMap ::const_iterator ConstIterator
The const iterator for our container.
Definition: cargopacket.h:222
uint32 TileIndex
The index/ID of a Tile.
Definition: tile_type.h:80
Action of returning previously reserved cargo from the vehicle to the station.
Definition: cargoaction.h:99
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.
Source/destination is an industry.
Definition: cargo_type.h:140
uint16 SourceID
Contains either industry ID, town ID or company ID (or INVALID_SOURCE)
Definition: cargo_type.h:146
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:51
uint Shift(uint max_move, VehicleCargoList *dest)
Shifts cargo between two vehicles.
Totally no unloading will be done.
Definition: order_type.h:62
static bool CanAllocateItem(size_t n=1)
Helper functions so we can use PoolItem::Function() instead of _poolitem_pool.Function() ...
Definition: pool_type.hpp:216
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:101
static const uint16 MAX_COUNT
Maximum number of items in a single cargo packet.
Definition: cargopacket.h:66
Money feeder_share
Value of feeder pickup to be paid for on delivery of cargo.
Definition: cargopacket.h:46
Action of final delivery of cargo.
Definition: cargoaction.h:41
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:54
TileIndex source_xy
The origin of the cargo (first station in feeder chain).
Definition: cargopacket.h:52
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:60
Action of loading cargo from a station onto a vehicle.
Definition: cargoaction.h:81
StationCargoPacketMap ::iterator Iterator
The iterator for our container.
Definition: cargopacket.h:218
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:48
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.