EntityInRange

The (nearest) entity-in-range interface helps you to easily create event based listeners to check what is the nearest entity to the player.

Simple example

---@type EntityInRangeApi
local EntityInRangeApi = exports.nss_libs:getEntityInRangeApi(GetCurrentResourceName())

-- For more vegetation texture names see https://github.com/OpenIV-Team/RAGE-StringsDatabase/tree/fc6bcdfdda9d79afb4571c35bc4db730b42dc0f4/RDR2/ArchiveItems/hd_0/hd/levels/rdr3/props/vegetation
local tree_texture_names = {
    "p_tree_birch_03",
    "p_tree_birch_03b",
    "p_tree_birch_03_lg",
    "p_tree_birch_03_md",
    "p_tree_birch_03_md_a"
}

---@type EntityInRangeListener
local listener

---@param nearest_entity EntityInRangeData
---@param listener_id number
local on_reach_tree = function(nearest_entity, listener_id)
    print('Reached tree', nearest_entity.entity, listener_id)
end

---@param nearest_entity EntityInRangeData
---@param listener_id number
local on_leave_tree = function(nearest_entity, listener_id)

    print('Left tree', nearest_entity.entity, listener_id)

    -- If declared lister variable is not available you can get listener by given listener_id from event like the
    -- following example:
    local event_listener = EntityInRangeApi.getListenerById(listener_id)

    -- Example for one time only: We remove the listener after tree was left
    event_listener.remove()
end

listener = EntityInRangeApi.create(tree_texture_names, on_reach_tree, on_leave_tree)

Public interface methods

create(texture_names, on_reach_callback, on_leave_callback):EntityInRangeListener

Creates a listener that calls the on_reach_callback if the player reaches the nearest entity of given texture_names and vice versa calls the on_leave_callback if the player lefts it.

Note: The created listener is initially active (on).

Returns an instance of EntityInRangeListener.

  • texture_names table Array of texture names.

  • on_reach_callback function Callback for "on-reach".

    • Arguments:

      • nearest_entity EntityInRangeData Object with entity details.

      • listener_id number ID of listener object.

  • on_leave_callback function, optional Callback for "on-left".

    • Same arguments as on_reach_callback.

  • custom_range number, optional Custom range for the listener. Default see Config.EntityInRange.DEFAULT_SEARCH_RADIUS in config.lua. Be careful with this value, because it can have a big impact on performance.

getListenerById(listener_id):EntityInRangeListener

Returns the listener object (EntityInRangeListener) matching the given listener ID otherwise nil.

  • listener_id number ID of a listener.

getEntitiesNearby(x, y, z, radius, model_name_or_hash, entity_type, filter_func):EntityInRangeData[]|nil

Returns the nearest entity (data object EntityInRangeData) of given texture_name or nil if no entity was found.

  • x number X position.

  • y number Y position.

  • z number Z position.

  • radius number, Range in meters to search for.

  • texture_name string|number|table<string|number>, optional Texture name(s) or hash(es)

  • entity_type number, optional Entity type. Default ENTITY_TYPE_OBJECT

  • filter_func function, optional Optional filter function to filter the found entities.

    • Arguments:

      • entity number

      • model_hash number

    • Returns:

      • boolean: true if the entity should be included in the result otherwise false.

Example:

---@type EntityInRangeApi
local EntityInRangeApi = exports.nss_libs:getEntityInRangeApi(GetCurrentResourceName())

local x = 0
local y = 0
local z = 0

-- See https://github.com/femga/rdr3_discoveries/blob/f729ba03f75a591ce5c841642dc873345242f612/peds/peds_list.lua for ped list ...
local texture_names = { "a_c_alligator_01", "a_c_alligator_02" }
local radius = 10.0 -- 10 meters
local entity_type = EntityInRangeApi.ENTITY_TYPE_PLAYER -- Only peds

---@type EntityInRangeApiCustomFilterFunction
local filter_func = function(entity, model_hash)
    
    -- You can filter what you want, e.g. if the entity is a real player or not, or if it is a animal or not, etc.
    if GetPedType(entity) ~= 4 then
        return false
    end
    
    return true
end

---@type EntityInRangeData[]|nil
local found_entities = EntityInRangeApi.getEntitiesNearby(x, y, z, radius, texture_names, entity_type, filter_func)

if found_entities then
    print('Found entities: ' .. tostring(json.encode(found_entities)))
else
    print('No entity found')
end 

getNearestObjectEntity(x, y, z, texture_name, range, entity_type):EntityInRangeData|nil

Returns the nearest entity (data object EntityInRangeData) of given texture_name or nil if no entity was found.

  • x number X position.

  • y number Y position.

  • z number Z position.

  • texture_name string|number Texture name or hash

  • range number, optional Range to search for. Default see Config.EntityInRange.DEFAULT_SEARCH_RADIUS in config.lua. Be careful with this value, because it can have a big impact on performance.

  • entity_type number, optional Entity type. Default ENTITY_TYPE_OBJECT

Example:

---@type EntityInRangeApi
local EntityInRangeApi = exports.nss_libs:getEntityInRangeApi(GetCurrentResourceName())

local x = 0
local y = 0
local z = 0
local texture_name = "p_tree_birch_03"
local range

---@type EntityInRangeData|nil
local found_entity = EntityInRangeApi.getNearestObjectEntity(x, y, z, texture_name, range)

if found_entity then
    print('Found nearest entity: ' .. tostring(json.encode(found_entity)))
else
    print('No entity found')
end 

ENTITY_TYPE_OBJECT number, static

Entity type for objects.

ENTITY_TYPE_PLAYER number, static

Entity type for players.

ENTITY_TYPE_VEHICLE number, static

Entity type for vehicles.


Public methods of EntityInRangeListener

remove():EntityInRangeListener

Removes the listener from the main entity-in-range checking loop and returns itself.

off():EntityInRangeListener

Alias for remove().

on():EntityInRangeListener

Insert the listener back to the main entity-in_range checking loop and returns itself.


Development notes

Open todos

Known issues

  • If a related resource is restarted and the player stand inside a range the Entity In Range trys to call the on-leave callback, but the resource is not available anymore. This results in an error.

  • Item sets have a maximum of entities they can handle. All entities above this maximum can not be found. This is a REDM/RDR2 issue.

Performance issues with classes/functions as callback arguments

Due to REDM restrictions (due to behavior currently unknown to us) on passing values between exported and non-exported script modules no classes or functions (callbacks) are passed as arguments into events. In this interface only the ID of the listener object is passed instead of the listener object itself. You can then get the listener object via the listener ID if required. This saves a lot of performance.

Last updated