* Tries to create a cargo subsidy with an industry as source. * @return True iff the subsidy was created. */
| 321 | * @return True iff the subsidy was created. |
| 322 | */ |
| 323 | bool FindSubsidyIndustryCargoRoute() |
| 324 | { |
| 325 | if (!Subsidy::CanAllocateItem()) return false; |
| 326 | |
| 327 | /* Select a random industry. */ |
| 328 | const Industry *src_ind = Industry::GetRandom(); |
| 329 | if (src_ind == nullptr) return false; |
| 330 | |
| 331 | uint trans, total; |
| 332 | |
| 333 | CargoType cargo_type; |
| 334 | |
| 335 | /* Randomize cargo type */ |
| 336 | int num_cargos = std::ranges::count_if(src_ind->produced, [](const auto &p) { return IsValidCargoType(p.cargo); }); |
| 337 | if (num_cargos == 0) return false; // industry produces nothing |
| 338 | int cargo_num = RandomRange(num_cargos) + 1; |
| 339 | |
| 340 | auto it = std::begin(src_ind->produced); |
| 341 | for (/* nothing */; it != std::end(src_ind->produced); ++it) { |
| 342 | if (IsValidCargoType(it->cargo)) cargo_num--; |
| 343 | if (cargo_num == 0) break; |
| 344 | } |
| 345 | assert(it != std::end(src_ind->produced)); // indicates loop didn't end as intended |
| 346 | |
| 347 | cargo_type = it->cargo; |
| 348 | trans = it->history[LAST_MONTH].PctTransported(); |
| 349 | total = it->history[LAST_MONTH].production; |
| 350 | |
| 351 | /* Quit if no production in this industry |
| 352 | * or if the pct transported is already large enough |
| 353 | * or if the cargo is automatically distributed */ |
| 354 | if (total == 0 || trans > SUBSIDY_MAX_PCT_TRANSPORTED || |
| 355 | !IsValidCargoType(cargo_type) || |
| 356 | _settings_game.linkgraph.GetDistributionType(cargo_type) != DT_MANUAL) { |
| 357 | return false; |
| 358 | } |
| 359 | |
| 360 | return FindSubsidyCargoDestination(cargo_type, {src_ind->index, SourceType::Industry}); |
| 361 | } |
| 362 | |
| 363 | /** |
| 364 | * Tries to find a suitable destination for the given source and cargo. |
no test coverage detected