# HG changeset patch # User smatz # Date 2009-07-02 12:10:39 # Node ID 564aa4953d26a0b08547a71707e935c10b4dcbec # Parent bb9023f5462885bdf52942ffe8351f270887e2fd (svn r16723) -Codechange: make GetNextArticPart(), GetLastEnginePart(), GetNextVehicle(), GetPrevVehicle(), GetNextUnit(), GetPrevUnit() members of Train diff --git a/src/ai/api/ai_vehicle.cpp b/src/ai/api/ai_vehicle.cpp --- a/src/ai/api/ai_vehicle.cpp +++ b/src/ai/api/ai_vehicle.cpp @@ -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; } diff --git a/src/articulated_vehicles.cpp b/src/articulated_vehicles.cpp --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.cpp @@ -207,7 +207,7 @@ bool IsArticulatedVehicleCarryingDiffere 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 CheckConsistencyOfArticulatedVehicl 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: diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -94,7 +94,7 @@ static void TransferCargo(Vehicle *old_v 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_v 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 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(num_units); ///< Will store vehicles of the old chain in their order Train **new_vehs = CallocT(num_units); ///< New vehicles corresponding to old_vehs or NULL if no replacement @@ -416,7 +416,7 @@ static CommandCost ReplaceChain(Vehicle * 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 /* 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 } 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 * 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(TileIn 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) { diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.cpp @@ -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()) { diff --git a/src/train.h b/src/train.h --- a/src/train.h +++ b/src/train.h @@ -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 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 /** * Set engine status - * @param v vehicle to change */ FORCEINLINE void SetEngine() { SetBit(this->subtype, TS_ENGINE); } @@ -197,7 +196,6 @@ struct Train : public SpecializedVehicle /** * 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 /** * 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 */ 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 */ diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp --- a/src/train_cmd.cpp +++ b/src/train_cmd.cpp @@ -968,7 +968,7 @@ static Train *UnlinkWagon(Train *v, Trai { /* 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, Trai } 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 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 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 * 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 } } 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 /* 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 /* 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 /* 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 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 { 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 t /* 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 t * 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 t * 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; } diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.cpp @@ -404,7 +404,7 @@ CommandCost CmdCloneVehicle(TileIndex ti } 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 ti } 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 ti } 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 ti } } 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) { /*