Skip to content

Add getElements with filtering support - #5188

Open
FileEX wants to merge 3 commits into
multitheftauto:masterfrom
FileEX:feature/getElements
Open

Add getElements with filtering support#5188
FileEX wants to merge 3 commits into
multitheftauto:masterfrom
FileEX:feature/getElements

Conversation

@FileEX

@FileEX FileEX commented Aug 16, 2026

Copy link
Copy Markdown
Member

Summary

This PR adds a new getElements function that allows retrieving multiple element types at once and filtering them based on various properties.

Syntax

table/nil getElements(table typesWithFilters, [element startAt = root])

The function returns nil if the types table is empty. Otherwise, it returns a table organized by element types as keys—for example:

local result = getElements({
    ped = {hasJetpack = true},
    vehicle = {model = 411},
})

local peds = result.ped
local vehicles = result.vehicle

If the filter table for a specific element type is empty, all elements of that type are returned, behaving exactly as if you had used getElementsByType.

Filter table syntax

The first argument is a table containing the element types to search for and their respective filters.

Each element type can have its own filter table:

{
    player = {
        streamedIn = true,
        onScreen = true,
        dimension = 0
    },

    vehicle = {
        model = {411, 415},
        isUnoccupied = true
    }
}

The key represents the element type, while its value is a table containing the filters for that type.

Filters

An important aspect of the filtering system is that the presence of a key determines whether the filter is checked. For example:

onScreen = false

does not mean that the onScreen filter is disabled. Instead, it means that only elements that are not currently on screen will be returned. The same applies to all other boolean filters, such as streamedIn, isLowLOD, isUnoccupied, etc. If a filter should not be checked, simply omit its key from the filter table.

Common filters

The following filters are available for multiple element types:

  • bool streamedIn: Whether the element is streamed in
  • bool onScreen: Whether the element is currently on screen
  • table inRange = { position = {x, y, z}, range = float }: Whether the element is within the specified range of the given position
  • int interior: Filters elements by interior
  • int dimension: Filters elements by dimension
  • int/table model: Filters elements by model. A single model ID or a table of model IDs can be provided, e.g. {0, 7, 2}
  • bool onGround: Whether the element is on the ground
  • bool inWater: Whether the element is in water
  • table alpha = { value = int, compareMethod = string }: Filters elements by alpha using the specified comparison method
  • bool isFrozen: Whether the element is frozen
  • bool isOnFire: Whether the element is on fire
  • bool isCollidable: Whether the element has collisions enabled (setElementCollisionsEnabled)
  • table health = { value = int, compareMethod = string }: Filters elements by health using the specified comparison method

The following comparison operators are supported for alpha and health:

== , ~=, <=, >= , < , >

For example:

player = {
    health = {
        value = 50,
        compareMethod = "<="
    }
}

will only return players with 50 HP or less.

Type-specific filters

Player

  • bool isInTeam: Whether the player belongs to a team

Ped / Player

  • bool isInVehicle: Whether the ped is inside a vehicle
  • bool hasJetpack: Whether the ped has a jetpack

Vehicle

  • bool isUnoccupied: Whether the vehicle is unoccupied
  • bool isDamageProof: Whether the vehicle is damage proof
  • string vehicleType: Filters vehicles by type, e.g. "automobile", "bike" etc.

If vehicleType is specified, the model filter is ignored.

Object

  • bool isBreakable: Whether the object is breakable
  • bool isRespawnable: Whether the object is respawnable
  • bool isMoving: Whether the object is moving
  • bool hasPhysics: Whether the object has physics. This is equivalent to engineGetModelPhysicalPropertiesGroup == -1

Object / Building

  • bool isLowLOD: Whether the object/building is a low LOD object

Marker

  • string markerType: Filters markers by type

Pickup

  • int pickupType: Filters pickups by type

Blip

  • int icon: Filters blips by icon

Colshape

  • int colShapeType: Filters colshapes by type

Team

  • bool isEmpty: Whether the team is empty

Weapon / Projectile

  • int weaponType: Filters weapons/projectiles by weapon ID

Current scope

For now, this function is client-side only.

The API implementation needs some feedback first, so I would like to make sure that the current approach and syntax are suitable before adding the server-side implementation.

Once the API implementation is considered ready, a server-side version of getElements will be added as well.

Motivation

#4797

Performance

The function was benchmarked using 1,000 consecutive calls with different numbers of elements:

Iterations Elements Total time Average time
1,000 600 282 ms 0.2820 ms
1,000 1,000 463 ms 0.4630 ms
1,000 1,900 795 ms 0.7950 ms

The main overhead is expected to come from the Lua/C++ boundary, particularly parsing the Lua filter tables into C++ and converting the resulting elements back into Lua values.

These benchmarks use 1,000 consecutive calls, which is considerably more frequent than the expected usage in typical scripts. In normal use, for example calling getElements once per second or periodically from a timer, the performance impact should be negligible.

Test plan

local x, y, z = getElementPosition(localPlayer);

for i = 1, 20 do
	createPed(0, x + i * 2, y + i * 2, z);
end

addCommandHandler('getWoundedPeds', function()
	local result = getElements({
		ped = {
			health = {value = 100, compareMethod = "<"}
		},
	});

	print('There are '..#result.ped..' wounded peds')
end)

Checklist

  • Your code should follow the coding guidelines.
  • Smaller pull requests are easier to review. If your pull request is beefy, your pull request should be reviewable commit-by-commit.

@FileEX FileEX added the enhancement New feature or request label Aug 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant