* Check the capacity of all vehicles in a chain and spread cargo if needed. * @param v The vehicle to check. * @pre You can only do this if the consist is not loading or unloading. It * must not carry reserved cargo, nor cargo to be unloaded or transferred. */
| 105 | * must not carry reserved cargo, nor cargo to be unloaded or transferred. |
| 106 | */ |
| 107 | void CheckCargoCapacity(Vehicle *v) |
| 108 | { |
| 109 | assert(v == nullptr || v->First() == v); |
| 110 | |
| 111 | for (Vehicle *src = v; src != nullptr; src = src->Next()) { |
| 112 | assert(src->cargo.TotalCount() == src->cargo.ActionCount(VehicleCargoList::MTA_KEEP)); |
| 113 | |
| 114 | /* Do we need to more cargo away? */ |
| 115 | if (src->cargo.TotalCount() <= src->cargo_cap) continue; |
| 116 | |
| 117 | /* We need to move a particular amount. Try that on the other vehicles. */ |
| 118 | uint to_spread = src->cargo.TotalCount() - src->cargo_cap; |
| 119 | for (Vehicle *dest = v; dest != nullptr && to_spread != 0; dest = dest->Next()) { |
| 120 | assert(dest->cargo.TotalCount() == dest->cargo.ActionCount(VehicleCargoList::MTA_KEEP)); |
| 121 | if (dest->cargo.TotalCount() >= dest->cargo_cap || dest->cargo_type != src->cargo_type) continue; |
| 122 | |
| 123 | uint amount = std::min(to_spread, dest->cargo_cap - dest->cargo.TotalCount()); |
| 124 | src->cargo.Shift(amount, &dest->cargo); |
| 125 | to_spread -= amount; |
| 126 | } |
| 127 | |
| 128 | /* Any left-overs will be thrown away, but not their feeder share. */ |
| 129 | if (src->cargo_cap < src->cargo.TotalCount()) src->cargo.Truncate(src->cargo.TotalCount() - src->cargo_cap); |
| 130 | } |
| 131 | } |
| 132 | |
| 133 | /** |
| 134 | * Transfer cargo from a single (articulated )old vehicle to the new vehicle chain |
no test coverage detected