* Clone/share/copy an order-list of another vehicle. * @param flags operation to perform * @param action action to perform * @param veh_dst destination vehicle to clone orders to * @param veh_src source vehicle to clone orders from, if any (none for CO_UNSHARE) * @return the cost of this operation or an error */
| 1495 | * @return the cost of this operation or an error |
| 1496 | */ |
| 1497 | CommandCost CmdCloneOrder(DoCommandFlags flags, CloneOptions action, VehicleID veh_dst, VehicleID veh_src) |
| 1498 | { |
| 1499 | Vehicle *dst = Vehicle::GetIfValid(veh_dst); |
| 1500 | if (dst == nullptr || !dst->IsPrimaryVehicle()) return CMD_ERROR; |
| 1501 | |
| 1502 | CommandCost ret = CheckOwnership(dst->owner); |
| 1503 | if (ret.Failed()) return ret; |
| 1504 | |
| 1505 | switch (action) { |
| 1506 | case CO_SHARE: { |
| 1507 | Vehicle *src = Vehicle::GetIfValid(veh_src); |
| 1508 | |
| 1509 | /* Sanity checks */ |
| 1510 | if (src == nullptr || !src->IsPrimaryVehicle() || dst->type != src->type || dst == src) return CMD_ERROR; |
| 1511 | |
| 1512 | ret = CheckOwnership(src->owner); |
| 1513 | if (ret.Failed()) return ret; |
| 1514 | |
| 1515 | /* Trucks can't share orders with busses (and visa versa) */ |
| 1516 | if (src->type == VEH_ROAD && RoadVehicle::From(src)->IsBus() != RoadVehicle::From(dst)->IsBus()) { |
| 1517 | return CMD_ERROR; |
| 1518 | } |
| 1519 | |
| 1520 | /* Is the vehicle already in the shared list? */ |
| 1521 | if (src->FirstShared() == dst->FirstShared()) return CMD_ERROR; |
| 1522 | |
| 1523 | for (const Order &order : src->Orders()) { |
| 1524 | if (!OrderGoesToStation(dst, order)) continue; |
| 1525 | |
| 1526 | /* Allow copying unreachable destinations if they were already unreachable for the source. |
| 1527 | * This is basically to allow cloning / autorenewing / autoreplacing vehicles, while the stations |
| 1528 | * are temporarily invalid due to reconstruction. */ |
| 1529 | const Station *st = Station::Get(order.GetDestination().ToStationID()); |
| 1530 | if (CanVehicleUseStation(src, st) && !CanVehicleUseStation(dst, st)) { |
| 1531 | return CommandCost(STR_ERROR_CAN_T_COPY_SHARE_ORDER, GetVehicleCannotUseStationReason(dst, st)); |
| 1532 | } |
| 1533 | } |
| 1534 | |
| 1535 | /* Check for aircraft range limits. */ |
| 1536 | if (dst->type == VEH_AIRCRAFT && !CheckAircraftOrderDistance(Aircraft::From(dst), src)) { |
| 1537 | return CommandCost(STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE); |
| 1538 | } |
| 1539 | |
| 1540 | if (src->orders == nullptr && !OrderList::CanAllocateItem()) { |
| 1541 | return CommandCost(STR_ERROR_NO_MORE_SPACE_FOR_ORDERS); |
| 1542 | } |
| 1543 | |
| 1544 | if (flags.Test(DoCommandFlag::Execute)) { |
| 1545 | /* If the destination vehicle had a OrderList, destroy it. |
| 1546 | * We only reset the order indices, if the new orders are obviously different. |
| 1547 | * (We mainly do this to keep the order indices valid and in range.) */ |
| 1548 | DeleteVehicleOrders(dst, false, dst->GetNumOrders() != src->GetNumOrders()); |
| 1549 | |
| 1550 | dst->orders = src->orders; |
| 1551 | |
| 1552 | /* Link this vehicle in the shared-list */ |
| 1553 | dst->AddToShared(src); |
| 1554 |
nothing calls this directly
no test coverage detected