Merge pull request #153 from thelindat/main

feat(esx/server): onesync entity spawning and iterators
This commit is contained in:
Mycroft
2022-05-10 20:18:50 +01:00
committed by GitHub
8 changed files with 216 additions and 11 deletions
+2
View File
@@ -4,6 +4,7 @@ game 'gta5'
description 'ES Extended' description 'ES Extended'
lua54 'yes'
version '1.7.0' version '1.7.0'
shared_scripts { shared_scripts {
@@ -20,6 +21,7 @@ server_scripts {
'server/common.lua', 'server/common.lua',
'server/classes/player.lua', 'server/classes/player.lua',
'server/functions.lua', 'server/functions.lua',
'server/onesync.lua',
'server/paycheck.lua', 'server/paycheck.lua',
'server/main.lua', 'server/main.lua',
'server/commands.lua', 'server/commands.lua',
+203
View File
@@ -0,0 +1,203 @@
ESX.OneSync = {}
---@class vector3
---@field x number
---@field y number
---@field z number
local function getNearbyPlayers(source, closest, distance, ignore)
local result = {}
local count = 0
if not distance then distance = 100 end
if type(source) == 'number' then
source = GetPlayerPed(source)
if not source then
error("Received invalid first argument (source); should be playerId or vector3 coordinates")
end
source = GetEntityCoords(GetPlayerPed(source))
end
for _, xPlayer in pairs(ESX.Players) do
if not ignore or not ignore[xPlayer.source] then
local entity = GetPlayerPed(xPlayer.source)
local coords = GetEntityCoords(entity)
if not closest then
local dist = #(source - coords)
if dist <= distance then
count += 1
result[count] = {id = xPlayer.source, ped = entity, coords = coords, dist = dist}
end
else
local dist = #(source - coords)
if dist <= (result.dist or distance) then
result = {id = xPlayer.source, ped = entity, coords = coords, dist = dist}
end
end
end
end
return result
end
---@param source vector3|number playerId or vector3 coordinates
---@param maxDistance number
---@param ignore table playerIds to ignore, where the key is playerId and value is true
function ESX.OneSync.GetPlayersInArea(source, maxDistance, ignore)
return getNearbyPlayers(source, false, maxDistance, ignore)
end
---@param source vector3|number playerId or vector3 coordinates
---@param maxDistance number
---@param ignore table playerIds to ignore, where the key is playerId and value is true
function ESX.OneSync.GetClosestPlayer(source, maxDistance, ignore)
return getNearbyPlayers(source, true, maxDistance, ignore)
end
---@param model number|string
---@param coords vector3|table
---@param heading number
---@param cb function
function ESX.OneSync.SpawnVehicle(model, coords, heading, cb)
if type(model) == 'string' then model = GetHashKey(model) end
CreateThread(function()
local entity = Citizen.InvokeNative(`CREATE_AUTOMOBILE`, model, coords.x, coords.y, coords.z, heading)
while not DoesEntityExist(entity) do Wait(50) end
-- Sometimes peds can spawn in the vehicle
local ped = GetPedInVehicleSeat(entity, -1)
if ped > 0 then
for i = -1, 6 do
ped = GetPedInVehicleSeat(entity, i)
local popType = GetEntityPopulationType(ped)
if popType <= 5 or popType >= 1 then
DeleteEntity(ped)
end
end
end
cb(entity)
end)
end
---@param model number|string
---@param coords vector3|table
---@param heading number
---@param cb function
function ESX.OneSync.SpawnObject(model, coords, heading, cb)
if type(model) == 'string' then model = GetHashKey(model) end
CreateThread(function()
local entity = CreateObject(model, coords, true, true)
while not DoesEntityExist(entity) do Wait(50) end
SetEntityHeading(entity, heading)
cb(entity)
end)
end
---@param model number|string
---@param coords vector3|table
---@param heading number
---@param cb function
function ESX.OneSync.SpawnPed(model, coords, heading, cb)
if type(model) == 'string' then model = GetHashKey(model) end
CreateThread(function()
local entity = CreatePed(0, model, coords.x, coords.y, coords.z, heading, true, true)
while not DoesEntityExist(entity) do Wait(50) end
cb(entity)
end)
end
---@param model number|string
---@param vehicle number entityId
---@param seat number
---@param cb function
function ESX.OneSync.SpawnPedInVehicle(model, vehicle, seat, cb)
if type(model) == 'string' then model = GetHashKey(model) end
CreateThread(function()
local entity = CreatePedInsideVehicle(vehicle, 1, model, seat, true, true)
while not DoesEntityExist(entity) do Wait(50) end
cb(entity)
end)
end
local function getNearbyEntities(entities, coords, modelFilter, maxDistance, isPed)
local nearbyEntities = {}
coords = type(coords) == 'number' and GetEntityCoords(GetPlayerPed(coords)) or vector3(coords.x, coords.y, coords.z)
for _, entity in pairs(entities) do
if not isPed or (isPed and not IsPedAPlayer(entity)) then
if not modelFilter or modelFilter[GetEntityModel(entity)] then
local entityCoords = GetEntityCoords(entity)
if not maxDistance or #(coords - entityCoords) <= maxDistance then
nearbyEntities[#nearbyEntities+1] = {entity=entity, coords=entityCoords}
end
end
end
end
return nearbyEntities
end
---@param coords vector3
---@param maxDistance number
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
---@return table
function ESX.OneSync.GetPedsInArea(coords, maxDistance, modelFilter)
return getNearbyEntities(GetAllPeds(), coords, modelFilter, maxDistance, true)
end
---@param coords vector3
---@param maxDistance number
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
---@return table
function ESX.OneSync.GetObjectsInArea(coords, maxDistance, modelFilter)
return getNearbyEntities(GetAllObjects(), coords, modelFilter, maxDistance)
end
---@param coords vector3
---@param maxDistance number
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
---@return table
function ESX.OneSync.GetVehiclesInArea(coords, maxDistance, modelFilter)
return getNearbyEntities(GetAllVehicles(), coords, modelFilter, maxDistance)
end
local function getClosestEntity(entities, coords, modelFilter, isPed)
local distance, closestEntity, closestCoords = maxDistance or 100, nil, nil
coords = type(coords) == 'number' and GetEntityCoords(GetPlayerPed(coords)) or vector3(coords.x, coords.y, coords.z)
for _, entity in pairs(entities) do
if not isPed or (isPed and not IsPedAPlayer(entity)) then
if not modelFilter or modelFilter[GetEntityModel(entity)] then
local entityCoords = GetEntityCoords(entity)
local dist = #(coords - entityCoords)
if dist < distance then
closestEntity, distance, closestCoords = entity, dist, entityCoords
end
end
end
end
return closestEntity, distance, closestCoords
end
---@param coords vector3
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
---@return number entityId, number distance, vector3 coords
function ESX.OneSync.GetClosestPed(coords, modelFilter)
return getClosestEntity(GetAllPeds(), coords, modelFilter, true)
end
---@param coords vector3
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
---@return number entityId, number distance, vector3 coords
function ESX.OneSync.GetClosestObject(coords, modelFilter)
return getClosestEntity(GetAllObjects(), coords, modelFilter)
end
---@param coords vector3
---@param modelFilter table models to ignore, where the key is the model hash and the value is true
---@return number entityId, number distance, vector3 coords
function ESX.OneSync.GetClosestVehicle(coords, modelFilter)
return getClosestEntity(GetAllVehicles(), coords, modelFilter)
end
+1 -1
View File
@@ -39,7 +39,7 @@ if not Config.UseDeferrals then
AddEventHandler('esx_identity:showRegisterIdentity', function() AddEventHandler('esx_identity:showRegisterIdentity', function()
TriggerEvent('esx_skin:resetFirstSpawn') TriggerEvent('esx_skin:resetFirstSpawn')
if not ESX.GetPlayerData().dead then if not ESX.PlayerData.dead then
EnableGui(true) EnableGui(true)
SetTimecycleModifier("hud_def_blur") SetTimecycleModifier("hud_def_blur")
SetTimecycleModifierStrength(1) SetTimecycleModifierStrength(1)
+1 -1
View File
@@ -229,7 +229,7 @@ end)
if Config.EnableControls then if Config.EnableControls then
RegisterCommand("accessory", function(src) RegisterCommand("accessory", function(src)
if not ESX.GetPlayerData().dead then if not ESX.PlayerData.dead then
OpenAccessoryMenu() OpenAccessoryMenu()
end end
end) end)
+3 -3
View File
@@ -13,7 +13,7 @@ end)
function OpenAmbulanceActionsMenu() function OpenAmbulanceActionsMenu()
local elements = {{label = _U('cloakroom'), value = 'cloakroom'}} local elements = {{label = _U('cloakroom'), value = 'cloakroom'}}
if Config.EnablePlayerManagement and ESX.GetPlayerData().job.grade_name == 'boss' then if Config.EnablePlayerManagement and ESX.PlayerData.job.grade_name == 'boss' then
table.insert(elements, {label = _U('boss_actions'), value = 'boss_actions'}) table.insert(elements, {label = _U('boss_actions'), value = 'boss_actions'})
end end
@@ -191,7 +191,7 @@ CreateThread(function()
while true do while true do
local sleep = 1500 local sleep = 1500
if ESX.GetPlayerData().job and ESX.GetPlayerData().job.name == 'ambulance' then if ESX.PlayerData.job and ESX.PlayerData.job.name == 'ambulance' then
local playerCoords = GetEntityCoords(PlayerPedId()) local playerCoords = GetEntityCoords(PlayerPedId())
local isInMarker, hasExited = false, false local isInMarker, hasExited = false, false
local currentHospital, currentPart, currentPartNum local currentHospital, currentPart, currentPartNum
@@ -380,7 +380,7 @@ CreateThread(function()
end) end)
RegisterCommand("ambulance", function(src) RegisterCommand("ambulance", function(src)
if ESX.GetPlayerData().job and ESX.GetPlayerData().job.name == 'ambulance' and not ESX.GetPlayerData().dead then if ESX.PlayerData.job and ESX.PlayerData.job.name == 'ambulance' and not ESX.PlayerData.dead then
OpenMobileAmbulanceActionsMenu() OpenMobileAmbulanceActionsMenu()
end end
end) end)
+2 -2
View File
@@ -78,13 +78,13 @@ end
-- Key Controls -- Key Controls
RegisterCommand('animmenu', function() RegisterCommand('animmenu', function()
if not ESX.GetPlayerData().dead then if not ESX.PlayerData.dead then
OpenAnimationsMenu() OpenAnimationsMenu()
end end
end, false) end, false)
RegisterCommand('cleartasks', function() RegisterCommand('cleartasks', function()
if not ESX.GetPlayerData().dead then if not ESX.PlayerData.dead then
ClearPedTasks(PlayerPedId()) ClearPedTasks(PlayerPedId())
end end
end, false) end, false)
+3 -3
View File
@@ -253,7 +253,7 @@ function OpenPropertyMenu(property)
menu.close() menu.close()
if data.current.value == 'enter' then if data.current.value == 'enter' then
TriggerEvent('instance:create', 'property', {property = property.name, owner = ESX.GetPlayerData().identifier}) TriggerEvent('instance:create', 'property', {property = property.name, owner = ESX.PlayerData.identifier})
elseif data.current.value == 'leave' then elseif data.current.value == 'leave' then
TriggerServerEvent('esx_property:removeOwnedProperty', property.name) TriggerServerEvent('esx_property:removeOwnedProperty', property.name)
elseif data.current.value == 'buy' then elseif data.current.value == 'buy' then
@@ -329,7 +329,7 @@ function OpenGatewayOwnedPropertiesMenu(property)
menu2.close() menu2.close()
if data2.current.value == 'enter' then if data2.current.value == 'enter' then
TriggerEvent('instance:create', 'property', {property = data.current.value, owner = ESX.GetPlayerData().identifier}) TriggerEvent('instance:create', 'property', {property = data.current.value, owner = ESX.PlayerData.identifier})
ESX.UI.Menu.CloseAll() ESX.UI.Menu.CloseAll()
elseif data2.current.value == 'leave' then elseif data2.current.value == 'leave' then
TriggerServerEvent('esx_property:removeOwnedProperty', data.current.value) TriggerServerEvent('esx_property:removeOwnedProperty', data.current.value)
@@ -690,7 +690,7 @@ AddEventHandler('esx:onPlayerSpawn', function()
end end
end end
TriggerEvent('instance:create', 'property', {property = propertyName, owner = ESX.GetPlayerData().identifier}) TriggerEvent('instance:create', 'property', {property = propertyName, owner = ESX.PlayerData.identifier})
end end
end end
end) end)
+1 -1
View File
@@ -741,7 +741,7 @@ end)
RegisterCommand('taximenu', function() RegisterCommand('taximenu', function()
if not ESX.GetPlayerData().dead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == 'taxi' then if not ESX.PlayerData.dead and Config.EnablePlayerManagement and ESX.PlayerData.job and ESX.PlayerData.job.name == 'taxi' then
OpenMobileTaxiActionsMenu() OpenMobileTaxiActionsMenu()
end end
end, false) end, false)