MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / Stage

Method Stage

src/cargopacket.cpp:435–527  ·  view source on GitHub ↗

* Stages cargo for unloading. The cargo is sorted so that packets to be * transferred, delivered or kept are in consecutive chunks in the list. At the * same time the designation_counts are updated to reflect the size of those * chunks. * @param accepted If the cargo will be accepted at the station. * @param current_station ID of the station. * @param next_station ID of the station the vehic

Source from the content-addressed store, hash-verified

433 * return If any cargo will be unloaded.
434 */
435bool 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);

Callers 1

PrepareUnloadFunction · 0.80

Calls 15

InvalidFunction · 0.85
NOT_REACHEDFunction · 0.85
ChangeShareMethod · 0.80
GetSharesMethod · 0.80
GetViaWithRestrictedMethod · 0.80
push_backMethod · 0.80
PayTransferMethod · 0.80
AddFeederShareMethod · 0.80
endMethod · 0.45
beginMethod · 0.45
HasDataMethod · 0.45

Tested by

no test coverage detected