Page cover

Open Files Preview

Here you can see the open files of the Advanced Bag

config.lua
--[[ 
  _   _  _____     ___      ____   ____ ____  ___ ____ _____ ____  
 | \ | |/ _ \ \   / / \    / ___| / ___|  _ \|_ _|  _ \_   _/ ___| 
 |  \| | | | \ \ / / _ \   \___ \| |   | |_) || || |_) || | \___ \ 
 | |\  | |_| |\ V / ___ \   ___) | |___|  _ < | ||  __/ | |  ___) |
 |_| \_|\___/  \_/_/   \_\ |____/ \____|_| \_\___|_|    |_| |____/ 
                                                                                                                                                              
                 https://nova-scripting.tebex.io/ 
              https://nova-scripting.gitbook.io/docs 
]]  

-- ============================================================================
-- GLOBAL CONFIGURATION
-- ============================================================================

Locales = {}
Config = {}     

-- Debug Mode: Enable/disable console debug prints
Config.DebugMode = false -- Set to true to see debug messages in console

-- Framework Configuration
Config.Framework = 'esx' -- Choose your framework: 'esx', 'qbcore', 'qbox', or 'custom'
Config.Locale = 'en' -- Language: 'en' (English) or 'nl' (Dutch)

-- ============================================================================
-- TARGET SYSTEM CONFIGURATION
-- ============================================================================

-- Target System
Config.UseTarget = true -- Use target system for interaction (ox_target or qb-target)
Config.TargetSystem = "qtarget" -- Choose target system: "qtarget" or "qb-target"

-- ============================================================================
-- BAG CORE SETTINGS
-- ============================================================================

-- Bag Object Settings
Config.BagModel = 'prop_cs_heist_bag_02' -- 3D object model for the bag
Config.RestrictOneBag = true -- Delete previous bag when placing a new one (only one bag allowed per player)

-- Bag Sharing Settings
Config.EnableBagSharing = true -- Whether players can share their bags with others

-- ============================================================================
-- BAG ITEMS CONFIGURATION
-- ============================================================================

-- Multiple Bag Items Configuration (REQUIRED - no more Config.BagItem)
Config.BagItems = {
    ['outfitbag'] = {
        maxOutfits = 15, -- Maximum outfits for this specific bag
        maxWeight = 35.0, -- Maximum weight in kg for this bag (only used if restrictionType = 'weight')
        maxAmount = 20 -- Maximum amount of items for this bag (only used if restrictionType = 'amount')
    },
    ['smallbag'] = {
        maxOutfits = 5, -- Small bag with fewer outfits
        maxWeight = 25.0, -- Less weight capacity
        maxAmount = 10 -- Less item capacity
    },
    ['mediumbag'] = {
        maxOutfits = 10, -- Medium bag with more outfits
        maxWeight = 35.0, -- More weight capacity
        maxAmount = 20 -- More item capacity
    },
    ['largebag'] = {
        maxOutfits = 20, -- Large bag with most outfits
        maxWeight = 50.0, -- Most weight capacity
        maxAmount = 30 -- Most item capacity
    }
}

-- Default values for bags without specific configuration
Config.DefaultBagSettings = {
    maxOutfits = 10, -- Default maximum outfits for bags not in Config.BagItems
    maxWeight = 30.0, -- Default maximum weight
    maxAmount = 15 -- Default maximum amount
}

-- ============================================================================
-- INVENTORY SYSTEM CONFIGURATION
-- ============================================================================

-- Inventory Check Settings
Config.CheckPlayerInventory = true -- Check if player has enough inventory space for all operations
Config.EnableBagRestrictions = true -- Enable/disable bag weight/amount restrictions
Config.EnableItemStacking = true -- Enable/disable automatic item stacking (combines same items)

-- Global Item Restrictions (applies to all bags)
Config.restrictionType = 'weight' -- 'weight' or 'amount' - how to limit items (global for all bags)
Config.excludedItems = { -- Items to exclude from inventory when adding to bag (global for all bags)
    'outfitbag',
    'smallbag',
    'mediumbag',
    'largebag'
}

-- ============================================================================
-- COMMAND CONFIGURATION
-- ============================================================================

