MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / HandleStationRefit

Function HandleStationRefit

src/economy.cpp:1475–1527  ·  view source on GitHub ↗

* Refit a vehicle in a station. * @param v Vehicle to be refitted. * @param consist_capleft Added cargo capacities in the consist. * @param st Station the vehicle is loading at. * @param next_station Possible next stations the vehicle can travel to. * @param new_cargo_type Target cargo for refit. */

Source from the content-addressed store, hash-verified

1473 * @param new_cargo_type Target cargo for refit.
1474 */
1475static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station *st, std::span<const StationID> next_station, CargoType new_cargo_type)
1476{
1477 Vehicle *v_start = v->GetFirstEnginePart();
1478 if (!IterateVehicleParts(v_start, IsEmptyAction())) return;
1479
1480 Backup<CompanyID> cur_company(_current_company, v->owner);
1481
1482 CargoTypes refit_mask = v->GetEngine()->info.refit_mask;
1483
1484 /* Remove old capacity from consist capacity and collect refit mask. */
1485 IterateVehicleParts(v_start, PrepareRefitAction(consist_capleft, refit_mask));
1486
1487 bool is_auto_refit = new_cargo_type == CARGO_AUTO_REFIT;
1488 if (is_auto_refit) {
1489 /* Get a refittable cargo type with waiting cargo for next_station or StationID::Invalid(). */
1490 new_cargo_type = v_start->cargo_type;
1491 for (CargoType cargo_type : SetCargoBitIterator(refit_mask)) {
1492 if (st->goods[cargo_type].HasData() && st->goods[cargo_type].GetData().cargo.HasCargoFor(next_station)) {
1493 /* Try to find out if auto-refitting would succeed. In case the refit is allowed,
1494 * the returned refit capacity will be greater than zero. */
1495 auto [cc, refit_capacity, mail_capacity, cargo_capacities] = Command<CMD_REFIT_VEHICLE>::Do(DoCommandFlag::QueryCost, v_start->index, cargo_type, 0xFF, true, false, 1); // Auto-refit and only this vehicle including artic parts.
1496 /* Try to balance different loadable cargoes between parts of the consist, so that
1497 * all of them can be loaded. Avoid a situation where all vehicles suddenly switch
1498 * to the first loadable cargo for which there is only one packet. If the capacities
1499 * are equal refit to the cargo of which most is available. This is important for
1500 * consists of only a single vehicle as those will generally have a consist_capleft
1501 * of 0 for all cargoes. */
1502 if (refit_capacity > 0 && (consist_capleft[cargo_type] < consist_capleft[new_cargo_type] ||
1503 (consist_capleft[cargo_type] == consist_capleft[new_cargo_type] &&
1504 st->goods[cargo_type].AvailableCount() > st->goods[new_cargo_type].AvailableCount()))) {
1505 new_cargo_type = cargo_type;
1506 }
1507 }
1508 }
1509 }
1510
1511 /* Refit if given a valid cargo. */
1512 if (new_cargo_type < NUM_CARGO && new_cargo_type != v_start->cargo_type) {
1513 /* StationID::Invalid() because in the DT_MANUAL case that's correct and in the DT_(A)SYMMETRIC
1514 * cases the next hop of the vehicle doesn't really tell us anything if the cargo had been
1515 * "via any station" before reserving. We rather produce some more "any station" cargo than
1516 * misrouting it. */
1517 IterateVehicleParts(v_start, ReturnCargoAction(st, StationID::Invalid()));
1518 CommandCost cost = std::get<0>(Command<CMD_REFIT_VEHICLE>::Do(DoCommandFlag::Execute, v_start->index, new_cargo_type, 0xFF, true, false, 1)); // Auto-refit and only this vehicle including artic parts.
1519 if (cost.Succeeded()) v->First()->profit_this_year -= cost.GetCost() << 8;
1520 }
1521
1522 /* Add new capacity to consist capacity and reserve cargo */
1523 IterateVehicleParts(v_start, FinalizeRefitAction(consist_capleft, st, next_station,
1524 is_auto_refit || v->First()->current_order.IsFullLoadOrder()));
1525
1526 cur_company.Restore();
1527}
1528
1529/**
1530 * Test whether a vehicle can load cargo at a station even if exclusive transport rights are present.

Callers 1

LoadUnloadVehicleFunction · 0.85

Calls 15

IterateVehiclePartsFunction · 0.85
IsEmptyActionClass · 0.85
PrepareRefitActionClass · 0.85
ReturnCargoActionClass · 0.85
InvalidFunction · 0.85
FinalizeRefitActionClass · 0.85
HasCargoForMethod · 0.80
SucceededMethod · 0.80
IsFullLoadOrderMethod · 0.80
GetFirstEnginePartMethod · 0.45
GetEngineMethod · 0.45
HasDataMethod · 0.45

Tested by

no test coverage detected