1
0
mirror of https://github.com/OpenTTD/OpenTTD.git synced 2025-08-28 08:59:09 +00:00

Codechange: Use vehicle tile hash to search for free wagons. (#14343)

Avoids iterating the vehicle pool.
This commit is contained in:
2025-06-08 19:07:43 +01:00
committed by GitHub
parent 4b18622c4e
commit 7c9c2aec49

View File

@@ -604,6 +604,28 @@ void GetTrainSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs,
} }
} }
/**
* Get a list of free wagons in a depot.
* @param tile Tile of depot.
* @return List of free wagons, sorted by vehicle index.
*/
static std::vector<VehicleID> GetFreeWagonsInDepot(TileIndex tile)
{
std::vector<VehicleID> free_wagons;
for (Vehicle *v : VehiclesOnTile(tile)) {
if (v->type != VEH_TRAIN) continue;
if (v->vehstatus.Test(VehState::Crashed)) continue;
if (!Train::From(v)->IsFreeWagon()) continue;
free_wagons.push_back(v->index);
}
/* Sort by vehicle index for consistency across clients. */
std::ranges::sort(free_wagons);
return free_wagons;
}
/** /**
* Build a railroad wagon. * Build a railroad wagon.
* @param flags type of operation. * @param flags type of operation.
@@ -673,18 +695,18 @@ static CommandCost CmdBuildRailWagon(DoCommandFlags flags, TileIndex tile, const
CheckConsistencyOfArticulatedVehicle(v); CheckConsistencyOfArticulatedVehicle(v);
/* Try to connect the vehicle to one of free chains of wagons. */ /* Try to connect the vehicle to one of free chains of wagons. */
for (Train *w : Train::Iterate()) { for (VehicleID vehicle : GetFreeWagonsInDepot(tile)) {
if (w->tile == tile && ///< Same depot if (vehicle == v->index) continue;
w->IsFreeWagon() && ///< A free wagon chain
w->engine_type == e->index && ///< Same type const Train *w = Train::Get(vehicle);
w->First() != v && ///< Don't connect to ourself if (w->engine_type != v->engine_type) continue; ///< Must be same type
!w->vehstatus.Test(VehState::Crashed)) { ///< Not crashed/flooded if (w->First() == v) continue; ///< Don't connect to ourself
if (Command<CMD_MOVE_RAIL_VEHICLE>::Do(DoCommandFlag::Execute, v->index, w->Last()->index, true).Succeeded()) { if (Command<CMD_MOVE_RAIL_VEHICLE>::Do(DoCommandFlag::Execute, v->index, w->Last()->index, true).Succeeded()) {
break; break;
} }
} }
} }
}
return CommandCost(); return CommandCost();
} }
@@ -693,14 +715,11 @@ static CommandCost CmdBuildRailWagon(DoCommandFlags flags, TileIndex tile, const
void NormalizeTrainVehInDepot(const Train *u) void NormalizeTrainVehInDepot(const Train *u)
{ {
assert(u->IsEngine()); assert(u->IsEngine());
for (const Train *v : Train::Iterate()) { for (VehicleID vehicle : GetFreeWagonsInDepot(u->tile)) {
if (v->IsFreeWagon() && v->tile == u->tile && if (Command<CMD_MOVE_RAIL_VEHICLE>::Do(DoCommandFlag::Execute, vehicle, u->index, true).Failed()) {
v->track == TRACK_BIT_DEPOT) {
if (Command<CMD_MOVE_RAIL_VEHICLE>::Do(DoCommandFlag::Execute, v->index, u->index, true).Failed()) {
break; break;
} }
} }
}
} }
static void AddRearEngineToMultiheadedTrain(Train *v) static void AddRearEngineToMultiheadedTrain(Train *v)
@@ -828,10 +847,10 @@ CommandCost CmdBuildRailVehicle(DoCommandFlags flags, TileIndex tile, const Engi
static Train *FindGoodVehiclePos(const Train *src) static Train *FindGoodVehiclePos(const Train *src)
{ {
EngineID eng = src->engine_type; EngineID eng = src->engine_type;
TileIndex tile = src->tile;
for (Train *dst : Train::Iterate()) { for (VehicleID vehicle : GetFreeWagonsInDepot(src->tile)) {
if (dst->IsFreeWagon() && dst->tile == tile && !dst->vehstatus.Test(VehState::Crashed)) { Train *dst = Train::Get(vehicle);
/* check so all vehicles in the line have the same engine. */ /* check so all vehicles in the line have the same engine. */
Train *t = dst; Train *t = dst;
while (t->engine_type == eng) { while (t->engine_type == eng) {
@@ -839,7 +858,6 @@ static Train *FindGoodVehiclePos(const Train *src)
if (t == nullptr) return dst; if (t == nullptr) return dst;
} }
} }
}
return nullptr; return nullptr;
} }