Custom Framework - Client
Make sure to check the qb.lua
and esx.lua
files for examples on how to implement the phone for your framework. They are always up to date with the latest changes.
Framework check
At the top of the file, add a check for Config.Framework
. If it's not set to your framework, return to prevent it from loading.
if Config.Framework ~= "your-framework" then
return
end
Wait for player to load
Next, you need to wait for the player to load. How this is done depends on your framework. Once the player's character has loaded, set loaded = true
. This lets the phone know that your framework has loaded, and is ready to be used.
while not ESX.PlayerLoaded do
Wait(500)
end
loaded = true
Framework events
The phone has a few common functions that can be used for framework events.
Player unload/switching character
Trigger LogOut()
when the player unloads their character. This closes the phone, ends calls etc.
-- This is an example from the lb-phone qb.lua file
RegisterNetEvent("QBCore:Client:OnPlayerUnload", function()
LogOut()
end)
When a character has been loaded, trigger FetchPhone()
to load the phone.
-- This is an example from the lb-phone qb.lua file
RegisterNetEvent("QBCore:Client:OnPlayerLoaded", function()
FetchPhone()
end)
Money change
When the player's money changes, you can trigger the wallet:setBalance
NUI event to update the wallet balance.
SendReactMessage("wallet:setBalance", math.floor(bankBalance))
Inventory item removal
When an item is removed from the player's inventory, you can add a check if the player has a phone item. If not, close the phone.
-- This is an example from the lb-phone esx.lua file
RegisterNetEvent("esx:removeInventoryItem", function(item, count)
-- Check if the config requires a phone item
if not Config.Item.Require or Config.Item.Unique or item ~= Config.Item.Name or count > 0 then
return
end
-- This wait allows various variables to update, fixing race conditions
Wait(500)
if not HasPhoneItem() then
-- OnDeath closes the phone, ends calls etc.
OnDeath()
end
end)
Framework functions
You need to implement the following functions for the phone to work with your framework.
HasPhoneItem
Check if the player has the phone item in their inventory.
---@param number?: string # The phone number to check (if using unique phones)
---@return boolean
function HasPhoneItem(number)
if not Config.Item.Require then
return true
end
if Config.Item.Unique then
-- HasPhoneNumber is a function defined in the unique phones file
return HasPhoneNumber(number)
end
-- Implement your own check here
return true
end
HasJob
Check if the player has one of various jobs
---@param jobs string[]
---@return boolean
function HasJob(jobs)
-- Edit this to get the player's job
local job = ESX.PlayerData.job.name
for i = 1, #jobs do
if jobs[i] == job then
return true
end
end
return false
end
Garage functions
ApplyVehicleMods
Apply vehicle mods to a vehicle
---@param vehicle number
---@param vehicleData table
function ApplyVehicleMods(vehicle, vehicleData) end
CreateFrameworkVehicle
Create a vehicle and apply mods
---@param vehicleData table
---@param coords vector3
---@return number? vehicle
function CreateFrameworkVehicle(vehicleData, coords)
local model = LoadModel(vehicleData.model)
local vehicle = CreateVehicle(model, coords.x, coords.y, coords.z, 0.0, true, false)
ApplyVehicleMods(vehicle, vehicleData)
return vehicle
end
Companies/services functions
GetCompanyData
This function should callback or return the company data for the player's job.
---@param cb fun(companyData: table)
function GetCompanyData(cb)
local companyData = {}
return companyData
end
The company data should return the following:
- job:
string
- jobLabel:
string
- isBoss:
boolean
- duty?:
boolean
- optional. Requires the ToggleDuty function to be implemented. For the toggle duty button to show, duty has to be true or false, not nil.
If the player is a boss, also return the following:
- balance:
number
- The company's bank balance - employees:
Employee[]
- A list of employees- name:
string
- id:
string
- the player's identifier - gradeLabel:
string
- grade:
string
- canInteract:
boolean
- Whether the player can interact with this employee (fire, promote etc.)
- name:
- grades:
Grade[]
- label:
string
- grade:
any
- label:
DepositMoney
Deposit money into the company's bank account. Return or callback the updated bank balance.
---@param amount number
---@param cb fun(amount: number)
function DepositMoney(amount, cb)
-- Implement your deposit function here
return newBalance
end
WithdrawMoney
Withdraw money from the company's bank account. Return or callback the updated bank balance.
---@param amount number
---@param cb fun(amount: number)
function WithdrawMoney(amount, cb)
-- Implement your withdraw function here
return newBalance
end
HireEmployee
Hire an employee. Return or callback the player data of the new employee (name & id).
---@param source number
---@param cb fun(employee: Employee)
function HireEmployee(source, cb)
-- Implement your hire function here
return { name = "John Doe", id = "license:1234567890" }
end
FireEmployee
Fire an employee. Return or callback boolean
---@param id string
---@param cb fun(success: boolean)
function FireEmployee(id, cb)
-- Implement your fire function here
return true
end
SetGrade
Promote/demote an employee. Return or callback boolean
---@param id string
---@param grade string
---@param cb fun(success: boolean)
function SetGrade(id, grade, cb)
-- Implement your set grade function here
return true
end
ToggleDuty
Optional. Toggle the player's duty status. You do not need to return anything.
function ToggleDuty()
-- Implement your duty toggle function here
TriggerServerEvent("QBCore:ToggleDuty")
end