Avoid tile hash scans for unsuitable vehicle types in EnsureNoVehicleOnGround

This commit is contained in:
Jonathan G Rennison
2023-03-22 18:25:08 +00:00
parent a9156ed516
commit 035a3331a2
2 changed files with 24 additions and 46 deletions

View File

@@ -550,29 +550,22 @@ Vehicle *VehicleFromPos(TileIndex tile, VehicleType type, void *data, VehicleFro
/** /**
* Callback that returns 'real' vehicles lower or at height \c *(int*)data . * Callback that returns 'real' vehicles lower or at height \c *(int*)data .
* @param v Vehicle to examine. * @param v Vehicle to examine.
* @param data Pointer to height data. * @param data unused.
* @return \a v if conditions are met, else \c nullptr. * @return \a v if conditions are met, else \c nullptr.
*/ */
static Vehicle *EnsureNoVehicleProcZ(Vehicle *v, void *data) static Vehicle *EnsureNoVehicleProc(Vehicle *v, void *data)
{ {
int z = static_cast<int>(reinterpret_cast<intptr_t>(data));
if (v->z_pos > z) return nullptr;
return v; return v;
} }
/** /**
* Callback that returns 'real' train-collidable road vehicles lower or at height \c *(int*)data . * Callback that returns 'real' train-collidable road vehicles lower or at height \c *(int*)data .
* @param v Vehicle to examine. * @param v Vehicle to examine.
* @param data Pointer to height data. * @param data unused
* @return \a v if conditions are met, else \c nullptr. * @return \a v if conditions are met, else \c nullptr.
*/ */
static Vehicle *EnsureNoTrainCollidableRoadVehicleProcZ(Vehicle *v, void *data) static Vehicle *EnsureNoTrainCollidableRoadVehicleProc(Vehicle *v, void *data)
{ {
int z = static_cast<int>(reinterpret_cast<intptr_t>(data));
if (v->z_pos > z) return nullptr;
if (HasBit(_roadtypes_non_train_colliding, RoadVehicle::From(v)->roadtype)) return nullptr; if (HasBit(_roadtypes_non_train_colliding, RoadVehicle::From(v)->roadtype)) return nullptr;
return v; return v;
@@ -601,50 +594,36 @@ static Vehicle *EnsureNoAircraftProcZ(Vehicle *v, void *data)
*/ */
CommandCost EnsureNoVehicleOnGround(TileIndex tile) CommandCost EnsureNoVehicleOnGround(TileIndex tile)
{ {
int z = GetTileMaxPixelZ(tile); if (IsAirportTile(tile)) {
int z = GetTileMaxPixelZ(tile);
if (VehicleFromPos(tile, VEH_AIRCRAFT, reinterpret_cast<void *>(static_cast<intptr_t>(z)), &EnsureNoAircraftProcZ, true) != nullptr) {
return CommandCost(STR_ERROR_AIRCRAFT_IN_THE_WAY);
}
return CommandCost();
}
/* Value v is not safe in MP games, however, it is used to generate a local if (IsTileType(tile, MP_RAILWAY) || IsLevelCrossingTile(tile) || HasStationTileRail(tile) || IsRailTunnelBridgeTile(tile)) {
* error message only (which may be different for different machines). if (VehicleFromPos(tile, VEH_TRAIN, nullptr, &EnsureNoVehicleProc, true) != nullptr) {
* Such a message does not affect MP synchronisation. return CommandCost(STR_ERROR_TRAIN_IN_THE_WAY);
*/ }
if (VehicleFromPos(tile, VEH_TRAIN, reinterpret_cast<void *>(static_cast<intptr_t>(z)), &EnsureNoVehicleProcZ, true) != nullptr) {
return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY);
} }
if (VehicleFromPos(tile, VEH_ROAD, reinterpret_cast<void *>(static_cast<intptr_t>(z)), &EnsureNoVehicleProcZ, true) != nullptr) { if (IsTileType(tile, MP_ROAD) || IsAnyRoadStopTile(tile) || (IsTileType(tile, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD)) {
return_cmd_error(STR_ERROR_ROAD_VEHICLE_IN_THE_WAY); if (VehicleFromPos(tile, VEH_ROAD, nullptr, &EnsureNoVehicleProc, true) != nullptr) {
return CommandCost(STR_ERROR_ROAD_VEHICLE_IN_THE_WAY);
}
} }
if (VehicleFromPos(tile, VEH_SHIP, reinterpret_cast<void *>(static_cast<intptr_t>(z)), &EnsureNoVehicleProcZ, true) != nullptr) { if (HasTileWaterClass(tile) || (IsBridgeTile(tile) && GetTunnelBridgeTransportType(tile) == TRANSPORT_WATER)) {
return_cmd_error(STR_ERROR_SHIP_IN_THE_WAY); if (VehicleFromPos(tile, VEH_SHIP, nullptr, &EnsureNoVehicleProc, true) != nullptr) {
return CommandCost(STR_ERROR_SHIP_IN_THE_WAY);
}
} }
if (VehicleFromPos(tile, VEH_AIRCRAFT, reinterpret_cast<void *>(static_cast<intptr_t>(z)), &EnsureNoAircraftProcZ, true) != nullptr) {
return_cmd_error(STR_ERROR_AIRCRAFT_IN_THE_WAY);
}
return CommandCost();
}
/**
* Ensure there is no road vehicle at the ground at the given position.
* @param tile Position to examine.
* @return Succeeded command (ground is free) or failed command (a vehicle is found).
*/
CommandCost EnsureNoRoadVehicleOnGround(TileIndex tile)
{
int z = GetTileMaxPixelZ(tile);
/* Value v is not safe in MP games, however, it is used to generate a local
* error message only (which may be different for different machines).
* Such a message does not affect MP synchronisation.
*/
Vehicle *v = VehicleFromPos(tile, VEH_ROAD, reinterpret_cast<void *>(static_cast<intptr_t>(z)), &EnsureNoVehicleProcZ, true);
if (v != nullptr) return_cmd_error(STR_ERROR_ROAD_VEHICLE_IN_THE_WAY);
return CommandCost(); return CommandCost();
} }
bool IsTrainCollidableRoadVehicleOnGround(TileIndex tile) bool IsTrainCollidableRoadVehicleOnGround(TileIndex tile)
{ {
int z = GetTileMaxPixelZ(tile); return VehicleFromPos(tile, VEH_ROAD, nullptr, &EnsureNoTrainCollidableRoadVehicleProc, true) != nullptr;
return VehicleFromPos(tile, VEH_ROAD, reinterpret_cast<void *>(static_cast<intptr_t>(z)), &EnsureNoTrainCollidableRoadVehicleProcZ, true) != nullptr;
} }
struct GetVehicleTunnelBridgeProcData { struct GetVehicleTunnelBridgeProcData {

View File

@@ -240,7 +240,6 @@ static inline uint32 GetCmdSendToDepot(const BaseVehicle *v)
} }
CommandCost EnsureNoVehicleOnGround(TileIndex tile); CommandCost EnsureNoVehicleOnGround(TileIndex tile);
CommandCost EnsureNoRoadVehicleOnGround(TileIndex tile);
bool IsTrainCollidableRoadVehicleOnGround(TileIndex tile); bool IsTrainCollidableRoadVehicleOnGround(TileIndex tile);
CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits); CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits);