| 4597 | } |
| 4598 | |
| 4599 | uint MoveGoodsToStation(CargoType cargo, uint amount, Source source, const StationList &all_stations, Owner exclusivity) |
| 4600 | { |
| 4601 | /* Return if nothing to do. Also the rounding below fails for 0. */ |
| 4602 | if (all_stations.empty()) return 0; |
| 4603 | if (amount == 0) return 0; |
| 4604 | |
| 4605 | Station *first_station = nullptr; |
| 4606 | typedef std::pair<Station *, uint> StationInfo; |
| 4607 | std::vector<StationInfo> used_stations; |
| 4608 | |
| 4609 | for (Station *st : all_stations) { |
| 4610 | if (exclusivity != INVALID_OWNER && exclusivity != st->owner) continue; |
| 4611 | if (!CanMoveGoodsToStation(st, cargo)) continue; |
| 4612 | |
| 4613 | /* Avoid allocating a vector if there is only one station to significantly |
| 4614 | * improve performance in this common case. */ |
| 4615 | if (first_station == nullptr) { |
| 4616 | first_station = st; |
| 4617 | continue; |
| 4618 | } |
| 4619 | if (used_stations.empty()) { |
| 4620 | used_stations.reserve(2); |
| 4621 | used_stations.emplace_back(first_station, 0); |
| 4622 | } |
| 4623 | used_stations.emplace_back(st, 0); |
| 4624 | } |
| 4625 | |
| 4626 | /* no stations around at all? */ |
| 4627 | if (first_station == nullptr) return 0; |
| 4628 | |
| 4629 | if (used_stations.empty()) { |
| 4630 | /* only one station around */ |
| 4631 | amount *= first_station->goods[cargo].rating + 1; |
| 4632 | return UpdateStationWaiting(first_station, cargo, amount, source); |
| 4633 | } |
| 4634 | |
| 4635 | TypedIndexContainer<std::array<uint32_t, OWNER_END.base()>, Owner> company_best = {}; // best rating for each company, including OWNER_NONE |
| 4636 | TypedIndexContainer<std::array<uint32_t, OWNER_END.base()>, Owner> company_sum = {}; // sum of ratings for each company |
| 4637 | uint best_rating = 0; |
| 4638 | uint best_sum = 0; // sum of best ratings for each company |
| 4639 | |
| 4640 | for (auto &p : used_stations) { |
| 4641 | auto owner = p.first->owner; |
| 4642 | auto rating = p.first->goods[cargo].rating; |
| 4643 | if (rating > company_best[owner]) { |
| 4644 | best_sum += rating - company_best[owner]; // it's usually faster than iterating companies later |
| 4645 | company_best[owner] = rating; |
| 4646 | if (rating > best_rating) best_rating = rating; |
| 4647 | } |
| 4648 | company_sum[owner] += rating; |
| 4649 | } |
| 4650 | |
| 4651 | /* From now we'll calculate with fractional cargo amounts. |
| 4652 | * First determine how much cargo we really have. */ |
| 4653 | amount *= best_rating + 1; |
| 4654 | |
| 4655 | uint moving = 0; |
| 4656 | for (auto &p : used_stations) { |
no test coverage detected