Skip to content

Commit

Permalink
fix(lib): vehicle spawning reliability
Browse files Browse the repository at this point in the history
  • Loading branch information
Manason authored Nov 28, 2024
1 parent 58d862e commit e0abe76
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 54 deletions.
33 changes: 14 additions & 19 deletions client/events.lua
Original file line number Diff line number Diff line change
Expand Up @@ -206,29 +206,24 @@ RegisterNetEvent('QBCore:Client:OnSharedUpdateMultiple', function(tableName, val
end)

-- Set vehicle props
---@param vehicle number
---@param netId number
---@param props table<any, any>
qbx.entityStateHandler('setVehicleProperties', function(vehicle, _, props)
RegisterNetEvent('qbx_core:client:setVehicleProperties', function(netId, props)
if not props then return end

SetTimeout(0, function()
local state = Entity(vehicle).state

local timeOut = GetGameTimer() + 10000

while state.setVehicleProperties do
if NetworkGetEntityOwner(vehicle) == cache.playerId then
if lib.setVehicleProperties(vehicle, props) then
state:set('setVehicleProperties', nil, true)
end
end
if GetGameTimer() > timeOut then
break
local timeOut = GetGameTimer() + 1000
local vehicle = NetworkGetEntityFromNetworkId(netId)
while true do
if NetworkGetEntityOwner(vehicle) == cache.playerId then
if lib.setVehicleProperties(vehicle, props) then
return
end

Wait(50)
end
end)
if GetGameTimer() > timeOut then
return
end

Wait(50)
end
end)

-- Clear vehicle peds
Expand Down
92 changes: 57 additions & 35 deletions modules/lib.lua
Original file line number Diff line number Diff line change
Expand Up @@ -271,51 +271,73 @@ if isServer then
local vehicleType = GetVehicleType(tempVehicle)
DeleteEntity(tempVehicle)

local veh = CreateVehicleServerSetter(model, vehicleType, coords.x, coords.y, coords.z, coords.w)
while not DoesEntityExist(veh) do Wait(0) end
while GetVehicleNumberPlateText(veh) == '' do Wait(0) end
local attempts = 0

if bucket and bucket > 0 then
exports.qbx_core:SetEntityBucket(veh, bucket)
end

if ped then
SetPedIntoVehicle(ped, veh, -1)
end
local veh, netId
while attempts < 3 do
veh = CreateVehicleServerSetter(model, vehicleType, coords.x, coords.y, coords.z, coords.w)
while not DoesEntityExist(veh) do Wait(0) end
while GetVehicleNumberPlateText(veh) == '' do Wait(0) end

if not pcall(function()
lib.waitFor(function()
local owner = NetworkGetEntityOwner(veh)
if ped then
--- the owner should be transferred to the driver
if owner == NetworkGetEntityOwner(ped) then return true end
else
if owner ~= -1 then return true end
end
end, 'client never set as owner', 5000)
end) then
DeleteEntity(veh)
error('Deleting vehicle which timed out finding an owner')
end
if bucket and bucket > 0 then
exports.qbx_core:SetEntityBucket(veh, bucket)
end

local state = Entity(veh).state
state:set('initVehicle', true, true)
if ped then
SetPedIntoVehicle(ped, veh, -1)
end

if props and type(props) == 'table' and props.plate then
state:set('setVehicleProperties', props, true)
if not pcall(function()
lib.waitFor(function()
if qbx.string.trim(GetVehicleNumberPlateText(veh)) == qbx.string.trim(props.plate) then
return true
local owner = NetworkGetEntityOwner(veh)
if ped then
--- the owner should be transferred to the driver
if owner == NetworkGetEntityOwner(ped) then return true end
else
if owner ~= -1 then return true end
end
end, 'Failed to set vehicle properties within 5 seconds', 5000)
end, 'client never set as owner', 5000)
end) then
DeleteEntity(veh)
error('Deleting vehicle which timed out setting vehicle properties')
error('Deleting vehicle which timed out finding an owner')
end

local state = Entity(veh).state
local owner = NetworkGetEntityOwner(veh)
state:set('initVehicle', true, true)
netId = NetworkGetNetworkIdFromEntity(veh)
if props and type(props) == 'table' and props.plate then
TriggerClientEvent('qbx_core:client:setVehicleProperties', owner, netId, props)
local success = pcall(function()
local plateMatched = false
lib.waitFor(function()
if qbx.string.trim(GetVehicleNumberPlateText(veh)) == qbx.string.trim(props.plate) then
local currentOwner = NetworkGetEntityOwner(veh)
assert(currentOwner == owner, ('Owner changed during vehicle init. expected=%s, actual=%s'):format(owner, currentOwner))
--- check that the plate matches twice, 100ms apart as a bug has been observed in which server side matches but plate is not observed by clients to match
if plateMatched then
return true
end
plateMatched = true
Wait(100)
end
end, 'Failed to set vehicle properties within 1 second', 1000)
end)
if success then
break
else
DeleteEntity(veh)
attempts += 1
end
else
break
end
end

if attempts == 3 then
error('unable to successfully spawn vehicle after 3 attempts')
end

local netId = NetworkGetNetworkIdFromEntity(veh)
exports.qbx_core:EnablePersistence(veh)
return netId, veh
end
Expand All @@ -325,8 +347,8 @@ else
---@field scale? integer default: `0.35`
---@field font? integer default: `4`
---@field color? vector4 rgba, white by default
---@field enableDropShadow? boolean
---@field enableOutline? boolean
---@field enableDropShadow? boolean
---@field enableOutline? boolean

---@class LibDrawText2DParams : LibDrawTextParams
---@field coords vector2
Expand Down

0 comments on commit e0abe76

Please sign in to comment.