@@ -6,12 +6,13 @@
*/
/** @file vehiclelist.cpp Lists of vehicles. */
#include "stdafx.h"
#include "train.h"
#include "vehicle_func.h"
#include "vehiclelist.h"
#include "vehiclelist_func.h"
#include "group.h"
#include "safeguards.h"
@@ -56,12 +57,45 @@ bool VehicleListIdentifier::UnpackIfVali
VehicleListIdentifier result;
[[maybe_unused]] bool ret = result.UnpackIfValid(data);
assert(ret);
return result;
}
/** Data for building a depot vehicle list. */
struct BuildDepotVehicleListData
{
VehicleList *engines; ///< Pointer to list to add vehicles to.
VehicleList *wagons; ///< Pointer to list to add wagons to (can be nullptr).
VehicleType type; ///< Type of vehicle.
bool individual_wagons; ///< If true add every wagon to \a wagons which is not attached to an engine. If false only add the first wagon of every row.
};
/**
* Add vehicles to a depot vehicle list.
* @param v The found vehicle.
* @param data The depot vehicle list data.
* @return Always nullptr.
static Vehicle *BuildDepotVehicleListProc(Vehicle *v, void *data)
auto bdvld = static_cast<BuildDepotVehicleListData *>(data);
if (v->type != bdvld->type || !v->IsInDepot()) return nullptr;
if (bdvld->type == VEH_TRAIN) {
const Train *t = Train::From(v);
if (t->IsArticulatedPart() || t->IsRearDualheaded()) return nullptr;
if (bdvld->wagons != nullptr && t->First()->IsFreeWagon()) {
if (bdvld->individual_wagons || t->IsFreeWagon()) bdvld->wagons->push_back(t);
return nullptr;
if (v->IsPrimaryVehicle()) bdvld->engines->push_back(v);
* Generate a list of vehicles inside a depot.
* @param type Type of vehicle
* @param tile The tile the depot is located on
* @param engines Pointer to list to add vehicles to
* @param wagons Pointer to list to add wagons to (can be nullptr)
@@ -69,38 +103,14 @@ bool VehicleListIdentifier::UnpackIfVali
void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engines, VehicleList *wagons, bool individual_wagons)
engines->clear();
if (wagons != nullptr && wagons != engines) wagons->clear();
for (const Vehicle *v : Vehicle::Iterate()) {
/* General tests for all vehicle types */
if (v->type != type) continue;
if (v->tile != tile) continue;
switch (type) {
case VEH_TRAIN: {
if (t->IsArticulatedPart() || t->IsRearDualheaded()) continue;
if (!t->IsInDepot()) continue;
if (wagons != nullptr && t->First()->IsFreeWagon()) {
if (individual_wagons || t->IsFreeWagon()) wagons->push_back(t);
continue;
if (!t->IsPrimaryVehicle()) continue;
break;
default:
if (!v->IsPrimaryVehicle()) continue;
if (!v->IsInDepot()) continue;
engines->push_back(v);
BuildDepotVehicleListData bdvld{engines, wagons, type, individual_wagons};
FindVehicleOnPos(tile, &bdvld, BuildDepotVehicleListProc);
/* Ensure the lists are not wasting too much space. If the lists are fresh
* (i.e. built within a command) then this will actually do nothing. */
engines->shrink_to_fit();
if (wagons != nullptr && wagons != engines) wagons->shrink_to_fit();
Status change: