Page cover

QBox Install

Setup

  1. First, go to https://keymaster.fivem.net/ and download the purchased files.

  2. We use this interact system in the inventory system. If you use our version, options like changing colors will work automatically, but you can also use the project creator's version if you wish.

  3. Upload the "row-textUI" file you downloaded from keymaster with the inventory and other inventory files to your server files.

  4. Find the sql file in the "row_inventory" file we gave you and read it.

  5. You can change the language of the file in row_inventory/fxmanifest.lua.

  6. Replace all ox_Inventory exports in your package with row_inventory.

Replace the function qbx_core/server/player.lua ⇒ self.Functions.SetInventory with the following

    function self.Functions.SetInventory(items)
        if GetResourceState('row_inventory') ~= 'missing' then 
            assert(not self.Offline, 'unsupported for offline players')
            exports.row_inventory:SetInventory(self.PlayerData.source, items)
            return
        end
        error('Player.Functions.SetInventory is unsupported for ox_inventory. Try ClearInventory, then add the desired items.')
    end

Replace the function qbx_core/server/player.lua ⇒ Save with the following

function Save(source)
    local ped = GetPlayerPed(source)
    local playerData = QBX.Players[source].PlayerData
    local playerState = Player(source)?.state
    local pcoords = playerData.position
    if not playerState.inApartment and not playerState.inProperty then
        local coords = GetEntityCoords(ped)
        pcoords = vec4(coords.x, coords.y, coords.z, GetEntityHeading(ped))
    end
    if not playerData then
        lib.print.error('QBX.PLAYER.SAVE - PLAYERDATA IS EMPTY!')
        return
    end

    playerData.metadata.health = GetEntityHealth(ped)
    playerData.metadata.armor = GetPedArmour(ped)

    if playerState.isLoggedIn then
        playerData.metadata.hunger = playerState.hunger or 0
        playerData.metadata.thirst = playerState.thirst or 0
        playerData.metadata.stress = playerState.stress or 0
    end

    CreateThread(function()
        storage.upsertPlayerEntity({
            playerEntity = playerData,
            position = pcoords,
        })
    end)
    if GetResourceState('row_inventory') ~= 'missing' then exports['row_inventory']:SaveInventory(source) end
    assert(GetResourceState('qb-inventory') ~= 'started', 'qb-inventory is not compatible with qbx_core. use ox_inventory instead')
    lib.print.verbose(('%s PLAYER SAVED!'):format(playerData.name))
end

Replace the qbx_core/server/player.lua ⇒ SaveOffline function with the following

function SaveOffline(playerData)
    if not playerData then
        lib.print.error('SaveOffline - PLAYERDATA IS EMPTY!')
        return
    end

    CreateThread(function()
        storage.upsertPlayerEntity({
            playerEntity = playerData,
            position = playerData.position.xyz
        })
    end)
    if GetResourceState('row_inventory') ~= 'missing' then exports['row_inventory']:SaveInventory(source) end
    assert(GetResourceState('qb-inventory') ~= 'started', 'qb-inventory is not compatible with qbx_core. use ox_inventory instead')
    lib.print.verbose(('%s OFFLINE PLAYER SAVED!'):format(playerData.name))
end

Replace the local function qbx_core/server/player.lua ⇒ emitMoneyEvents with the following

local function emitMoneyEvents(source, playerMoney, moneyType, amount, actionType, reason, difference)
    local isSet = actionType == 'set'
    local isRemove = actionType == 'remove'

    TriggerClientEvent('hud:client:OnMoneyChange', source, moneyType, isSet and math.abs(difference) or amount, isSet and difference < 0 or isRemove, reason)
    TriggerClientEvent('QBCore:Client:OnMoneyChange', source, moneyType, amount, actionType, reason)
    TriggerEvent('QBCore:Server:OnMoneyChange', source, moneyType, amount, actionType, reason)

    if moneyType == 'bank' and isRemove then
        TriggerClientEvent('qb-phone:client:RemoveBankMoney', source, amount)
    end

    local oxMoneyType = moneyType == 'cash' and 'money' or moneyType

    if accountsAsItems[oxMoneyType] then
        if actionType == "add" then
            exports.row_inventory:AddItem(source, oxMoneyType, amount, false, {}, reason or "emitMoneyAdd")
        elseif actionType == "remove" then
            exports.row_inventory:RemoveItem(source, oxMoneyType, amount, nil, reason or "emitMoneyRemove", true)
        elseif actionType == "set" then
            if difference and difference > 0 then
                exports.row_inventory:AddItem(source, oxMoneyType, difference, false, {}, reason or "emitMoneySet")
            elseif difference and difference < 0 then
                exports.row_inventory:RemoveItem(source, oxMoneyType, math.abs(difference), nil, reason or "emitMoneySet", true)
            end
        end
    end
end

CheckPlayerData => playerData.items = {}

if GetResourceState('row_inventory') ~= 'missing' then
        playerData.items = exports['row_inventory']:LoadInventory(playerData.source, playerData.citizenid)
    else 
        playerData.items = {}
    end
  1. And finally edit the server.cfg initialization section like this.

ensure interact
ensure row-textUI
ensure row_inventory

Last updated