Well done.
It’s good, but there was room for improvement again, in my opinion. Some of the changes will make it faster, some are just better practice when writing code and others are my personal preference. But the changes include;
- Not getting PlayerPedId() multiple times
- Not creating new vars when you can check/reassign the parameters
- Not assigning the game pool to a var and looping, but instead looping from it directly
- Not using global vars in a loop that aren’t needed that scope, which can alter expected results
- Not looping with an integer index and assigning it to a new variable but instead looping in pairs
- Cleaned up a lot of the check variables with less repetition of natives
It now looks like this. Feel free to give it a test;
function GetClosestEntity(entitytype, alive, targets, los, ignoreanimals, coords)
-- Usage: GetClosestEntity("CPed", "alive", "any", "inlos", false, vector3(x, y, z))
-- entitytype: "CPed", "CObject", "CVehicle", "CPickup"
-- alive: "any", "alive", "dead" or (Vehicle only: "alivedriver", "deaddriver")
-- targets: "any", "player", "npc" or (Vehicle only: "empty")
-- los: "any", "notinlos", "inlos"
-- ignoreanimals: true, false
-- coords: vector3, {x, y, z} or nil for the player's coords
local playerPed, closestEntity, closestDist, aliveCheck, losCheck = PlayerPedId(), -1, -1, false, false
-- Get peds, objects, vehicles or pickups, according to the param
entitytype = entitytype or "CPed"
-- Get only alive or dead entities, according to the param
alive = alive or "alive"
-- Get entities that are only players or npcs or both, according to the param
targets = targets or "any"
-- Get only entities in or out of your line of sight, according to the param
los = los or "inlos"
-- Ignore entities that are animals according to the ignoreanimals param
ignoreanimals = ignoreanimals or false
-- Get specified coords or coords of current player if empty
coords = coords or GetEntityCoords(playerPed)
-- Loop through the game pool until closest entity is found.
for index, entity in pairs(GetGamePool(entitytype)) do
local driver = entitytype == "CVehicle" and GetPedInVehicleSeat(entity, -1) or -1
-- Handles the alive param
local aliveCheck =
(alive == "any") or
(alive == "alive" and not IsEntityDead(entity)) or
(alive == "dead" and IsEntityDead(entity)) or
(alive == "alivedriver" and driver > 0 and not IsEntityDead(driver)) or
(alive == "deaddriver" and driver > 0 and IsEntityDead(driver))
-- Handles the targets param
local targetsCheck =
(targets == "any") or
(targets == "player" and IsPedAPlayer(driver == -1 and entity or driver)) or
(targets == "npc" and driver == -1 and not IsPedAPlayer(entity)) or
(targets == "npc" and driver > 0 and not IsPedAPlayer(driver)) or
(targets == "empty" and driver == 0 and GetVehicleNumberOfPassengers(entity) == 0)
-- Handles the los param
local losCheck =
(los == "any") or
(los == "inlos" and HasEntityClearLosToEntity(playerPed, entity, 17)) or
(los == "notinlos" and not HasEntityClearLosToEntity(playerPed, entity, 17))
-- Handles the ignoreanimals param
local ignoreanimalsCheck = (not ignoreanimals or (IsEntityAPed(entity) and GetPedType(entity) ~= 28))
if entity ~= playerPed and aliveCheck and losCheck and targetsCheck and ignoreanimalsCheck then
local distance = #(coords - GetEntityCoords(entity))
if closestDist == -1 or distance < closestDist then
closestEntity = entity
closestDist = distance
end
end
end
return closestEntity, closestDist
end
local ent, dist = GetClosestEntity("CPed", "alive", "any", "inlos", false)
print(ent, dist)
if IsEntityAVehicle(ent) then
print("Entity is a veh")
elseif IsEntityAPed(ent) then
print("Entity is a ped")
elseif IsEntityAnObject(ent) then
print("Entity is a object")
end
if IsEntityDead(ent) then
print("Entity is dead")
else
print("Entity is alive")
end