Here to remove old posts
This can be done a number of ways. Given you mentioned the job was called “cardealer” I am going to make some assumptions. Like you using the ESX framework. But in future, please provide as much information as possible. If anybody wants support, they should be giving EVERYTHING they know, so people can get straight to solving the issue, not figuring out stuff you already know and could have shared with those helping.
Anyway, all of these solutions assume you are using ESX and require something similar to the following added to the script, if it isn’t already (it probably is, though). These 2 event handlers can go anywhere in the client file;
RegisterNetEvent("esx:playerLoaded")
AddEventHandler("esx:playerLoaded", function(xPlayer)
ESX.PlayerData = xPlayer
end)
RegisterNetEvent("esx:setJob")
AddEventHandler("esx:setJob", function(job)
ESX.PlayerData.job = job
end)
The above code is not the only way to ensure the player’s job is always set, but it’s one of the best ways to avoid calling slow ESX functions in a loop. Basically, with ESX, once you have set the player’s job on load and updated on setJob, you can access the name with ESX.PlayerData.job.name
and use that for checks. Without something like this, you will get an error that you are trying to reference a nil property “job” of PlayerData, if you use my solutions. Anyway, now that we know what job the player has and it’s updated each time they set a new job, we can proceed. Let’s choose a solution.
Solution 1:
Edit the line for the key press check and add a check for the player’s job. This however, does mean that the marker and the 3D text are displayed despite not being a car dealer.
if IsControlJustPressed(0, 38) and ESX.PlayerData.job.name == "cardealer" then
OpenVehicleShop()
end
Solution 2:
Wrap the whole vehicleshopCoords loop inside a check for the job, so that no marker or text will display unless they have the car dealer job.
if ESX.PlayerData.job.name == "cardealer" then
for i = 1, #vehicleshopCoords do
-- etc
end
end
Solution 3:
If you want to compare it to multiple jobs, not just “cardealer”, you can replace ESX.PlayerData.job.name == "cardealer"
with a function that loops a table and checks against all approved jobs. I called mine HasApprovedJob
.
local approvedJobs = {
"cardealer",
"pdm",
"vapid"
}
function HasApprovedJob()
for i = 1, #approvedJobs do
if ESX.PlayerData.job.name == approvedJobs[i] then
return true
end
end
return false
end
Then you just use solution 1 or 2 with this function call, instead of the single job check. For example;
if HasApprovedJob() then
for i = 1, #vehicleshopCoords do
-- etc
end
end
Completed Example:
local approvedJobs = {
"cardealer",
"pdm",
"vapid"
}
function HasApprovedJob()
for i = 1, #approvedJobs do
if ESX.PlayerData.job.name == approvedJobs[i] then
return true
end
end
return false
end
RegisterNetEvent('esx:playerLoaded')
AddEventHandler('esx:playerLoaded', function(xPlayer)
ESX.PlayerData = xPlayer
end)
RegisterNetEvent("esx:setJob")
AddEventHandler("esx:setJob", function(job)
ESX.PlayerData.job = job
end)
Citizen.CreateThread(function()
while true do
Citizen.Wait(3)
local ped = PlayerPedId()
if HasApprovedJob() then
for i = 1, #vehicleshopCoords do
local actualShop = vehicleshopCoords[i]
local dist = #(actualShop - GetEntityCoords(ped))
if dist <= 50.0 then
DrawMarker(23, actualShop.x, actualShop.y, actualShop.z - 0.97, 0, 0, 0, 0, 0, 0, 1.0, 1.0, 0.7, 200, 10, 10, 100, 0, 0, 0, 0, 0, 0, 0)
if dist <= 10.0 then
DrawText3Ds(actualShop.x, actualShop.y, actualShop.z,"PRESS ~r~E~w~ TO OPEN VEHICLE SHOP")
if dist <= 5.0 then
if IsControlJustPressed(0, 38) then
OpenVehicleShop()
end
end
end
end
end
end
end
end)