* 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
| 1417 | * @return the cost of this operation or an error |
| 1418 | */ |
| 1419 | CommandCost 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. */ |
no test coverage detected