diff --git a/src/vehicle_base.h b/src/vehicle_base.h index 38ade16539..ab99580b85 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.h @@ -1344,6 +1344,21 @@ public: } }; + struct VehicleFrontOnlyTypeMaskFilter { + VehicleTypeMask vt_mask; + + bool operator() (size_t index) + { +#if OTTD_UPPER_TAGGED_PTR + uintptr_t vptr = _vehicle_pool.GetRaw(index); + return !VehiclePoolOps::IsNonFrontVehiclePtr(vptr) && HasBit(this->vt_mask, VehiclePoolOps::GetVehicleType(vptr)); +#else + const Vehicle *v = Vehicle::Get(index); + return HasBit(this->vt_mask, v->type) && v->Previous() == nullptr; +#endif + } + }; + /** * Returns an iterable ensemble of all valid vehicles of the given type * @param vt the VehicleType to filter @@ -1375,6 +1390,17 @@ public: { return Pool::IterateWrapperFiltered(from, VehicleFrontOnlyTypeFilter{ vt }); } + + /** + * Returns an iterable ensemble of all valid front vehicles of the given type + * @param VehicleTypeMask the set of VehicleType to filter, as a VehicleTypeMask + * @param from index of the first vehicle to consider + * @return an iterable ensemble of all valid front vehicles of the given type + */ + static Pool::IterateWrapperFiltered IterateTypeMaskFrontOnly(VehicleTypeMask vt_mask, size_t from = 0) + { + return Pool::IterateWrapperFiltered(from, VehicleFrontOnlyTypeMaskFilter{ vt_mask }); + } }; inline bool IsPointInViewportVehicleRedrawArea(const std::vector &viewport_redraw_rects, const Point &pt) diff --git a/src/vehicle_type.h b/src/vehicle_type.h index 399f247144..e30c3e141f 100644 --- a/src/vehicle_type.h +++ b/src/vehicle_type.h @@ -39,6 +39,9 @@ DECLARE_POSTFIX_INCREMENT(VehicleType) template <> struct EnumPropsT : MakeEnumPropsT {}; DECLARE_ENUM_AS_ADDABLE(VehicleType) +using VehicleTypeMask = uint8_t; +static_assert(VEH_END <= 8); + struct Vehicle; struct Train; struct RoadVehicle;