From 6b6667b4c5a20e96d3711e37e6bcfcd46b7efee0 Mon Sep 17 00:00:00 2001 From: Kenshin13 <63159154+Kenshiin13@users.noreply.github.com> Date: Sat, 14 Dec 2024 22:33:47 +0100 Subject: [PATCH] Merge pull request #1539 from Kenshiin13/spawn-vehicle feat(es_extended): add promise support for vehicle spawn functions --- [core]/es_extended/client/functions.lua | 25 +++++++-- [core]/es_extended/server/modules/onesync.lua | 56 +++++++++++++------ 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/[core]/es_extended/client/functions.lua b/[core]/es_extended/client/functions.lua index 8c35eae6..8a577e7e 100644 --- a/[core]/es_extended/client/functions.lua +++ b/[core]/es_extended/client/functions.lua @@ -530,10 +530,14 @@ end ---@param vehicleModel integer | string The vehicle to spawn ---@param coords table | vector3 The coords to spawn the vehicle at ---@param heading number The heading of the vehicle ----@param cb? function The callback function +---@param cb? fun(vehicle: number) The callback function ---@param networked? boolean Whether the vehicle should be networked ----@return nil +---@return number? vehicle function ESX.Game.SpawnVehicle(vehicleModel, coords, heading, cb, networked) + if cb and not ESX.IsFunctionReference(cb) then + error("Invalid callback function") + end + local model = type(vehicleModel) == "number" and vehicleModel or joaat(vehicleModel) local vector = type(coords) == "vector3" and coords or vec(coords.x, coords.y, coords.z) local isNetworked = networked == nil or networked @@ -549,8 +553,15 @@ function ESX.Game.SpawnVehicle(vehicleModel, coords, heading, cb, networked) return error(("Resource ^5%s^1 Tried to spawn vehicle on the client but the position is too far away (Out of onesync range)."):format(executingResource)) end + local promise = not cb and promise.new() CreateThread(function() - ESX.Streaming.RequestModel(model) + local modelHash = ESX.Streaming.RequestModel(model) + if not modelHash then + if promise then + return promise:reject(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) + end + error(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) + end local vehicle = CreateVehicle(model, vector.x, vector.y, vector.z, heading, isNetworked, true) @@ -569,10 +580,16 @@ function ESX.Game.SpawnVehicle(vehicleModel, coords, heading, cb, networked) Wait(0) end - if cb then + if promise then + promise:resolve(vehicle) + elseif cb then cb(vehicle) end end) + + if promise then + return Citizen.Await(promise) + end end ---@param vehicle integer The vehicle to spawn diff --git a/[core]/es_extended/server/modules/onesync.lua b/[core]/es_extended/server/modules/onesync.lua index 87c5f7f0..cb914a17 100644 --- a/[core]/es_extended/server/modules/onesync.lua +++ b/[core]/es_extended/server/modules/onesync.lua @@ -82,35 +82,57 @@ end ---@param coords vector3|table ---@param heading number ---@param properties table ----@param cb function +---@param cb? fun(netId: number) +---@return number? netId function ESX.OneSync.SpawnVehicle(model, coords, heading, properties, cb) + if cb and not ESX.IsFunctionReference(cb) then + error("Invalid callback function") + end + + local vehicleModel = joaat(model) local vehicleProperties = properties + local promise = not cb and promise.new() CreateThread(function() local xPlayer = ESX.OneSync.GetClosestPlayer(coords, 300) ESX.GetVehicleType(vehicleModel, xPlayer.id, function(vehicleType) - if vehicleType then - local createdVehicle = CreateVehicleServerSetter(vehicleModel, vehicleType, coords.x, coords.y, coords.z, heading) - local tries = 0 - - while not createdVehicle or createdVehicle == 0 or not GetEntityCoords(createdVehicle) do - Wait(200) - tries = tries + 1 - if tries > 20 then - return error(("Could not spawn vehicle - ^5%s^7!"):format(model)) - end + if not vehicleType then + if (promise) then + return promise:reject(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) end - -- luacheck: ignore - SetEntityOrphanMode(createdVehicle, 2) - local networkId = NetworkGetNetworkIdFromEntity(createdVehicle) - Entity(createdVehicle).state:set("VehicleProperties", vehicleProperties, true) - cb(networkId) - else error(("Tried to spawn invalid vehicle - ^5%s^7!"):format(model)) end + + local createdVehicle = CreateVehicleServerSetter(vehicleModel, vehicleType, coords.x, coords.y, coords.z, heading) + local tries = 0 + + while not createdVehicle or createdVehicle == 0 or not GetEntityCoords(createdVehicle) do + Wait(200) + tries = tries + 1 + if tries > 20 then + if promise then + return promise:reject(("Could not spawn vehicle - ^5%s^7!"):format(model)) + end + error(("Could not spawn vehicle - ^5%s^7!"):format(model)) + end + end + + -- luacheck: ignore + SetEntityOrphanMode(createdVehicle, 2) + local networkId = NetworkGetNetworkIdFromEntity(createdVehicle) + Entity(createdVehicle).state:set("VehicleProperties", vehicleProperties, true) + if promise then + promise:resolve(networkId) + elseif cb then + cb(networkId) + end end) end) + + if promise then + return Citizen.Await(promise) + end end ---@param model number|string