Config.Command = {
    enabled = true, -- Enable /advancedbag command
    command = "advancedbag", -- Command name (without /)
    shortCommand = "ab", -- Short command name (without /)
    description = "Open the advanced bag interface", -- Command description shown in help
    allowedRoles = {
        "admin", 
        "superadmin"
    }, -- Roles that can use the command (ESX groups)
    allowedJobs = {
        --'exampleJob' -- Jobs that can use the command (leave empty for no job restriction)
    }, 
    cooldown = 300 -- Cooldown between command uses in seconds (5 minutes)
}

-- ============================================================================
-- KEYBIND CONFIGURATION
-- ============================================================================

-- Keybind Settings (only applicable if target system is disabled)
Config.Keybinds = {
    public = 'ENTER', -- Key to toggle bag public/private
    open = 'E', -- Key to open the bag
    pickup = 'G', -- Key to pickup the bag
}

-- ============================================================================
-- ANIMATION CONFIGURATION
-- ============================================================================

Config.BagAnimation = {
    enabled = true, -- Enable/Disable bag placement/pickup animation
    dict = 'amb@medic@standing@tendtodead@idle_a',
    anim = 'idle_a',
}

Config.OutfitChangeAnimation = {
    enabled = true, -- Enable/Disable outfit change animation
    duration = 5000, -- Animation duration in milliseconds
    dict = 'mp_safehouseshower@male@',
    anim = 'male_shower_towel_dry_to_get_dressed',
}

Config.OutfitPartAnimations = {
    head = {
        enabled = true,
        duration = 750, -- Duration in milliseconds
        dict = 'mp_masks@on_foot',
        anim = 'put_on_mask'
    },
    shirt = {
        enabled = true,
        duration = 2500,
        dict = 'mp_safehouseshower@male@',
        anim = 'male_shower_towel_dry_to_get_dressed'
    },
    pants = {
        enabled = true,
        duration = 2000,
        dict = 'clothingtrousers',
        anim = 'try_trousers_neutral_a'
    },
    shoes = {
        enabled = true,
        duration = 1000,
        dict = 'amb@medic@standing@kneel@base',
        anim = 'base'
    }
}

-- ============================================================================
-- THEME CONFIGURATION
-- ============================================================================

Config.Themes = {
    primary = 'rgba(75, 0, 130, 1)', -- Primary color (main theme color)
    secondary = 'rgba(106, 13, 173, 1)', -- Secondary color (accent)
    accent = 'rgba(138, 43, 226, 1)', -- Accent color (highlights)
    text = 'rgba(255, 255, 255, 1)', -- Text color
    background = 'rgba(75, 0, 130, 0.9)', -- Background color
    hover = 'rgba(106, 13, 173, 0.95)', -- Hover color
    border = 'rgba(255, 255, 255, 0.1)', -- Border color
    success = 'rgba(74, 222, 128, 1)', -- Success color (green)
    error = 'rgba(255, 107, 107, 1)', -- Error color (red)
    warning = 'rgba(251, 191, 36, 1)', -- Warning color (yellow)
    bagImage = 'outfitbag_purple.png' -- Bag image filename (without path) eg outfitbag_purple.png/outfitbag_blue.png/outfitbag_gray.png/outfitbag_pink.png/outfitbag_red.png
}
client-utils.lua
-- =====================================================================
-- Configuration Data ---------------------------------------------------
-- =====================================================================

-- Ped component drawable indices
drawable = {
    ['mask'] = 1,
    ['torso'] = 3,
    ['legs'] = 4,
    ['bag'] = 5,
    ['feet'] = 6,
    ['accessory'] = 7,
    ['undershirt'] = 8,
    ['chest'] = 9,
    ['decals'] = 10,
    ['tops'] = 11,
}

-- Ped prop indices
props = {
    ['helmet'] = 0,
    ['glasses'] = 1,
    ['ear'] = 2,
}

