diff --git a/src/engine.cpp b/src/engine.cpp index 8534558332..c4184ee36e 100644 --- a/src/engine.cpp +++ b/src/engine.cpp @@ -961,8 +961,8 @@ static CompanyID GetPreviewCompany(Engine *e) c->old_economy[0].performance_history > best_hist) { /* Check whether the company uses similar vehicles */ - for (const Vehicle *v : Vehicle::Iterate()) { - if (v->owner != c->index || v->type != e->type || HasBit(v->subtype, GVSF_VIRTUAL)) continue; + for (const Vehicle *v : Vehicle::IterateType(e->type)) { + if (v->owner != c->index || HasBit(v->subtype, GVSF_VIRTUAL)) continue; if (!v->GetEngine()->CanCarryCargo() || !HasBit(cargomask, v->cargo_type)) continue; best_hist = c->old_economy[0].performance_history; diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index 3ebbf5daa8..f19732e81d 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.cpp @@ -823,8 +823,8 @@ CommandCost CmdAddSharedVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 if (flags & DC_EXEC) { /* Find the first front engine which belong to the group id_g * then add all shared vehicles of this front engine to the group id_g */ - for (const Vehicle *v : Vehicle::Iterate()) { - if (v->type == type && v->IsPrimaryVehicle()) { + for (const Vehicle *v : Vehicle::IterateType(type)) { + if (v->IsPrimaryVehicle()) { if (v->group_id != id_g) continue; /* For each shared vehicles add it to the group */ diff --git a/src/infrastructure.cpp b/src/infrastructure.cpp index 22983cb014..f8a5341dd5 100644 --- a/src/infrastructure.cpp +++ b/src/infrastructure.cpp @@ -254,8 +254,8 @@ bool CheckSharingChangePossible(VehicleType type, bool new_value) }); StringID error_message = STR_NULL; - for (Vehicle *v : Vehicle::Iterate()) { - if (type != v->type || HasBit(v->subtype, GVSF_VIRTUAL)) continue; + for (Vehicle *v : Vehicle::IterateType(type)) { + if (HasBit(v->subtype, GVSF_VIRTUAL)) continue; if (v->Previous() != nullptr) continue; /* Check vehicle positiion */ diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index 1870d5a971..ea7a967408 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.cpp @@ -3786,8 +3786,8 @@ CommandCost CmdMassChangeOrder(TileIndex tile, DoCommandFlag flags, uint32_t p1, DestinationID to_dest = GB(p2, 0, 16); if (flags & DC_EXEC) { - for (Vehicle *v : Vehicle::Iterate()) { - if (v->type == vehtype && v->IsPrimaryVehicle() && CheckOwnership(v->owner).Succeeded() && VehicleCargoFilter(v, cargo_filter)) { + for (Vehicle *v : Vehicle::IterateType(vehtype)) { + if (v->IsPrimaryVehicle() && CheckOwnership(v->owner).Succeeded() && VehicleCargoFilter(v, cargo_filter)) { int index = 0; bool changed = false; diff --git a/src/settings.cpp b/src/settings.cpp index e8af1f544e..b061a21032 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1224,8 +1224,8 @@ static bool CanUpdateServiceInterval(VehicleType type, int32_t &new_value) static void UpdateServiceInterval(VehicleType type, int32_t new_value) { if (_game_mode != GM_MENU && Company::IsValidID(_current_company)) { - for (Vehicle *v : Vehicle::Iterate()) { - if (v->owner == _current_company && v->type == type && v->IsPrimaryVehicle() && !v->ServiceIntervalIsCustom()) { + for (Vehicle *v : Vehicle::IterateType(type)) { + if (v->owner == _current_company && v->IsPrimaryVehicle() && !v->ServiceIntervalIsCustom()) { v->SetServiceInterval(new_value); } } diff --git a/src/sl/vehicle_sl.cpp b/src/sl/vehicle_sl.cpp index a1a53a9c9a..c98662b21d 100644 --- a/src/sl/vehicle_sl.cpp +++ b/src/sl/vehicle_sl.cpp @@ -595,12 +595,12 @@ void FixupTrainLengths() { /* Vehicle center was moved from 4 units behind the front to half the length * behind the front. Move vehicles so they end up on the same spot. */ - for (Vehicle *v : Vehicle::Iterate()) { - if (v->type == VEH_TRAIN && v->IsPrimaryVehicle()) { + for (Train *v : Train::Iterate()) { + if (v->IsPrimaryVehicle()) { /* The vehicle center is now more to the front depending on vehicle length, * so we need to move all vehicles forward to cover the difference to the * old center, otherwise wagon spacing in trains would be broken upon load. */ - for (Train *u = Train::From(v); u != nullptr; u = u->Next()) { + for (Train *u = v; u != nullptr; u = u->Next()) { if (u->track == TRACK_BIT_DEPOT || (u->vehstatus & VS_CRASHED)) continue; Train *next = u->Next(); @@ -670,7 +670,7 @@ void FixupTrainLengths() } /* Update all cached properties after moving the vehicle chain around. */ - Train::From(v)->ConsistChanged(CCF_TRACK); + v->ConsistChanged(CCF_TRACK); } } } diff --git a/src/sl/waypoint_sl.cpp b/src/sl/waypoint_sl.cpp index 18337edb80..2a2192cce9 100644 --- a/src/sl/waypoint_sl.cpp +++ b/src/sl/waypoint_sl.cpp @@ -149,9 +149,7 @@ void MoveWaypointsToBaseStations() for (Order *o = ol->GetFirstOrder(); o != nullptr; o = o->next) UpdateWaypointOrder(o); } - for (Vehicle *v : Vehicle::Iterate()) { - if (v->type != VEH_TRAIN) continue; - + for (Vehicle *v : Vehicle::IterateType(VEH_TRAIN)) { UpdateWaypointOrder(&v->current_order); } diff --git a/src/vehicle.cpp b/src/vehicle.cpp index 2dc716b5c4..a3bb54974f 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.cpp @@ -3032,9 +3032,9 @@ bool CanBuildVehicleInfrastructure(VehicleType type, byte subtype) } /* We should be able to build infrastructure when we have the actual vehicle type */ - for (const Vehicle *v : Vehicle::Iterate()) { - if (v->type == VEH_ROAD && GetRoadTramType(RoadVehicle::From(v)->roadtype) != (RoadTramType)subtype) continue; - if (v->owner == _local_company && v->type == type) return true; + for (const Vehicle *v : Vehicle::IterateType(type)) { + if (type == VEH_ROAD && GetRoadTramType(RoadVehicle::From(v)->roadtype) != (RoadTramType)subtype) continue; + if (v->owner == _local_company) return true; } return false; diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 87317f642e..fe0974b08d 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -1289,6 +1289,30 @@ public: uint32_t GetDisplayMaxWeight() const; uint32_t GetDisplayMinPowerToWeight() const; + + struct VehicleTypeFilter { + VehicleType vt; + + bool operator() (size_t index) + { +#if OTTD_UPPER_TAGGED_PTR + return VehiclePoolOps::GetVehicleType(_vehicle_pool.GetRaw(index)) == this->vt; +#else + return Vehicle::Get(index)->type == this->vt; +#endif + } + }; + + /** + * Returns an iterable ensemble of all valid vehicles of the given type + * @param vt the VehicleType to filter + * @param from index of the first vehicle to consider + * @return an iterable ensemble of all valid vehicles of the given type + */ + static Pool::IterateWrapperFiltered IterateType(VehicleType vt, size_t from = 0) + { + return Pool::IterateWrapperFiltered(from, VehicleTypeFilter{ vt }); + } }; inline bool IsPointInViewportVehicleRedrawArea(const std::vector &viewport_redraw_rects, const Point &pt) diff --git a/src/vehiclelist.cpp b/src/vehiclelist.cpp index c6d496f925..2f88bcf37b 100644 --- a/src/vehiclelist.cpp +++ b/src/vehiclelist.cpp @@ -73,9 +73,8 @@ void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine engines->clear(); if (wagons != nullptr && wagons != engines) wagons->clear(); - for (const Vehicle *v : Vehicle::Iterate()) { + for (const Vehicle *v : Vehicle::IterateType(type)) { /* General tests for all vehicle types */ - if (v->type != type) continue; if (v->tile != tile) continue; if (HasBit(v->subtype, GVSF_VIRTUAL)) continue; @@ -156,8 +155,8 @@ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli }; auto fill_all_vehicles = [&]() { - for (const Vehicle *v : Vehicle::Iterate()) { - if (!HasBit(v->subtype, GVSF_VIRTUAL) && v->type == vli.vtype && v->owner == vli.company && v->IsPrimaryVehicle()) { + for (const Vehicle *v : Vehicle::IterateType(vli.vtype)) { + if (!HasBit(v->subtype, GVSF_VIRTUAL) && v->owner == vli.company && v->IsPrimaryVehicle()) { add_veh(v); } } @@ -185,8 +184,8 @@ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli case VL_GROUP_LIST: if (vli.index != ALL_GROUP) { - for (const Vehicle *v : Vehicle::Iterate()) { - if (!HasBit(v->subtype, GVSF_VIRTUAL) && v->type == vli.vtype && v->IsPrimaryVehicle() && + for (const Vehicle *v : Vehicle::IterateType(vli.vtype)) { + if (!HasBit(v->subtype, GVSF_VIRTUAL) && v->IsPrimaryVehicle() && v->owner == vli.company && GroupIsInGroup(v->group_id, vli.index)) { add_veh(v); }