* Iterate over orders starting at \a cur and \a next and refresh links * associated with them. \a cur and \a next can be equal. If they're not they * must be "neighbours" in their order list, which means \a next must be directly * reachable from \a cur without passing any further OT_GOTO_STATION or * OT_IMPLICIT orders in between. * @param cur Current order being evaluated. * @param next Nex
| 247 | * @param num_hops Number of hops already taken by recursive calls to this method. |
| 248 | */ |
| 249 | void LinkRefresher::RefreshLinks(VehicleOrderID cur, VehicleOrderID next, RefreshFlags flags, uint num_hops) |
| 250 | { |
| 251 | assert(this->vehicle->orders != nullptr); |
| 252 | const OrderList &orderlist = *this->vehicle->orders; |
| 253 | while (next < orderlist.GetNumOrders()) { |
| 254 | const Order *next_order = orderlist.GetOrderAt(next); |
| 255 | |
| 256 | if ((next_order->IsType(OT_GOTO_DEPOT) || next_order->IsType(OT_GOTO_STATION)) && next_order->IsRefit()) { |
| 257 | flags.Set(RefreshFlag::WasRefit); |
| 258 | if (!next_order->IsAutoRefit()) { |
| 259 | this->HandleRefit(next_order->GetRefitCargo()); |
| 260 | } else if (!flags.Test(RefreshFlag::InAutorefit)) { |
| 261 | flags.Set(RefreshFlag::InAutorefit); |
| 262 | LinkRefresher backup(*this); |
| 263 | for (CargoType cargo = 0; cargo != NUM_CARGO; ++cargo) { |
| 264 | if (CargoSpec::Get(cargo)->IsValid() && this->HandleRefit(cargo)) { |
| 265 | this->RefreshLinks(cur, next, flags, num_hops); |
| 266 | *this = backup; |
| 267 | } |
| 268 | } |
| 269 | } |
| 270 | } |
| 271 | |
| 272 | /* Only reset the refit capacities if the "previous" next is a station, |
| 273 | * meaning that either the vehicle was refit at the previous station or |
| 274 | * it wasn't at all refit during the current hop. */ |
| 275 | if (flags.Test(RefreshFlag::WasRefit) && (next_order->IsType(OT_GOTO_STATION) || next_order->IsType(OT_IMPLICIT))) { |
| 276 | flags.Set(RefreshFlag::ResetRefit); |
| 277 | } else { |
| 278 | flags.Reset(RefreshFlag::ResetRefit); |
| 279 | } |
| 280 | |
| 281 | next = this->PredictNextOrder(cur, next, flags, num_hops); |
| 282 | if (next == INVALID_VEH_ORDER_ID) break; |
| 283 | Hop hop(cur, next, this->cargo); |
| 284 | if (this->seen_hops->find(hop) != this->seen_hops->end()) { |
| 285 | break; |
| 286 | } else { |
| 287 | this->seen_hops->insert(hop); |
| 288 | } |
| 289 | |
| 290 | next_order = orderlist.GetOrderAt(next); |
| 291 | |
| 292 | /* Don't use the same order again, but choose a new one in the next round. */ |
| 293 | flags.Reset(RefreshFlag::UseNext); |
| 294 | |
| 295 | /* Skip resetting and link refreshing if next order won't do anything with cargo. */ |
| 296 | if (!next_order->IsType(OT_GOTO_STATION) && !next_order->IsType(OT_IMPLICIT)) continue; |
| 297 | |
| 298 | if (flags.Test(RefreshFlag::ResetRefit)) { |
| 299 | this->ResetRefit(); |
| 300 | flags.Reset({RefreshFlag::ResetRefit, RefreshFlag::WasRefit}); |
| 301 | } |
| 302 | |
| 303 | const Order *cur_order = orderlist.GetOrderAt(cur); |
| 304 | |
| 305 | if (cur_order->IsType(OT_GOTO_STATION) || cur_order->IsType(OT_IMPLICIT)) { |
| 306 | if (cur_order->CanLeaveWithCargo(flags.Test(RefreshFlag::HasCargo))) { |
no test coverage detected