(svn r16723) -Codechange: make GetNextArticPart(), GetLastEnginePart(), GetNextVehicle(), GetPrevVehicle(), GetNextUnit(), GetPrevUnit() members of Train

This commit is contained in:
smatz 2009-07-02 12:10:39 +00:00
parent 4d14c1b534
commit 6a0855f0d1
7 changed files with 133 additions and 131 deletions

View File

@ -31,7 +31,7 @@
const Train *v = ::Train::GetIfValid(vehicle_id);
if (v != NULL) {
while ((v = GetNextUnit(v)) != NULL) num++;
while ((v = v->GetNextUnit()) != NULL) num++;
}
return num;
@ -87,11 +87,11 @@
EnforcePrecondition(false, dest_vehicle_id == -1 || ::Vehicle::Get(dest_vehicle_id)->type == VEH_TRAIN);
const Train *v = ::Train::Get(source_vehicle_id);
while (source_wagon-- > 0) v = GetNextUnit(v);
while (source_wagon-- > 0) v = v->GetNextUnit();
const Train *w = NULL;
if (dest_vehicle_id != -1) {
w = ::Train::Get(dest_vehicle_id);
while (dest_wagon-- > 0) w = GetNextUnit(w);
while (dest_wagon-- > 0) w = w->GetNextUnit();
}
return AIObject::DoCommand(0, v->index | ((w == NULL ? INVALID_VEHICLE : w->index) << 16), move_attached_wagons ? 1 : 0, CMD_MOVE_RAIL_VEHICLE);
@ -138,7 +138,7 @@
EnforcePrecondition(false, ::Vehicle::Get(vehicle_id)->type == VEH_TRAIN);
const Train *v = ::Train::Get(vehicle_id);
while (wagon-- > 0) v = GetNextUnit(v);
while (wagon-- > 0) v = v->GetNextUnit();
return AIObject::DoCommand(0, v->index, sell_attached_wagons ? 1 : 0, CMD_SELL_RAIL_WAGON);
}
@ -244,7 +244,7 @@
const Vehicle *v = ::Vehicle::Get(vehicle_id);
if (v->type == VEH_TRAIN) {
while (wagon-- > 0) v = GetNextUnit(::Train::From(v));
while (wagon-- > 0) v = ::Train::From(v)->GetNextUnit();
}
return v->engine_type;
}
@ -282,7 +282,7 @@
const Vehicle *v = ::Vehicle::Get(vehicle_id);
if (v->type == VEH_TRAIN) {
while (wagon-- > 0) v = GetNextUnit(::Train::From(v));
while (wagon-- > 0) v = ::Train::From(v)->GetNextUnit();
}
return v->age;
}

View File

