1401 } else if (age == 366*1 || age == 366*2 || age == 366*3 || age == 366*4 || age == 366*5) { |
1401 } else if (age == 366*1 || age == 366*2 || age == 366*3 || age == 366*4 || age == 366*5) { |
1402 ShowVehicleGettingOld(v, STR_01A2_IS_GETTING_VERY_OLD_AND); |
1402 ShowVehicleGettingOld(v, STR_01A2_IS_GETTING_VERY_OLD_AND); |
1403 } |
1403 } |
1404 } |
1404 } |
1405 |
1405 |
1406 extern int32 EstimateTrainCost(const RailVehicleInfo *rvi); |
|
1407 extern int32 EstimateRoadVehCost(EngineID engine_type); |
|
1408 extern int32 EstimateShipCost(EngineID engine_type); |
|
1409 extern int32 EstimateAircraftCost(EngineID engine_type); |
|
1410 extern int32 CmdRefitRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2); |
|
1411 extern int32 CmdRefitShip(int x, int y, uint32 flags, uint32 p1, uint32 p2); |
|
1412 extern int32 CmdRefitAircraft(int x, int y, uint32 flags, uint32 p1, uint32 p2); |
|
1413 |
|
1414 int32 CmdCloneOrder(int x, int y, uint32 flags, uint32 veh1_veh2, uint32 mode); |
|
1415 int32 CmdMoveRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2); |
|
1416 int32 CmdBuildRailVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2); |
|
1417 int32 CmdBuildRoadVeh(int x, int y, uint32 flags, uint32 p1, uint32 p2); |
|
1418 int32 CmdBuildShip(int x, int y, uint32 flags, uint32 p1, uint32 p2); |
|
1419 int32 CmdBuildAircraft(int x, int y, uint32 flags, uint32 p1, uint32 p2); |
|
1420 |
|
1421 typedef int32 VehBuildProc(int x, int y, uint32 flags, uint32 p1, uint32 p2); |
|
1422 |
|
1423 static VehBuildProc * const _veh_build_cmd_table[] = { |
|
1424 CmdBuildRailVehicle, |
|
1425 CmdBuildRoadVeh, |
|
1426 CmdBuildShip, |
|
1427 CmdBuildAircraft, |
|
1428 }; |
|
1429 |
|
1430 static VehicleID * _new_vehicle_id_proc_table[] = { |
1406 static VehicleID * _new_vehicle_id_proc_table[] = { |
1431 &_new_train_id, |
1407 &_new_train_id, |
1432 &_new_roadveh_id, |
1408 &_new_roadveh_id, |
1433 &_new_ship_id, |
1409 &_new_ship_id, |
1434 &_new_aircraft_id, |
1410 &_new_aircraft_id, |
1435 }; |
1411 }; |
1436 |
1412 |
1437 /** Clone a vehicle. If it is a train, it will clone all the cars too |
1413 /** Clone a vehicle. If it is a train, it will clone all the cars too |
1438 * @param x,y unused |
1414 * @param x,y depot where the cloned vehicle is build |
1439 * @param p1 the original vehicle's index |
1415 * @param p1 the original vehicle's index |
1440 * @param p2 1 = shared orders, else copied orders |
1416 * @param p2 1 = shared orders, else copied orders |
1441 */ |
1417 */ |
1442 int32 CmdCloneVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2) |
1418 int32 CmdCloneVehicle(int x, int y, uint32 flags, uint32 p1, uint32 p2) |
1443 { |
1419 { |
1444 Vehicle *vfront, *v; |
1420 Vehicle *v_front, *v; |
1445 Vehicle *wfront, *w1, *w2; |
1421 Vehicle *w_front, *w, *w_rear; |
1446 int cost, total_cost; |
1422 int cost, total_cost = 0; |
1447 VehBuildProc *proc; |
|
1448 VehicleID *new_id; |
1423 VehicleID *new_id; |
1449 uint refit_command = 0; |
|
1450 byte needs_refitting = 255; |
|
1451 |
1424 |
1452 if (!IsVehicleIndex(p1)) |
1425 if (!IsVehicleIndex(p1)) |
1453 return CMD_ERROR; |
1426 return CMD_ERROR; |
1454 v = GetVehicle(p1); |
1427 v = GetVehicle(p1); |
1455 wfront = v; |
1428 v_front = v; |
1456 w1 = v; |
1429 w = NULL; |
1457 vfront = v; |
1430 w_front = NULL; |
|
1431 w_rear = NULL; |
|
1432 |
|
1433 |
|
1434 /* |
|
1435 * v_front is the front engine in the original vehicle |
|
1436 * v is the car/vehicle of the original vehicle, that is currently being copied |
|
1437 * w_front is the front engine of the cloned vehicle |
|
1438 * w is the car/vehicle currently being cloned |
|
1439 * w_rear is the rear end of the cloned train. It's used to add more cars and is only used by trains |
|
1440 */ |
1458 |
1441 |
1459 if (!CheckOwnership(v->owner)) |
1442 if (!CheckOwnership(v->owner)) |
1460 return CMD_ERROR; |
1443 return CMD_ERROR; |
1461 |
1444 |
1462 if (v->type == VEH_Train && v->subtype != TS_Front_Engine) return CMD_ERROR; |
1445 if (v->type == VEH_Train && v->subtype != TS_Front_Engine) return CMD_ERROR; |
1463 |
1446 |
1464 //no need to check if it is a depot since the build command do that |
|
1465 switch (v->type) { |
|
1466 case VEH_Train: refit_command = CMD_REFIT_RAIL_VEHICLE; break; |
|
1467 case VEH_Road: break; |
|
1468 case VEH_Ship: refit_command = CMD_REFIT_SHIP; break; |
|
1469 case VEH_Aircraft: refit_command = CMD_REFIT_AIRCRAFT; break; |
|
1470 default: return CMD_ERROR; |
|
1471 } |
|
1472 |
|
1473 proc = _veh_build_cmd_table[v->type - VEH_Train]; |
|
1474 new_id = _new_vehicle_id_proc_table[v->type - VEH_Train]; |
1447 new_id = _new_vehicle_id_proc_table[v->type - VEH_Train]; |
1475 total_cost = proc(x, y, flags, v->engine_type, 3); |
1448 |
1476 if (total_cost == CMD_ERROR) |
1449 do { |
1477 return CMD_ERROR; |
1450 cost = DoCommand(x, y, v->engine_type, 3, flags, CMD_BUILD_VEH(v->type)); |
|
1451 |
|
1452 if (CmdFailed(cost)) return cost; |
|
1453 |
|
1454 total_cost += cost; |
|
1455 |
|
1456 if (flags & DC_EXEC) { |
|
1457 if (v->type == VEH_Train && RailVehInfo(v->engine_type)->flags & RVI_WAGON) { |
|
1458 w = GetVehicle(_new_wagon_id); |
|
1459 } else { |
|
1460 w = GetVehicle(*new_id); |
|
1461 } |
|
1462 |
|
1463 if (v->type != VEH_Road) { // road vehicles can't be refitted |
|
1464 if (v->cargo_type != w->cargo_type) { |
|
1465 DoCommand(x, y, w->index, v->cargo_type, flags, CMD_REFIT_VEH(v->type)); |
|
1466 } |
|
1467 } |
|
1468 |
|
1469 if (v->type == VEH_Train && v->subtype != TS_Front_Engine) { |
|
1470 // this s a train car |
|
1471 |
|
1472 // add this unit to the end of the train |
|
1473 DoCommand(x, y, (w_rear->index << 16) | w->index, 1, flags, CMD_MOVE_RAIL_VEHICLE); |
|
1474 } else { |
|
1475 // this is a front engine or not a train. It need orders |
|
1476 w_front = w; |
|
1477 DoCommand(x, y, (v->index << 16) | w->index, p2 & 1 ? CO_SHARE : CO_COPY, flags, CMD_CLONE_ORDER); |
|
1478 } |
|
1479 w_rear = w; // trains needs to know the last car in the train, so they can add more in next loop |
|
1480 } |
|
1481 } while (v->type == VEH_Train && (v=v->next) != NULL); |
1478 |
1482 |
1479 if (flags & DC_EXEC) { |
1483 if (flags & DC_EXEC) { |
1480 wfront = GetVehicle(*new_id); |
1484 v = v_front; |
1481 w1 = wfront; |
1485 w = w_front; |
1482 CmdCloneOrder(x, y, flags, (v->index << 16) | w1->index, p2 & 1 ? CO_SHARE : CO_COPY); |
1486 if (v->type == VEH_Train) { |
1483 |
1487 _new_train_id = w_front->index; // _new_train_id needs to be the front engine due to the callback function |
1484 if (wfront->cargo_type != v->cargo_type) { |
1488 |
1485 //a refit is needed |
1489 while (w != NULL && v != NULL) { // checking both just in case something went wrong |
1486 needs_refitting = v->cargo_type; |
1490 w->spritenum = v->spritenum; // makes sure that multiheaded engines are facing the correct way |
1487 } |
1491 w = w->next; |
1488 } |
|
1489 if (v->type == VEH_Train) { |
|
1490 // now we handle the cars |
|
1491 v = v->next; |
|
1492 while (v != NULL) { |
|
1493 cost = proc(x, y, flags, v->engine_type, 3); |
|
1494 if (cost == CMD_ERROR) |
|
1495 return CMD_ERROR; |
|
1496 total_cost += cost; |
|
1497 |
|
1498 if (flags & DC_EXEC) { |
|
1499 // add this unit to the end of the train |
|
1500 w2 = GetVehicle(RailVehInfo(v->engine_type)->flags & RVI_WAGON ? _new_wagon_id : _new_train_id); |
|
1501 CmdMoveRailVehicle(x, y, flags, (w1->index << 16) | w2->index, 0); |
|
1502 w1 = w2; |
|
1503 } |
|
1504 v = v->next; |
|
1505 } |
|
1506 |
|
1507 if (flags & DC_EXEC) { |
|
1508 _new_train_id = wfront->index; |
|
1509 v = vfront; |
|
1510 w1 = wfront; |
|
1511 while (w1 != NULL && v != NULL) { |
|
1512 w1->spritenum = v->spritenum; // makes sure that multiheaded engines are facing the correct way |
|
1513 if (w1->cargo_type != v->cargo_type) // checks if a refit is needed |
|
1514 needs_refitting = v->cargo_type; |
|
1515 w1 = w1->next; |
|
1516 v = v->next; |
1492 v = v->next; |
1517 } |
1493 } |
1518 |
1494 } |
1519 } |
|
1520 } |
|
1521 if (flags & DC_EXEC && needs_refitting != 255 && vfront->type != VEH_Road) { // right now we do not refit road vehicles |
|
1522 if (DoCommandByTile(wfront->tile, wfront->index, needs_refitting, 0, refit_command) != CMD_ERROR) |
|
1523 DoCommandByTile(wfront->tile, wfront->index, needs_refitting, DC_EXEC, refit_command); |
|
1524 } |
1495 } |
1525 return total_cost; |
1496 return total_cost; |
1526 } |
1497 } |
1527 |
1498 |
1528 /* Replaces a vehicle (used to be called autorenew) |
1499 /* Replaces a vehicle (used to be called autorenew) |