* Refresh link stats for the given pair of orders. * @param cur Last stop where the consist could interact with cargo. * @param next Next order to be processed. */
| 179 | * @param next Next order to be processed. |
| 180 | */ |
| 181 | void LinkRefresher::RefreshStats(VehicleOrderID cur, VehicleOrderID next) |
| 182 | { |
| 183 | assert(this->vehicle->orders != nullptr); |
| 184 | const OrderList &orderlist = *this->vehicle->orders; |
| 185 | auto orders = orderlist.GetOrders(); |
| 186 | |
| 187 | StationID next_station = orders[next].GetDestination().ToStationID(); |
| 188 | Station *st = Station::GetIfValid(orders[cur].GetDestination().ToStationID()); |
| 189 | if (st != nullptr && next_station != StationID::Invalid() && next_station != st->index) { |
| 190 | Station *st_to = Station::Get(next_station); |
| 191 | for (CargoType cargo = 0; cargo < NUM_CARGO; ++cargo) { |
| 192 | /* Refresh the link and give it a minimum capacity. */ |
| 193 | |
| 194 | uint cargo_quantity = this->capacities[cargo]; |
| 195 | if (cargo_quantity == 0) continue; |
| 196 | |
| 197 | if (this->vehicle->GetDisplayMaxSpeed() == 0) continue; |
| 198 | |
| 199 | /* If not allowed to merge link graphs, make sure the stations are |
| 200 | * already in the same link graph. */ |
| 201 | if (!this->allow_merge && st->goods[cargo].link_graph != st_to->goods[cargo].link_graph) { |
| 202 | continue; |
| 203 | } |
| 204 | |
| 205 | /* A link is at least partly restricted if a vehicle can't load at its source. */ |
| 206 | EdgeUpdateMode restricted_mode = orders[cur].GetLoadType() != OrderLoadType::NoLoad ? |
| 207 | EdgeUpdateMode::Unrestricted : EdgeUpdateMode::Restricted; |
| 208 | /* This estimates the travel time of the link as the time needed |
| 209 | * to travel between the stations at half the max speed of the consist. |
| 210 | * The result is in tiles/tick (= 2048 km-ish/h). */ |
| 211 | uint32_t time_estimate = DistanceManhattan(st->xy, st_to->xy) * 4096U / this->vehicle->GetDisplayMaxSpeed(); |
| 212 | |
| 213 | /* If the vehicle is currently full loading, increase the capacities at the station |
| 214 | * where it is loading by an estimate of what it would have transported if it wasn't |
| 215 | * loading. Don't do that if the vehicle has been waiting for longer than the entire |
| 216 | * order list is supposed to take, though. If that is the case the total duration is |
| 217 | * probably far off and we'd greatly overestimate the capacity by increasing.*/ |
| 218 | if (this->is_full_loading && this->vehicle->orders != nullptr && |
| 219 | st->index == vehicle->last_station_visited && |
| 220 | this->vehicle->orders->GetTotalDuration() > this->vehicle->current_order_time) { |
| 221 | uint effective_capacity = cargo_quantity * this->vehicle->load_unload_ticks; |
| 222 | if (effective_capacity > (uint)this->vehicle->orders->GetTotalDuration()) { |
| 223 | IncreaseStats(st, cargo, next_station, effective_capacity / |
| 224 | this->vehicle->orders->GetTotalDuration(), 0, 0, |
| 225 | {EdgeUpdateMode::Increase, restricted_mode}); |
| 226 | } else if (RandomRange(this->vehicle->orders->GetTotalDuration()) < effective_capacity) { |
| 227 | IncreaseStats(st, cargo, next_station, 1, 0, 0, {EdgeUpdateMode::Increase, restricted_mode}); |
| 228 | } else { |
| 229 | IncreaseStats(st, cargo, next_station, cargo_quantity, 0, time_estimate, {EdgeUpdateMode::Refresh, restricted_mode}); |
| 230 | } |
| 231 | } else { |
| 232 | IncreaseStats(st, cargo, next_station, cargo_quantity, 0, time_estimate, {EdgeUpdateMode::Refresh, restricted_mode}); |
| 233 | } |
| 234 | } |
| 235 | } |
| 236 | } |
| 237 | |
| 238 | /** |
no test coverage detected