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

Function CmdSellRailWagon

src/train_cmd.cpp:1419–1491  ·  view source on GitHub ↗

* Sell a (single) train wagon/engine. * @param flags type of operation * @param t the train wagon to sell * @param sell_chain the selling mode * - sell_chain = false: only sell the single dragged wagon/engine (and any belonging rear-engines) * - sell_chain = true: sell the vehicle and all vehicles following it in the chain * if the wagon is dragged, don't delete t

Source from the content-addressed store, hash-verified

1417 * @return the cost of this operation or an error
1418 */
1419CommandCost CmdSellRailWagon(DoCommandFlags flags, Vehicle *t, bool sell_chain, bool backup_order, ClientID user)
1420{
1421 Train *v = Train::From(t)->GetFirstEnginePart();
1422 Train *first = v->First();
1423
1424 if (v->IsRearDualheaded()) return CommandCost(STR_ERROR_REAR_ENGINE_FOLLOW_FRONT);
1425
1426 /* First make a backup of the order of the train. That way we can do
1427 * whatever we want with the order and later on easily revert. */
1428 TrainList original;
1429 MakeTrainBackup(original, first);
1430
1431 /* We need to keep track of the new head and the head of what we're going to sell. */
1432 Train *new_head = first;
1433 Train *sell_head = nullptr;
1434
1435 /* Split the train in the wanted way. */
1436 ArrangeTrains(&sell_head, nullptr, &new_head, v, sell_chain);
1437
1438 /* We don't need to validate the second train; it's going to be sold. */
1439 CommandCost ret = ValidateTrains(nullptr, nullptr, first, new_head, !flags.Test(DoCommandFlag::AutoReplace));
1440 if (ret.Failed()) {
1441 /* Restore the train we had. */
1442 RestoreTrainBackup(original);
1443 return ret;
1444 }
1445
1446 if (first->orders == nullptr && !OrderList::CanAllocateItem()) {
1447 /* Restore the train we had. */
1448 RestoreTrainBackup(original);
1449 return CommandCost(STR_ERROR_NO_MORE_SPACE_FOR_ORDERS);
1450 }
1451
1452 CommandCost cost(EXPENSES_NEW_VEHICLES);
1453 for (Train *part = sell_head; part != nullptr; part = part->Next()) cost.AddCost(-part->value);
1454
1455 /* do it? */
1456 if (flags.Test(DoCommandFlag::Execute)) {
1457 /* First normalise the sub types of the chain. */
1458 NormaliseSubtypes(new_head);
1459
1460 if (v == first && !sell_chain && new_head != nullptr && new_head->IsFrontEngine()) {
1461 if (v->IsEngine()) {
1462 /* We are selling the front engine. In this case we want to
1463 * 'give' the order, unit number and such to the new head. */
1464 new_head->orders = first->orders;
1465 new_head->AddToShared(first);
1466 DeleteVehicleOrders(first);
1467
1468 /* Copy other important data from the front engine */
1469 new_head->CopyVehicleConfigAndStatistics(first);
1470 }
1471 GroupStatistics::CountVehicle(new_head, 1); // after copying over the profit, if required
1472 } else if (v->IsPrimaryVehicle() && backup_order) {
1473 OrderBackup::Backup(v, user);
1474 }
1475
1476 /* We need to update the information about the train. */

Callers 1

CmdSellVehicleFunction · 0.85

Calls 15

CommandCostClass · 0.85
MakeTrainBackupFunction · 0.85
ArrangeTrainsFunction · 0.85
ValidateTrainsFunction · 0.85
RestoreTrainBackupFunction · 0.85
NormaliseSubtypesFunction · 0.85
DeleteVehicleOrdersFunction · 0.85
BackupClass · 0.85
NormaliseTrainHeadFunction · 0.85
IsRearDualheadedMethod · 0.80
TestMethod · 0.80
FailedMethod · 0.80

Tested by

no test coverage detected