| 413 | } |
| 414 | |
| 415 | static uint32_t VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, uint8_t variable, uint32_t parameter, bool &available) |
| 416 | { |
| 417 | /* Calculated vehicle parameters */ |
| 418 | switch (variable) { |
| 419 | case 0x25: // Get engine GRF ID |
| 420 | return v->GetGRFID(); |
| 421 | |
| 422 | case 0x40: // Get length of consist |
| 423 | if (!HasBit(v->grf_cache.cache_valid, NCVV_POSITION_CONSIST_LENGTH)) { |
| 424 | v->grf_cache.position_consist_length = PositionHelper(v, false); |
| 425 | SetBit(v->grf_cache.cache_valid, NCVV_POSITION_CONSIST_LENGTH); |
| 426 | } |
| 427 | return v->grf_cache.position_consist_length; |
| 428 | |
| 429 | case 0x41: // Get length of same consecutive wagons |
| 430 | if (!HasBit(v->grf_cache.cache_valid, NCVV_POSITION_SAME_ID_LENGTH)) { |
| 431 | v->grf_cache.position_same_id_length = PositionHelper(v, true); |
| 432 | SetBit(v->grf_cache.cache_valid, NCVV_POSITION_SAME_ID_LENGTH); |
| 433 | } |
| 434 | return v->grf_cache.position_same_id_length; |
| 435 | |
| 436 | case 0x42: { // Consist cargo information |
| 437 | if (!HasBit(v->grf_cache.cache_valid, NCVV_CONSIST_CARGO_INFORMATION)) { |
| 438 | std::array<uint8_t, NUM_CARGO> common_cargoes{}; |
| 439 | uint8_t cargo_classes = 0; |
| 440 | uint8_t user_def_data = 0; |
| 441 | |
| 442 | for (const Vehicle *u = v; u != nullptr; u = u->Next()) { |
| 443 | if (v->type == VEH_TRAIN) user_def_data |= Train::From(u)->tcache.user_def_data; |
| 444 | |
| 445 | /* Skip empty engines */ |
| 446 | if (!u->GetEngine()->CanCarryCargo()) continue; |
| 447 | |
| 448 | cargo_classes |= CargoSpec::Get(u->cargo_type)->classes.base(); |
| 449 | common_cargoes[u->cargo_type]++; |
| 450 | } |
| 451 | |
| 452 | /* Pick the most common cargo type */ |
| 453 | auto cargo_it = std::max_element(std::begin(common_cargoes), std::end(common_cargoes)); |
| 454 | /* Return INVALID_CARGO if nothing is carried */ |
| 455 | CargoType common_cargo_type = (*cargo_it == 0) ? INVALID_CARGO : static_cast<CargoType>(std::distance(std::begin(common_cargoes), cargo_it)); |
| 456 | |
| 457 | /* Count subcargo types of common_cargo_type */ |
| 458 | std::array<uint8_t, UINT8_MAX + 1> common_subtypes{}; |
| 459 | for (const Vehicle *u = v; u != nullptr; u = u->Next()) { |
| 460 | /* Skip empty engines and engines not carrying common_cargo_type */ |
| 461 | if (u->cargo_type != common_cargo_type || !u->GetEngine()->CanCarryCargo()) continue; |
| 462 | |
| 463 | common_subtypes[u->cargo_subtype]++; |
| 464 | } |
| 465 | |
| 466 | /* Pick the most common subcargo type*/ |
| 467 | auto subtype_it = std::max_element(std::begin(common_subtypes), std::end(common_subtypes)); |
| 468 | /* Return UINT8_MAX if nothing is carried */ |
| 469 | uint8_t common_subtype = (*subtype_it == 0) ? UINT8_MAX : static_cast<uint8_t>(std::distance(std::begin(common_subtypes), subtype_it)); |
| 470 | |
| 471 | /* Note: We have to store the untranslated cargotype in the cache as the cache can be read by different NewGRFs, |
| 472 | * which will need different translations */ |
no test coverage detected