-- Default "naked" component values organized by model hash and body zones
naked = {
    [1885233650] = {  -- Male model hash
        top = {
            ['torso'] = 15,
            ['undershirt'] = 15,
            ['tops'] = 15,
            ['accessory'] = 0,
            ['decals'] = 0,
            ['bag'] = 0,
        },
        bottom = {
            ['legs'] = 61,
            ['feet'] = 34,
        }
    },
    [-1667301416] = {  -- Female model hash
        top = {
            ['torso'] = 15,
            ['undershirt'] = 14,
            ['tops'] = 18,
            ['accessory'] = 0,
            ['decals'] = 0,
            ['bag'] = 0,
        },
        bottom = {
            ['legs'] = 62,
            ['feet'] = 35,
        }
    }
}

-- Model hash to gender mapping
models = {
    [1885233650] = 'M',  -- Male
    [-1667301416] = 'F'  -- Female
}

-- =====================================================================
-- User-Customizable Event Handlers -------------------------------------
-- =====================================================================

-- Handle bag placement events from server
RegisterNetEvent("nv-advancedbag:placeBag")
AddEventHandler("nv-advancedbag:placeBag", function(bagItem)
  Debug("Received placeBag event with bagItem: " .. tostring(bagItem))
  CreateBagObject(true, bagItem)
end)

-- =====================================================================
-- User-Customizable Utility Functions ----------------------------------
-- =====================================================================



function notification(title, text, time, type)
    SetNotificationTextEntry("STRING")
    AddTextComponentString(text)
    DrawNotification(0,1)

    --SetTextEntry_2("STRING")
    --AddTextComponentString(text)
    --DrawSubtitleTimed(duration or 30000, 1)
    
    -- Default ESX Notify:
    -- TriggerEvent('esx:showNotification', text)
    
    -- Default QB Notify:
    --TriggerEvent('QBCore:Notify', text, 'info', 5000)
    
    -- OKOK Notify:
    -- exports['okokNotify']:Alert(title, text, time, type, false)
    
    -- Display 3D text in the world (like "Press [E] to interact")
    -- Users can customize this function to change how 3D text is displayed
end

function Draw3DText(x, y, z, text, font, scaleX, scaleY)
    local camX, camY, camZ = table.unpack(GetGameplayCamCoords())
    local distance = GetDistanceBetweenCoords(camX, camY, camZ, x, y, z, true)
    local scale = (1 / distance) * 20
    local fov = (1 / GetGameplayCamFov()) * 100
    scale = scale * fov
    
    SetTextScale(scaleX * scale, scaleY * scale)
    SetTextFont(font)
    SetTextProportional(1)
    SetTextDropshadow(1, 1, 1, 1, 255)
    SetTextEdge(2, 0, 0, 0, 150)
    SetTextDropShadow()
    SetTextOutline()
    SetTextEntry("STRING")
    SetTextCentre(1)
    AddTextComponentString(text)
    SetDrawOrigin(x, y, z, 0)
    DrawText(0.0, 0.0)
    ClearDrawOrigin()
end

-- =====================================================================
-- User-Customizable Callback Functions ---------------------------------
-- =====================================================================

