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.

Step 1: Check Framework Compatibility

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

Step 2: Wait for Player to Fully 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

Step 3: Required Framework Functions

You need to implement the following functions for the phone to work with your framework.

FreamworkNotification

Used to display notifications

function FreamworkNotification(text, notifType, length)
    notifType = notifType or "info"
    length = length or 5000
    print(text, notifType, length)
end

GetClosestPlayer

Finds nearest players

function GetClosestPlayer()
    return Config.Core.Game.GetClosestPlayer()
end

GetVehiclesInArea

Returns vehicles in the specified area

function GetVehiclesInArea(pos, maxRadius)
    return Config.Core.Game.GetVehiclesInArea(pos, maxRadius)
end

GetClosestVehicle

Returns the closest vehicle to the player

function GetClosestVehicle(coord)
    return Config.Core.Game.GetClosestVehicle(coord)
end

GetPlayersInArea

This function gets all players in the given radius.

function GetPlayersInArea(coord, maxRadius)
    return Config.Core.Game.GetPlayersInArea(coord, maxRadius)
end

GetPlayerBankBalance

Returns the player's bank money

function GetPlayerBankBalance()
    local money = 0
    return money

    -- Returns the player's bank balance.
    -- Uses a promise to handle the asynchronous callback from the server.
    --[[
        local p = promise.new()

        Config.Core.Functions.TriggerCallback('gksphone:server:getPlayerBankBalance', function(balance)
            local money = 0
            if balance then
                money = math.floor(balance * 100) / 100
            end
            p:resolve(money)
        end)
    
        return Citizen.Await(p)
    --]]
end

VehicleCreate

function VehicleCreate(model, coords, vehicleData)
    local createCar = CreateVehicle(model, coords.x, coords.y, coords.z, 0.0, true, false)
    SetVehicleOnGroundProperly(createCar)
    Config.Core.Game.SetVehicleProperties(createCar, vehicleData?.vehMods)
    SetFuel(createCar, vehicleData?.vehMods?.fuelLevel or 100)
    GiveKeyCar(createCar)
    SetModelAsNoLongerNeeded(model)
    return createCar
end

Step 4: Required Framework Events

Player load/unload/switching character

For character information when a character is loaded

PlayerData = {}
RegisterNetEvent('esx:playerLoaded', function(data)
    PlayerData = data
    PlayerData.identifier = PlayerData.identifier -- 'Player identifier'
    if PlayerData ~= nil then
        if PlayerData.job ~= nil then
            JobInfo.job = PlayerData.job.name
            JobInfo.job_grade = PlayerData.job.grade
            JobInfo.job_label = PlayerData.job.label
            JobInfo.job_grade_label = PlayerData.job.grade_label
            JobInfo.onDuty = PlayerData.job?.onDuty or false
            JobUpdate()
        end
    end

    if not isFirstLoaded then
        if Config.AutoOpen then
            ForceLoadPhone()
        end
    end

    isFirstLoaded = true
end)

When the character logs out, this closes the phone, ends calls, etc.

RegisterNetEvent('esx:onPlayerLogout', function()
    Debugprint('esx:onPlayerLogout')
    PlayerData = {}
    JobInfo.job = ""
    JobInfo.job_grade = 0
    JobInfo.job_label = ""
    JobInfo.job_grade_label = ""
    JobInfo.onDuty = false
    isFirstLoaded = false
    TriggerServerEvent("gksphone:server:playerDropped")
end)

Player Die/handcuffed character

When a character dies or is handcuffed

Cuffed = false
AddEventHandler('esx:onPlayerDeath', function(data)
    if PhoneOpen == true then
        OpenPhone()
    end
    PhoneOpenBlock = true
    PhoneBlockReason = "You can't use the phone while dead, handcuffed or in last stand."
    if Incall then
        EndPhoneCall()
    end
    if MusicData and MusicData[CurrentPlayerId] then
        TriggerServerEvent('gksphone:server:musicListen', nil, nil, "pause", nil)
    end
end)

AddEventHandler("playerSpawned", function()
    PhoneBlockReason = ""
    PhoneOpenBlock = false
end)

AddEventHandler("esx:onPlayerSpawn", function()
    PhoneBlockReason = ""
    PhoneOpenBlock = false
end)

RegisterNetEvent('esx_policejob:handcuff', function()
    Cuffed = not Cuffed
    if Cuffed then
        if PhoneOpen == true then
            OpenPhone()
        end
        PhoneOpenBlock = true
        PhoneBlockReason = "You can't use the phone while dead, handcuffed or in last stand."
        if Incall then
            EndPhoneCall()
        end
    else
        PhoneBlockReason = ""
        PhoneOpenBlock = false
    end
end)

RegisterNetEvent('esx_policejob:unrestrain', function()
    PhoneBlockReason = ""
    PhoneOpenBlock = false
end)

Last updated