@ -207,7 +207,7 @@ bool IsArticulatedVehicleCarryingDifferentCargos(const Vehicle *v, CargoID *carg
switch (v->type) {
case VEH_TRAIN:
v = Train::From(v)->HasArticulatedPart() ? GetNextArticPart(Train::From(v)) : NULL;
v = Train::From(v)->HasArticulatedPart() ? Train::From(v)->GetNextArticPart() : NULL;
break;
case VEH_ROAD:
@ -254,7 +254,7 @@ void CheckConsistencyOfArticulatedVehicle(const Vehicle *v)
switch (v->type) {
case VEH_TRAIN:
v = Train::From(v)->HasArticulatedPart() ? GetNextArticPart(Train::From(v)) : NULL;
v = Train::From(v)->HasArticulatedPart() ? Train::From(v)->GetNextArticPart() : NULL;
break;
case VEH_ROAD:

View File

@ -94,7 +94,7 @@ static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chai
for (Vehicle *src = old_veh; src != NULL; src = src->Next()) {
if (!part_of_chain && src->type == VEH_TRAIN && src != old_veh && src != Train::From(old_veh)->other_multiheaded_part && !Train::From(src)->IsArticulatedPart()) {
/* Skip vehicles, which do not belong to old_veh */
src = GetLastEnginePart(Train::From(src));
src = Train::From(src)->GetLastEnginePart();
continue;
}
if (src->cargo_type >= NUM_CARGO || src->cargo.Count() == 0) continue;
@ -103,7 +103,7 @@ static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chai
for (Vehicle *dest = new_head; dest != NULL && src->cargo.Count() > 0; dest = dest->Next()) {
if (!part_of_chain && dest->type == VEH_TRAIN && dest != new_head && dest != Train::From(new_head)->other_multiheaded_part && !Train::From(dest)->IsArticulatedPart()) {
/* Skip vehicles, which do not belong to new_head */
dest = GetLastEnginePart(Train::From(dest));
dest = Train::From(dest)->GetLastEnginePart();
continue;
}
if (dest->cargo_type != src->cargo_type) continue;
@ -406,7 +406,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
uint16 old_total_length = (Train::From(old_head)->tcache.cached_total_length + TILE_SIZE - 1) / TILE_SIZE * TILE_SIZE;
int num_units = 0; ///< Number of units in the chain
for (Train *w = Train::From(old_head); w != NULL; w = GetNextUnit(w)) num_units++;
for (Train *w = Train::From(old_head); w != NULL; w = w->GetNextUnit()) num_units++;
Train **old_vehs = CallocT<Train *>(num_units); ///< Will store vehicles of the old chain in their order
Train **new_vehs = CallocT<Train *>(num_units); ///< New vehicles corresponding to old_vehs or NULL if no replacement
@ -416,7 +416,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
* Note: The replacement vehicles can only successfully build as long as the old vehicles are still in their chain */
int i;
Train *w;
for (w = Train::From(old_head), i = 0; w != NULL; w = GetNextUnit(w), i++) {
for (w = Train::From(old_head), i = 0; w != NULL; w = w->GetNextUnit(), i++) {
assert(i < num_units);
old_vehs[i] = w;
@ -432,10 +432,10 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
/* Note: When autoreplace has already failed here, old_vehs[] is not completely initialized. But it is also not needed. */
if (cost.Succeeded()) {
/* Separate the head, so we can start constructing the new chain */
Train *second = GetNextUnit(Train::From(old_head));
Train *second = Train::From(old_head)->GetNextUnit();
if (second != NULL) cost.AddCost(MoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true));
assert(GetNextUnit(new_head) == NULL);
assert(Train::From(new_head)->GetNextUnit() == NULL);
/* Append engines to the new chain
* We do this from back to front, so that the head of the temporary vehicle chain does not change all the time.
@ -479,7 +479,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
} else {
/* We have reached 'last_engine', continue with the next engine towards the front */
assert(append == last_engine);
last_engine = GetPrevUnit(last_engine);
last_engine = last_engine->GetPrevUnit();
}
}
}
@ -538,10 +538,10 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon
* Note: The vehicle attach callback is disabled here :) */
if ((flags & DC_EXEC) == 0) {
/* Separate the head, so we can reattach the old vehicles */
Train *second = GetNextUnit(Train::From(old_head));
Train *second = Train::From(old_head)->GetNextUnit();
if (second != NULL) MoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true);
assert(GetNextUnit(Train::From(old_head)) == NULL);
assert(Train::From(old_head)->GetNextUnit() == NULL);
for (int i = num_units - 1; i > 0; i--) {
CommandCost ret = MoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false);
@ -633,7 +633,7 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1
bool any_replacements = false;
while (w != NULL && !any_replacements) {
any_replacements = (GetNewEngineType(w, c) != INVALID_ENGINE);
w = (!free_wagon && w->type == VEH_TRAIN ? GetNextUnit(Train::From(w)) : NULL);
w = (!free_wagon && w->type == VEH_TRAIN ? Train::From(w)->GetNextUnit() : NULL);
}
if (any_replacements) {

View File

@ -44,7 +44,7 @@ void ConnectMultiheadedTrains()
bool sequential_matching = v->IsFrontEngine();
for (Train *u = v; u != NULL; u = GetNextVehicle(u)) {
for (Train *u = v; u != NULL; u = u->GetNextVehicle()) {
if (u->other_multiheaded_part != NULL) continue; // we already linked this one
if (u->IsMultiheaded()) {
@ -58,7 +58,7 @@ void ConnectMultiheadedTrains()
EngineID eid = u->engine_type;
Train *w;
if (sequential_matching) {
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
for (w = u->GetNextVehicle(); w != NULL; w = w->GetNextVehicle()) {
if (w->engine_type != eid || w->other_multiheaded_part != NULL || !w->IsMultiheaded()) continue;
/* we found a car to partner with this engine. Now we will make sure it face the right way */
@ -70,7 +70,7 @@ void ConnectMultiheadedTrains()
}
} else {
uint stack_pos = 0;
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
for (w = u->GetNextVehicle(); w != NULL; w = w->GetNextVehicle()) {
if (w->engine_type != eid || w->other_multiheaded_part != NULL || !w->IsMultiheaded()) continue;
if (w->IsEngine()) {

View File

@ -37,21 +37,6 @@ enum VehicleRailFlags {
VRF_TRAIN_STUCK = 8,
};
/** enum to handle train subtypes
* Do not access it directly unless you have to. Use the access functions below
* This is an enum to tell what bit to access as it is a bitmask
*/
enum TrainSubtype {
TS_FRONT = 0, ///< Leading engine of a train
TS_ARTICULATED_PART = 1, ///< Articulated part of an engine
TS_WAGON = 2, ///< Wagon
TS_ENGINE = 3, ///< Engine, that can be front engines, but might be placed behind another engine
TS_FREE_WAGON = 4, ///< First in a wagon chain (in depot)
TS_MULTIHEADED = 5, ///< Engine is a multiheaded
};
void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2);
void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2);
@ -149,6 +134,21 @@ struct Train : public SpecializedVehicle<Train, VEH_TRAIN> {
TileIndex GetOrderStationLocation(StationID station);
bool FindClosestDepot(TileIndex *location, DestinationID *destination, bool *reverse);
/**
* enum to handle train subtypes
* Do not access it directly unless you have to. Use the access functions below
* This is an enum to tell what bit to access as it is a bitmask
*/
enum TrainSubtype {
TS_FRONT = 0, ///< Leading engine of a train
TS_ARTICULATED_PART = 1, ///< Articulated part of an engine
TS_WAGON = 2, ///< Wagon
TS_ENGINE = 3, ///< Engine, that can be front engine, but might be placed behind another engine
TS_FREE_WAGON = 4, ///< First in a wagon chain (in depot)
TS_MULTIHEADED = 5, ///< Engine is multiheaded
};
/**
* Set front engine state
*/
@ -181,7 +181,6 @@ struct Train : public SpecializedVehicle<Train, VEH_TRAIN> {
/**
* Set engine status
* @param v vehicle to change
*/
FORCEINLINE void SetEngine() { SetBit(this->subtype, TS_ENGINE); }
@ -197,7 +196,6 @@ struct Train : public SpecializedVehicle<Train, VEH_TRAIN> {
/**
* Clear a vehicle from being a free wagon
* @param v vehicle to change
*/
FORCEINLINE void ClearFreeWagon() { ClrBit(this->subtype, TS_FREE_WAGON); }
@ -232,7 +230,6 @@ struct Train : public SpecializedVehicle<Train, VEH_TRAIN> {
/**
* Check if a train is a wagon
* @param v vehicle to check
* @return Returns true if vehicle is a wagon
*/
FORCEINLINE bool IsWagon() const { return HasBit(this->subtype, TS_WAGON); }
@ -261,77 +258,80 @@ struct Train : public SpecializedVehicle<Train, VEH_TRAIN> {
*/
FORCEINLINE bool HasArticulatedPart() const { return this->Next() != NULL && this->Next()->IsArticulatedPart(); }
/**
* Get the next part of a multi-part engine.
* Will only work on a multi-part engine (this->EngineHasArticPart() == true),
* Result is undefined for normal engine.
* @return next part of articulated engine
*/
FORCEINLINE Train *GetNextArticPart() const
{
assert(this->HasArticulatedPart());
return this->Next();
}
/**
* Get the last part of a multi-part engine.
* @return Last part of the engine.
*/
FORCEINLINE Train *GetLastEnginePart()
{
Train *v = this;
while (v->HasArticulatedPart()) v = v->GetNextArticPart();
return v;
}
/**
* Get the next real (non-articulated part) vehicle in the consist.
* @return Next vehicle in the consist.
*/
FORCEINLINE Train *GetNextVehicle() const
{
const Train *v = this;
while (v->HasArticulatedPart()) v = v->GetNextArticPart();
/* v now contains the last artic part in the engine */
return v->Next();
}
/**
* Get the previous real (non-articulated part) vehicle in the consist.
* @return Previous vehicle in the consist.
*/
FORCEINLINE Train *GetPrevVehicle() const
{
Train *v = this->Previous();
while (v != NULL && v->IsArticulatedPart()) v = v->Previous();
return v;
}
/**
* Get the next real (non-articulated part and non rear part of dualheaded engine) vehicle in the consist.
* @return Next vehicle in the consist.
*/
FORCEINLINE Train *GetNextUnit() const
{
Train *v = this->GetNextVehicle();
if (v != NULL && v->IsRearDualheaded()) v = v->GetNextVehicle();
return v;
}
/**
* Get the previous real (non-articulated part and non rear part of dualheaded engine) vehicle in the consist.
* @return Previous vehicle in the consist.
*/
FORCEINLINE Train *GetPrevUnit()
{
Train *v = this->GetPrevVehicle();
if (v != NULL && v->IsRearDualheaded()) v = v->GetPrevVehicle();
return v;
}
};
#define FOR_ALL_TRAINS(var) FOR_ALL_VEHICLES_OF_TYPE(Train, var)
/**
* Get the next part of a multi-part engine.
* Will only work on a multi-part engine (v->HasArticulatedPart() == true),
* Result is undefined for normal engine.
*/
static inline Train *GetNextArticPart(const Train *v)
{
assert(v->HasArticulatedPart());
return v->Next();
}
/** Get the last part of a multi-part engine.
* @param v Vehicle.
* @return Last part of the engine.
*/
static inline Train *GetLastEnginePart(Train *v)
{
while (v->HasArticulatedPart()) v = GetNextArticPart(v);
return v;
}
/** Get the next real (non-articulated part) vehicle in the consist.
* @param v Vehicle.
* @return Next vehicle in the consist.
*/
static inline Train *GetNextVehicle(const Train *v)
{
while (v->HasArticulatedPart()) v = GetNextArticPart(v);
/* v now contains the last artic part in the engine */
return v->Next();
}
/** Get the previous real (non-articulated part) vehicle in the consist.
* @param w Vehicle.
* @return Previous vehicle in the consist.
*/
static inline Train *GetPrevVehicle(const Train *w)
{
Train *v = w->Previous();
while (v != NULL && v->IsArticulatedPart()) v = v->Previous();
return v;
}
/** Get the next real (non-articulated part and non rear part of dualheaded engine) vehicle in the consist.
* @param v Vehicle.
* @return Next vehicle in the consist.
*/
static inline Train *GetNextUnit(const Train *v)
{
Train *w = GetNextVehicle(v);
if (w != NULL && w->IsRearDualheaded()) w = GetNextVehicle(w);
return w;
}
/** Get the previous real (non-articulated part and non rear part of dualheaded engine) vehicle in the consist.
* @param v Vehicle.
* @return Previous vehicle in the consist.
*/
static inline Train *GetPrevUnit(const Train *v)
{
Train *w = GetPrevVehicle(v);
if (w != NULL && w->IsRearDualheaded()) w = GetPrevVehicle(w);
return w;
}
#endif /* TRAIN_H */

View File

@ -968,7 +968,7 @@ static Train *UnlinkWagon(Train *v, Train *first)
{
/* unlinking the first vehicle of the chain? */
if (v == first) {
v = GetNextVehicle(v);
v = v->GetNextVehicle();
if (v == NULL) return NULL;
if (v->IsWagon()) v->SetFreeWagon();
@ -982,8 +982,8 @@ static Train *UnlinkWagon(Train *v, Train *first)
}
Train *u;
for (u = first; GetNextVehicle(u) != v; u = GetNextVehicle(u)) {}
GetLastEnginePart(u)->SetNext(GetNextVehicle(v));
for (u = first; u->GetNextVehicle() != v; u = u->GetNextVehicle()) {}
u->GetLastEnginePart()->SetNext(v->GetNextVehicle());
return first;
}
@ -1034,7 +1034,7 @@ static void NormaliseTrainConsist(Train *v)
assert(v->IsFrontEngine());
for (; v != NULL; v = GetNextVehicle(v)) {
for (; v != NULL; v = v->GetNextVehicle()) {
if (!v->IsMultiheaded() || !v->IsEngine()) continue;
/* make sure that there are no free cars before next engine */
@ -1094,7 +1094,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
dst_head = dst->First();
if (dst_head->tile != src_head->tile) return CMD_ERROR;
/* Now deal with articulated part of destination wagon */
dst = GetLastEnginePart(dst);
dst = dst->GetLastEnginePart();
} else {
dst_head = NULL;
}
@ -1126,8 +1126,9 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
* row that are being moved. */
if (HasBit(p2, 0)) {
const Train *u;
for (u = src_head; u != src && u != NULL; u = GetNextVehicle(u))
for (u = src_head; u != src && u != NULL; u = u->GetNextVehicle()) {
src_len--;
}
} else {
/* If moving only one vehicle, just count that. */
src_len = 1;
@ -1141,8 +1142,9 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
}
} else {
/* Abort if we're creating a new train on an existing row. */
if (src_len > max_len && src == src_head && GetNextVehicle(src_head)->IsEngine())
if (src_len > max_len && src == src_head && src_head->GetNextVehicle()->IsEngine()) {
return_cmd_error(STR_ERROR_TRAIN_TOO_LONG);
}
}
}
@ -1157,7 +1159,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
/* When we move the front vehicle, the second vehicle might need a unitnumber */
if (!HasBit(p2, 0) && (src->IsFreeWagon() || (src->IsFrontEngine() && dst == NULL)) && (flags & DC_AUTOREPLACE) == 0) {
Train *second = GetNextUnit(src);
Train *second = src->GetNextUnit();
if (second != NULL && second->IsEngine() && GetFreeUnitNumber(VEH_TRAIN) > _settings_game.vehicle.max_trains) {
return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME);
}
@ -1268,7 +1270,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
/* If we move the front Engine and if the second vehicle is not an engine
add the whole vehicle to the DEFAULT_GROUP */
if (src->IsFrontEngine() && !IsDefaultGroupID(src->group_id)) {
Train *v = GetNextVehicle(src);
Train *v = src->GetNextVehicle();
if (v != NULL && v->IsEngine()) {
v->group_id = src->group_id;
@ -1280,8 +1282,8 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
/* unlink ALL wagons */
if (src != src_head) {
Train *v = src_head;
while (GetNextVehicle(v) != src) v = GetNextVehicle(v);
GetLastEnginePart(v)->SetNext(NULL);
while (v->GetNextVehicle() != src) v = v->GetNextVehicle();
v->GetLastEnginePart()->SetNext(NULL);
} else {
InvalidateWindowData(WC_VEHICLE_DEPOT, src_head->tile); // We removed a line
src_head = NULL;
@ -1291,7 +1293,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
if (src_head == dst_head) dst_head = NULL;
/* unlink single wagon from linked list */
src_head = UnlinkWagon(src, src_head);
GetLastEnginePart(src)->SetNext(NULL);
src->GetLastEnginePart()->SetNext(NULL);
}
if (dst == NULL) {
@ -1340,8 +1342,8 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u
{
Train *v;
for (v = src; GetNextVehicle(v) != NULL; v = GetNextVehicle(v)) {}
GetLastEnginePart(v)->SetNext(dst->Next());
for (v = src; v->GetNextVehicle() != NULL; v = v->GetNextVehicle()) {}
v->GetLastEnginePart()->SetNext(dst->Next());
}
dst->SetNext(src);
}
@ -1460,7 +1462,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
/* 2. We are selling the front vehicle, some special action might be required
* here, so take attention */
if (v == first) {
Train *new_f = GetNextVehicle(first);
Train *new_f = first->GetNextVehicle();
/* 2.2 If there are wagons present after the deleted front engine, check
* if the second wagon (which will be first) is an engine. If it is one,
@ -1521,7 +1523,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
* If we encounter a matching rear-engine to a front-engine
* earlier in the chain (before deletion), leave it alone */
for (Train *tmp; v != NULL; v = tmp) {
tmp = GetNextVehicle(v);
tmp = v->GetNextVehicle();
if (v->IsMultiheaded()) {
if (v->IsEngine()) {
@ -1537,7 +1539,7 @@ CommandCost CmdSellRailWagon(TileIndex tile, DoCommandFlag flags, uint32 p1, uin
* deleted here. However, because tmp has already
* been set it needs to be updated now so that the
* loop never sees the rear part. */
if (tmp == rear) tmp = GetNextVehicle(tmp);
if (tmp == rear) tmp = tmp->GetNextVehicle();
if (flags & DC_EXEC) {
first = UnlinkWagon(rear, first);
@ -4439,7 +4441,7 @@ Money Train::GetRunningCost() const
if (v->IsMultiheaded()) cost_factor /= 2;
cost += cost_factor * GetPriceByIndex(rvi->running_cost_class);
} while ((v = GetNextVehicle(v)) != NULL);
} while ((v = v->GetNextVehicle()) != NULL);
return cost;
}

View File

@ -404,7 +404,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
}
w_rear = w; // trains needs to know the last car in the train, so they can add more in next loop
}
} while (v->type == VEH_TRAIN && (v = GetNextVehicle(Train::From(v))) != NULL);
} while (v->type == VEH_TRAIN && (v = Train::From(v)->GetNextVehicle()) != NULL);
if ((flags & DC_EXEC) && v_front->type == VEH_TRAIN) {
/* for trains this needs to be the front engine due to the callback function */
@ -438,7 +438,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
}
if (w->type == VEH_TRAIN && Train::From(w)->HasArticulatedPart()) {
w = GetNextArticPart(Train::From(w));
w = Train::From(w)->GetNextArticPart();
} else if (w->type == VEH_ROAD && RoadVehicle::From(w)->HasArticulatedPart()) {
w = w->Next();
} else {
@ -454,7 +454,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
}
if (v->type == VEH_TRAIN && Train::From(v)->HasArticulatedPart()) {
v = GetNextArticPart(Train::From(v));
v = Train::From(v)->GetNextArticPart();
} else if (v->type == VEH_ROAD && RoadVehicle::From(v)->HasArticulatedPart()) {
v = v->Next();
} else {
@ -462,8 +462,8 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint
}
} while (v != NULL);
if ((flags & DC_EXEC) && v->type == VEH_TRAIN) w = GetNextVehicle(Train::From(w));
} while (v->type == VEH_TRAIN && (v = GetNextVehicle(Train::From(v))) != NULL);
if ((flags & DC_EXEC) && v->type == VEH_TRAIN) w = Train::From(w)->GetNextVehicle();
} while (v->type == VEH_TRAIN && (v = Train::From(v)->GetNextVehicle()) != NULL);
if (flags & DC_EXEC) {
/*