1
0
Fork 0

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

Avoids iterating the vehicle pool.
pull/13972/merge
Peter Nelson 2025-06-08 19:07:43 +01:00 committed by GitHub
parent 4b18622c4e
commit 7c9c2aec49
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 42 additions and 24 deletions

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,15 +695,15 @@ 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()) {
break; if (Command<CMD_MOVE_RAIL_VEHICLE>::Do(DoCommandFlag::Execute, v->index, w->Last()->index, true).Succeeded()) {
} break;
} }
} }
} }
@ -693,12 +715,9 @@ 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) { break;
if (Command<CMD_MOVE_RAIL_VEHICLE>::Do(DoCommandFlag::Execute, v->index, u->index, true).Failed()) {
break;
}
} }
} }
} }
@ -828,16 +847,15 @@ 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. */
Train *t = dst; /* check so all vehicles in the line have the same engine. */
while (t->engine_type == eng) { Train *t = dst;
t = t->Next(); while (t->engine_type == eng) {
if (t == nullptr) return dst; t = t->Next();
} if (t == nullptr) return dst;
} }
} }