For the complete documentation index, see llms.txt. This page is also available as Markdown.

⚙️Editable files preview

Config and bridge files preview, these files are ignored by the escrow system and can be modified.

Main files

These are the main files you can edit to customize this resource

client/cl_editable.lua
---------------------------------------------------------------------------------
--   _____       _                    _____          _                         --
--  |  __ \     (_)                  / ____|        | |                        --
--  | |__) |__   _  ___   ___   _ __ | |      ___   __| |  ___                 --
--  |  ___/ _ \ | |/ __| / _ \ | '_ \| |     / _ \ / _` | / _ \                --
--  | |  | (_) || |\__ \| (_) || | | | |____| (_) | (_| ||  __/                --
--  |_|   \___/ |_||___/ \___/ |_| |_|\_____|\___/ \__,_| \___|                --
--                                                                             --
--  © PoisonCode                                                               --
---------------------------------------------------------------------------------
--  Discord:       https://discord.gg/rNJ8cHXCsN                               --
--  Tebex:         https://tebex.poisoncode.com                                --
--  Docs:          https://docs.poisoncode.com                                 --
---------------------------------------------------------------------------------


RegisterCommand("collections", function(source, args)
    showUI(not IsUiDisplayed)
end)


exports('openCollections', function()
    showUI(not IsUiDisplayed)
end)


RegisterNetEvent('pc_collections:client:openCollections', function()
    showUI(not IsUiDisplayed)
end)
server/sv_editable.lua
COLLECTIONS_CACHE = {}
Database = {}

---------------------------------------------------------------------------------
--   _____       _                    _____          _                         --
--  |  __ \     (_)                  / ____|        | |                        --
--  | |__) |__   _  ___   ___   _ __ | |      ___   __| |  ___                 --
--  |  ___/ _ \ | |/ __| / _ \ | '_ \| |     / _ \ / _` | / _ \                --
--  | |  | (_) || |\__ \| (_) || | | | |____| (_) | (_| ||  __/                --
--  |_|   \___/ |_||___/ \___/ |_| |_|\_____|\___/ \__,_| \___|                --
--                                                                             --
--  © PoisonCode                                                               --
---------------------------------------------------------------------------------
--  Discord:       https://discord.gg/rNJ8cHXCsN                               --
--  Tebex:         https://tebex.poisoncode.com                                --
--  Docs:          https://docs.poisoncode.com                                 --
---------------------------------------------------------------------------------

-- ====================================================================================================== --
-- ------------------------------------------- DATABASE ------------------------------------------------- --
-- ====================================================================================================== --

function Database.Init()
    if Config.Database == "oxmysql" and GetResourceState('oxmysql') ~= 'started' then
        print("^1[ERROR] oxmysql defined in config but not started. Switching to JSON.^0")
        Config.Database = "json"
    end

    if Config.Database == "json" then
        local loadFile = LoadResourceFile(GetCurrentResourceName(), "./server/data.json")
        if loadFile then
            COLLECTIONS_CACHE = json.decode(loadFile)
        else
            COLLECTIONS_CACHE = {}
        end
    end
end


---@param PID string Player Unique Identifier
---@param collectionName string|nil Collection name to get count for
---@return number|table 
function Database.GetLimitCounts(PID, collectionName)
    if Config.Database == "oxmysql" then
        if not collectionName then
            local result = {}
            local response = MySQL.prepare.await('SELECT collection, count FROM `collections` WHERE `player_id` = ?', {PID})
            if response then
                if #response == 0 and response.collection then response = {response} end
                for _, row in ipairs(response) do
                    result[row.collection] = row.count
                end
            end
            return result
        else
            return MySQL.prepare.await('SELECT count FROM `collections` WHERE `player_id` = ? AND `collection` = ?', {PID, collectionName}) or 0
        end
    else
        if not COLLECTIONS_CACHE[PID] then return (collectionName and 0 or {}) end
        if collectionName then
            return COLLECTIONS_CACHE[PID][collectionName] or 0
        else
            return COLLECTIONS_CACHE[PID]
        end
    end
end


---@param PID string Player Unique Identifier
---@param collectionName string
function Database.IncrementLimit(PID, collectionName)
    if Config.Database == "oxmysql" then
        MySQL.prepare.await('INSERT INTO collections (player_id, collection, count) VALUES (?,?,1) ON DUPLICATE KEY UPDATE count = count + 1', {PID, collectionName})
    else
        if not COLLECTIONS_CACHE[PID] then COLLECTIONS_CACHE[PID] = {} end
        COLLECTIONS_CACHE[PID][collectionName] = (COLLECTIONS_CACHE[PID][collectionName] or 0) + 1
        SaveResourceFile(GetCurrentResourceName(), "./server/source/data.json", json.encode(COLLECTIONS_CACHE), -1)
    end
end

-- ====================================================================================================== --
-- --------------------------------------------- OTHER -------------------------------------------------- --
-- ====================================================================================================== --

---@param player player Player source id
---@return string Unique Player identifier
function GetPlayerUID(player)
    if Config.Framework == "ESX" then
        return Bridge.GetPlayer(player).identifier
    elseif Config.Framework == "QBCore" or Config.Framework == "QBox" then
        return Bridge.GetPlayer(player).PlayerData.citizenid
    elseif Config.Framework == "ox_core" then
        return Bridge.GetPlayer(player).charId
    end
end


RegisterNetEvent('pc_collections:server:openCollections', function(target)
    TriggerClientEvent('pc_collections:client:openCollections', target)
end)


exports('openCollections', function(target)
    TriggerClientEvent('pc_collections:client:openCollections', target)
end)
config.lua
Config = {}
Locales = {}
Bridge = {}
---------------------------------------------------------------------------------
--   _____       _                    _____          _                         --
--  |  __ \     (_)                  / ____|        | |                        --
--  | |__) |__   _  ___   ___   _ __ | |      ___   __| |  ___                 --
--  |  ___/ _ \ | |/ __| / _ \ | '_ \| |     / _ \ / _` | / _ \                --
--  | |  | (_) || |\__ \| (_) || | | | |____| (_) | (_| ||  __/                --
--  |_|   \___/ |_||___/ \___/ |_| |_|\_____|\___/ \__,_| \___|                --
--                                                                             --
--  © PoisonCode                                                               --
---------------------------------------------------------------------------------
--  Discord:       https://discord.gg/rNJ8cHXCsN                               --
--  Tebex:         https://tebex.poisoncode.com                                --
--  Docs:          https://docs.poisoncode.com                                 --
---------------------------------------------------------------------------------

-- ====================================================================================================== --
-- ---------------------------------------- BRIDGE SETTINGS --------------------------------------------- --
-- ====================================================================================================== --

Config.Framework = "ESX" -- "ESX" / "QBCore" / "QBox" / "ox_core"
Config.InventorySystem = "ox_inventory" -- "ox_inventory" / "ESX" / "QBCore" / "QBox" (ox_core has to use ox_inventory)
Config.Database = "oxmysql" -- "oxmysql" / "json" -- we recommend using oxmysql, you have to setup the database table using the provided SQL file.
Config.Notifications = "pc_notifications" -- pc_notifications / "custom"

-- ====================================================================================================== --
-- -------------------------------------------- GENERAL ------------------------------------------------- --
-- ====================================================================================================== --

Config.Locale = "en" -- Set your language here -- available languages: en 

Config.Debug = false -- Enable debug messages

Config.ShowClaimLimits = true -- Show claim limits in the UI
Config.ShowRewardIcons = true -- Show reward icons in the UI, if disabled only names will be shown

-- ====================================================================================================== --
-- -------------------------------------------- SKILLS -------------------------------------------------- --
-- ====================================================================================================== --
--   For this section to work, you need pc_skills resource: https://tebex.poisoncode.com/scripts/skills   --
-- ====================================================================================================== --

Config.UseSkillSystem = true -- Enable skill system integration
Config.SkillName = "skill1" -- Skill name from the skill system 

-- ====================================================================================================== --
-- ------------------------------------------ COLLECTIONS ----------------------------------------------- --
-- ====================================================================================================== --

Config.Collections = {

    ["collection1"] = { -- Collection name
        order = 1, -- Order in the list
        label = "Example collection 1", -- Collection name
        limit = false, -- Limit how many times player can complete this collection, set to false for unlimited
        items = { -- Items required to complete this collection
            {name = "bread", label = "Bread", count = 2},
        },
        reward = { -- Items rewarded for completing this collection
            {name = "money", label = "Cash", count = 500},
        },
        -- pc_skills integration, this will only work if Config.pc_skills.enabled is set to true
        lvl = 1, -- Level required to unlock this collection, only works if Config.pc_skills.enabled is set to true
        rewardXP = 200, -- Experience points rewarded for completing this collection, only works if Config.pc_skills.enabled is set to true
    },

    ["collection2"] = {
        order = 2,
        label = "Example collection 2",
        limit = 1,
        items = {
            {name = "weed", label = "Weed", count = 5},
            {name = "glove", label = "Gloves", count = 2},
            {name = "mask1", label = "Mask", count = 1},
        },
        reward = {
            {name = "armour", label = "Bulletproof vest", count = 1},
            {name = "weapon_pistol", label = "Pistol", count = 1},
        },
        lvl = 1,
        rewardXP = 10,
    },

    ["collection3"] = {
        order = 3,
        label = "Example collection 3",
        limit = 1,
        items = {
            {name = "carrot", label = "Carrot", count = 1},
            {name = "eggplant", label = "Eggplant", count = 1},
            {name = "Pepper", label = "Pepper", count = 1},
        },
        reward = {
            {name = "money", label = "Cash", count = 20000},
        },
        lvl = 5,
        rewardXP = 20,
    },

    ["collection4"] = {
        order = 4,
        label = "Example collection 4",
        limit = 2,
        items = {
            {name = "bread", label = "Bread", count = 1},
            {name = "bread", label = "Bread", count = 1},
            {name = "bread", label = "Bread", count = 1},
            {name = "bread", label = "Bread", count = 1},
            {name = "bread", label = "Bread", count = 1},
            {name = "water", label = "Water", count = 1},
            {name = "water", label = "Water", count = 1},
            {name = "water", label = "Water", count = 1},
            {name = "water", label = "Water", count = 1},
            {name = "water", label = "Water", count = 1},
        },
        reward = {
            {name = "usb_black", label = "USB stick", count = 2},
        },
        lvl = 3,
        rewardXP = 20,
    },

        ["collection5"] = {
        order = 5,
        label = "Example collection 5",
        limit = 3,
        items = {
            {name = "advancedkit", label = "Repair kit", count = 1},
            {name = "ziptie", label = "Ziptie", count = 5},
        },
        reward = {
            {name = "internals", label = "Parts", count = 2},
        },
        lvl = 3,
        rewardXP = 100,
    },
    
}

Bridge module

Bridge module is used to provide compatibility with different frameworks, inventory systems and much more, you can see which system are supported and if you have sufficient knowledge - add a new one.

server/framework.lua
server/inventory.lua
server/notifications.lua

If you encounter any problems during configuration, you can create a support ticket on our discord.

Last updated