-- This function is called when a player applies an outfit
-- Users can add custom logic here (notifications, animations, sounds, etc.)
function OnPlayerApplyOutfit(outfitData, outfitName)
    -- Success notification
    notification("Outfit Bag", L("~g~Outfit applied successfully!"), 5000, "success")
    
    -- Example additional customizations:
    -- PlaySoundFrontend(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", 1)
    -- TriggerEvent('animations:client:EmoteCommandStart', {"dance"})
end

-- This function is called when a player applies a specific outfit part
-- Users can add custom logic here (notifications, animations, sounds, etc.)
function OnPlayerApplyOutfitPart(outfitData, outfitName, part)
    local partNames = {
        head = "head items",
        shirt = "shirt",
        pants = "pants", 
        shoes = "shoes"
    }
    
    local partName = partNames[part] or part
    
    -- Success notification
    notification("Outfit Bag", L("~g~" .. partName .. " applied successfully!"), 5000, "success")
    
    -- Example additional customizations:
    -- PlaySoundFrontend(-1, "SELECT", "HUD_FRONTEND_DEFAULT_SOUNDSET", 1)
    -- TriggerEvent('animations:client:EmoteCommandStart', {"dance"})
end
framework/server-framework.lua
Framework = nil

if Config['Framework']:upper() == 'ESX' then
    Framework = exports['es_extended']:getSharedObject()

    RegisterServerCallback = Framework.RegisterServerCallback
    GetPlayerFromId = Framework.GetPlayerFromId
    RegisterUsableItem = Framework.RegisterUsableItem

    function GetName(source)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.getName()
    end

    function isInGroup(source, groupList)
        local xPlayer = GetPlayerFromId(source)
        local playerGroup = xPlayer.getGroup()
        for _, group in ipairs(groupList) do
            if group == playerGroup then
                return true
            end
        end
        return false
    end

    function GetPlayersFunction()
        return Framework.GetPlayers()
    end

    function GetPlayerJobFunction(source)
        local xPlayer = GetPlayerFromId(source)
        PlayerJob = xPlayer.job.name
        return PlayerJob
    end

    function AddMoneyFunction(source, type, amount)
        local xPlayer = GetPlayerFromId(source)
        xPlayer.addAccountMoney(type, amount)
    end

    function RemoveMoneyFunction(source, type, amount)
        local xPlayer = GetPlayerFromId(source)
        xPlayer.removeAccountMoney(type, amount)
    end

    function GetMoneyFunction(source, type)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.getAccount(type).money
    end

    function GetIdentifierFunction(source)
        local xPlayer = GetPlayerFromId(source)
        if not xPlayer then
            print("^1[OUTFIT BAG] Error: Player not found for source " .. tostring(source) .. "^7")
            return nil
        end
        return xPlayer.identifier
    end

    function AddItemFunction(source, item, amount)
        local xPlayer = GetPlayerFromId(source)
        if not xPlayer then
            print("^1[OUTFIT BAG] Error: Player not found for add item, source " .. tostring(source) .. "^7")
            return false
        end
        xPlayer.addInventoryItem(item, amount)
        return true
    end

    function RemoveItemFunction(source, item, amount)
        local xPlayer = GetPlayerFromId(source)
        if not xPlayer then
            print("^1[OUTFIT BAG] Error: Player not found for remove item, source " .. tostring(source) .. "^7")
            return false
        end
        xPlayer.removeInventoryItem(item, amount)
        return true
    end

    function GetPlayerInventoryFunction(source)
        local xPlayer = GetPlayerFromId(source)
        if not xPlayer then
            print("^1[OUTFIT BAG] Error: Player not found for inventory check, source " .. tostring(source) .. "^7")
            return {}
        end
        local inventory = xPlayer.getInventory()
        local items = {}
        for _, item in pairs(inventory) do
            if item.count > 0 then
                -- Check if item should be excluded
                local shouldExclude = false
                for _, excludedItem in ipairs(Config.excludedItems) do
                    if item.name:lower() == excludedItem:lower() then
                        shouldExclude = true
                        break
                    end
                end
                
                if not shouldExclude then
                    table.insert(items, {
                        name = item.name,
                        label = item.label,
                        quantity = item.count,
                        weight = item.weight or 0.0
                    })
                end
            end
        end
        return items
    end

    function GetPlayerItemDataFunction(source, itemName)
        local xPlayer = GetPlayerFromId(source)
        if not xPlayer then
            print("^1[OUTFIT BAG] Error: Player not found for item data check, source " .. tostring(source) .. "^7")
            return nil
        end
        local item = xPlayer.getInventoryItem(itemName)
        if item and item.count > 0 then
            return {
                name = item.name,
                label = item.label,
                quantity = item.count,
                weight = item.weight or 0.0
            }
        end
        return nil
    end

    function CanCarryItemFunction(source, itemName, amount)
        local xPlayer = GetPlayerFromId(source)
        if not xPlayer then
            print("^1[OUTFIT BAG] Error: Player not found for can carry check, source " .. tostring(source) .. "^7")
            return false
        end
        return xPlayer.canCarryItem(itemName, amount)
    end

    function GetPlayerWeightFunction(source)
        local xPlayer = GetPlayerFromId(source)
        if not xPlayer then
            print("^1[OUTFIT BAG] Error: Player not found for weight check, source " .. tostring(source) .. "^7")
            return 0
        end
        return xPlayer.getInventoryWeight()
    end

    function GetPlayerMaxWeightFunction(source)
        local xPlayer = GetPlayerFromId(source)
        if not xPlayer then
            print("^1[OUTFIT BAG] Error: Player not found for max weight check, source " .. tostring(source) .. "^7")
            return 0
        end
        return xPlayer.getMaxWeight()
    end

elseif Config['Framework']:upper() == 'QBCORE' then
    Framework = exports['qb-core']:GetCoreObject()

    RegisterServerCallback = Framework.Functions.CreateCallback
    GetPlayerFromId = Framework.Functions.GetPlayer
    RegisterUsableItem = Framework.Functions.CreateUseableItem

    function GetName(source)
        local xPlayer = Framework.Functions.GetPlayer(source)
        return xPlayer.Functions.GetName()
    end

    function isInGroup(source, groupList)
        for _, group in ipairs(groupList) do
            if Framework.Functions.HasPermission(source, group) then
                return true
            end
        end
        return false
    end

    function GetPlayersFunction()
        return Framework.Functions.GetPlayers()
    end

    function GetPlayerJobFunction(source)
        local xPlayer = GetPlayerFromId(source)
        PlayerJob = xPlayer.PlayerData.job.name
        return PlayerJob
    end

    function AddMoneyFunction(source, type, amount)
        local xPlayer = Framework.Functions.GetPlayer(source)
        xPlayer.Functions.AddMoney(type, amount)
    end

    function RemoveMoneyFunction(source, type, amount)
        local xPlayer = Framework.Functions.GetPlayer(source)
        xPlayer.Functions.RemoveMoney(type, amount) 
    end

    function GetMoneyFunction(source, type)
        local xPlayer = Framework.Functions.GetPlayer(source) 
        return xPlayer.Functions.GetMoney(type) 
    end

    function GetIdentifierFunction(source)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.PlayerData.citizenid
    end

    function AddItemFunction(source, item, amount)
        local xPlayer = Framework.Functions.GetPlayer(source)
        xPlayer.Functions.AddItem(item, amount)
    end

    function RemoveItemFunction(source, item, amount)
        local xPlayer = Framework.Functions.GetPlayer(source)
        xPlayer.Functions.RemoveItem(item, amount)
    end

    function GetPlayerInventoryFunction(source)
        local xPlayer = GetPlayerFromId(source)
        local inventory = xPlayer.PlayerData.items
        local items = {}
        for _, item in pairs(inventory) do
            if item.amount > 0 then
                -- Check if item should be excluded
                local shouldExclude = false
                for _, excludedItem in ipairs(Config.excludedItems) do
                    if item.name:lower() == excludedItem:lower() then
                        shouldExclude = true
                        break
                    end
                end
                
                if not shouldExclude then
                    table.insert(items, {
                        name = item.name,
                        label = item.label,
                        quantity = item.amount,
                        weight = item.weight or 0.0
                    })
                end
            end
        end
        return items
    end

    function GetPlayerItemDataFunction(source, itemName)
        local xPlayer = GetPlayerFromId(source)
        local item = xPlayer.PlayerData.items[itemName]
        if item and item.amount > 0 then
            return {
                name = item.name,
                label = item.label,
                quantity = item.amount,
                weight = item.weight or 0.0
            }
        end
        return nil
    end

    function CanCarryItemFunction(source, itemName, amount)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.Functions.CanCarryItem(itemName, amount)
    end

    function GetPlayerWeightFunction(source)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.PlayerData.metadata["inventoryweight"] or 0
    end

    function GetPlayerMaxWeightFunction(source)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.PlayerData.metadata["maxweight"] or 120000
    end

elseif Config['Framework']:upper() == 'QBOX' then
    Framework = exports['qbox-core']:GetCoreObject()

    RegisterServerCallback = Framework.Functions.CreateCallback
    GetPlayerFromId = Framework.Functions.GetPlayer
    RegisterUsableItem = Framework.Functions.CreateUseableItem

    function GetName(source)
        local xPlayer = Framework.Functions.GetPlayer(source)
        return xPlayer.Functions.GetName()
    end

    function isInGroup(source, groupList)
        for _, group in ipairs(groupList) do
            if Framework.Functions.HasPermission(source, group) then
                return true
            end
        end
        return false
    end

    function GetPlayersFunction()
        return Framework.Functions.GetPlayers()
    end

    function GetPlayerJobFunction(source)
        local xPlayer = GetPlayerFromId(source)
        PlayerJob = xPlayer.PlayerData.job.name
        return PlayerJob
    end

    function AddMoneyFunction(source, type, amount)
        local xPlayer = GetPlayerFromId(source)
        xPlayer.Functions.AddMoney(type, amount)
    end

    function RemoveMoneyFunction(source, type, amount)
        local xPlayer = Framework.Functions.GetPlayer(source)
        xPlayer.Functions.RemoveMoney(type, amount) 
    end

    function GetMoneyFunction(source, type)
        local xPlayer = Framework.Functions.GetPlayer(source) 
        return xPlayer.Functions.GetMoney(type) 
    end
    
    function GetIdentifierFunction(source)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.PlayerData.citizenid
    end

    function AddItemFunction(source, item, amount)
        local xPlayer = Framework.Functions.GetPlayer(source)
        xPlayer.Functions.AddItem(item, amount)
    end

    function RemoveItemFunction(source, item, amount)
        local xPlayer = Framework.Functions.GetPlayer(source)
        xPlayer.Functions.RemoveItem(item, amount)
    end

    function GetPlayerInventoryFunction(source)
        local xPlayer = GetPlayerFromId(source)
        local inventory = xPlayer.PlayerData.items
        local items = {}
        for _, item in pairs(inventory) do
            if item.amount > 0 then
                -- Check if item should be excluded
                local shouldExclude = false
                for _, excludedItem in ipairs(Config.excludedItems) do
                    if item.name:lower() == excludedItem:lower() then
                        shouldExclude = true
                        break
                    end
                end
                
                if not shouldExclude then
                    table.insert(items, {
                        name = item.name,
                        label = item.label,
                        quantity = item.amount,
                        weight = item.weight or 0.0
                    })
                end
            end
        end
        return items
    end

    function GetPlayerItemDataFunction(source, itemName)
        local xPlayer = GetPlayerFromId(source)
        local item = xPlayer.PlayerData.items[itemName]
        if item and item.amount > 0 then
            return {
                name = item.name,
                label = item.label,
                quantity = item.amount,
                weight = item.weight or 0.0
            }
        end
        return nil
    end

    function CanCarryItemFunction(source, itemName, amount)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.Functions.CanCarryItem(itemName, amount)
    end

    function GetPlayerWeightFunction(source)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.PlayerData.metadata["inventoryweight"] or 0
    end

    function GetPlayerMaxWeightFunction(source)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.PlayerData.metadata["maxweight"] or 120000
    end

elseif Config['Framework']:upper() == 'CUSTOM' then
    -- Uncomment and modify the following lines for your custom framework

    --[[Framework = exports['your-custom-framework']:GetCoreObject()

    RegisterServerCallback = Framework.Functions.CreateCallback
    GetPlayerFromId = Framework.Functions.GetPlayer
    RegisterUsableItem = Framework.Functions.CreateUseableItem

    function GetName(source)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.Functions.GetName()
    end

    function isInGroup(source, groupList)
        for _, group in ipairs(groupList) do
            if Framework.Functions.HasPermission(source, group) then
                return true
            end
        end
        return false
    end

    function GetPlayersFunction()
        return Framework.Functions.GetPlayers()
    end

    function GetPlayerJobFunction(source)
        local xPlayer = GetPlayerFromId(source)
        PlayerJob = xPlayer.PlayerData.job.name
        return PlayerJob
    end

    function AddMoneyFunction(source, type, amount)
        local xPlayer = GetPlayerFromId(source)
        xPlayer.Functions.AddMoney(type, amount)
    end

    function RemoveMoneyFunction(source, type, amount)
        local xPlayer = Framework.Functions.GetPlayer(source)
        xPlayer.Functions.RemoveMoney(type, amount) 
    end

    function GetMoneyFunction(source, type)
        local xPlayer = Framework.Functions.GetPlayer(source) 
        return xPlayer.Functions.GetMoney(type) 
    end
    
    function GetIdentifierFunction(source)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.PlayerData.citizenid
    end 

    function AddItemFunction(source, item, amount)
        local xPlayer = Framework.Functions.GetPlayer(source)
        xPlayer.Functions.AddItem(item, amount)
    end

    function RemoveItemFunction(source, item, amount)
        local xPlayer = Framework.Functions.GetPlayer(source)
        xPlayer.Functions.RemoveItem(item, amount)
    end

    function GetPlayerInventoryFunction(source)
        local xPlayer = GetPlayerFromId(source)
        local inventory = xPlayer.PlayerData.items
        local items = {}
        for _, item in pairs(inventory) do
            if item.amount > 0 then
                -- Check if item should be excluded
                local shouldExclude = false
                for _, excludedItem in ipairs(Config.excludedItems) do
                    if item.name:lower() == excludedItem:lower() then
                        shouldExclude = true
                        break
                    end
                end
                
                if not shouldExclude then
                    table.insert(items, {
                        name = item.name,
                        label = item.label,
                        quantity = item.amount,
                        weight = item.weight or 0.0
                    })
                end
            end
        end
        return items
    end

    function GetPlayerItemDataFunction(source, itemName)
        local xPlayer = GetPlayerFromId(source)
        local item = xPlayer.PlayerData.items[itemName]
        if item and item.amount > 0 then
            return {
                name = item.name,
                label = item.label,
                quantity = item.amount,
                weight = item.weight or 0.0
            }
        end
        return nil
    end

    function CanCarryItemFunction(source, itemName, amount)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.Functions.CanCarryItem(itemName, amount)
    end

    function GetPlayerWeightFunction(source)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.PlayerData.metadata["inventoryweight"] or 0
    end

    function GetPlayerMaxWeightFunction(source)
        local xPlayer = GetPlayerFromId(source)
        return xPlayer.PlayerData.metadata["maxweight"] or 120000
    end --]]

    print('Custom framework support is not implemented yet. Please uncomment and modify the custom framework logic above.')
else
    print('Invalid framework specified in Config.lua. Please check your configuration.')
end
framework/client-framework.lua
Framework = nil

if Config['Framework']:upper() == 'ESX' then
    Framework = exports['es_extended']:getSharedObject()
    TriggerServerCallback = Framework.TriggerServerCallback

    -- //Functions\\ --
    function GetPlayerData()
        return Framework.GetPlayerData()
    end

    function GetIdentifierFunction()
        local xPlayer = GetPlayerData()
        return xPlayer.identifier
    end
elseif Config['Framework']:upper() == 'QBCORE' then
    Framework = exports['qb-core']:GetCoreObject()
    TriggerServerCallback = Framework.Functions.TriggerCallback

    -- //Functions\\ --
    function GetPlayerData()
        return Framework.Functions.GetPlayerData()
    end

    function GetIdentifierFunction()
        local xPlayer = GetPlayerData()
        return xPlayer.citizenid
    end
elseif Config['Framework']:upper() == 'QBOX' then
    Framework = exports['qbox-core']:GetCoreObject()
    TriggerServerCallback = Framework.Functions.TriggerCallback

    -- //Functions\\ --
    function GetPlayerData()
        return Framework.Functions.GetPlayerData()
    end

    function GetIdentifierFunction()
        local xPlayer = GetPlayerData()
        return xPlayer.citizenid
    end
elseif Config['Framework']:upper() == 'CUSTOM' then
    -- Uncomment and modify the following lines for your custom framework

    --[[ Framework = exports['your-custom-framework']:GetCoreObject()
    TriggerServerCallback = Framework.Functions.TriggerCallback

    -- //Functions\\ --
    function GetPlayerData()
        return Framework.Functions.GetPlayerData()
    end

    function GetIdentifierFunction()
        local xPlayer = GetPlayerData()
        return xPlayer.citizenid
    end --]]

    print('Custom framework support is not implemented yet. Please uncomment and modify the custom framework logic above.')
else
    print('Invalid framework specified in Config.lua. Please check your configuration.')
end

Last updated