iLLeniumStudios / illenium-appearance

fivem-appearance for qb-core and ESX framework, packed with a lot of features
MIT License
248 stars 222 forks source link

Feat Request: Clothing Metadata support #406

Open MrMallenby opened 6 months ago

MrMallenby commented 6 months ago

Hi there i was wondering if it would be possible to have a clothing metadata function added to the script as to work with the clothes as items scripts that are knocking around these days, such as the clothes as item system in the c8re inventory & clothing scripts which rely on being fed meta data when the clothes are purchased

blugthek commented 3 weeks ago

i just make an handler

On illenium side

client.startPlayerCustomization(function(appearance)
        if (appearance) then
            ...
            TriggerEvent('BX:appearanceBridge', appearance.components) -- add this line
            TriggerEvent('BX:appearanceBridge', appearance.props) -- add this line
            ...
        end
    end, config)

client

RegisterNetEvent('BX:appearanceBridge')
    AddEventHandler('BX:appearanceBridge', function(dataArgs)
        local skin = {}
        local newTable = {}
        local newTorso = 4
        for k, v in pairs(dataArgs) do
            if v.component_id then
                if v.component_id == 3 then
                    newTorso = v.drawable
                end
                v.permanent = true
                newTable[v.component_id] = v
            end
            if v.prop_id then
                v.permanent = true
                newTable[v.prop_id] = v
            end
        end
        for k in sPairs(newTable) do
            skin[#skin + 1] = k
        end
        for k, v in pairs(dataArgs) do
            for j, o in pairs(v) do
                print(("[%s] : %s = %s"):format(k, j, o))
            end
            if v.component_id == 11 then
                v.torso = newTorso
            end
            ClothesCreation(v)
        end
    end)

    local clothingMappings = {
        [1] = { name = 'mask', components = { mID = 1, wID = 1 } },
        [3] = { name = 'arm', components = { mID = 1, wID = 1 } },
        [4] = { name = 'pants', components = { mID = 4, wID = 4 } },
        [5] = { name = 'backpacks', components = { mID = 5, wID = 5 } },
        [6] = { name = 'shoes', components = { mID = 6, wID = 6 } },
        [7] = { name = 'accessory', components = { mID = 7, wID = 7 } },
        [8] = { name = 'tshirt', components = { mID = 8, wID = 8 } },
        [9] = { name = 'bodyarmor', components = { mID = 9, wID = 9 } },
        [10] = { name = 'badge', components = { mID = 10, wID = 10 } },
        [11] = { name = 'torso', components = { mID = 11, wID = 11 } }
    }

    local accessoryMappings = {
        [0] = { name = 'hat', components = { mPropID = 0, wPropID = 0 } },
        [1] = { name = 'glass', components = { mPropID = 1, wPropID = 1 } },
        [2] = { name = 'ear', components = { mPropID = 2, wPropID = 2 } },
        [6] = { name = 'watch', components = { mPropID = 6, wPropID = 6 } },
        [7] = { name = 'bracelet', components = { mPropID = 7, wPropID = 7 } },
    }

    local armHandlers = {}

    RegisterNetEvent('BX:skinBridge')
    AddEventHandler('BX:skinBridge', function(dataArgs)
        ClothesCreation(dataArgs)
    end)

    function ClothesCreation(dataArgs)
        -- Check if dataArgs is nil
        if not dataArgs then
            return
        end

        local clothingInfo, accessoryInfo

        -- Check if component_id exists in dataArgs
        if dataArgs.component_id then
            clothingInfo = clothingMappings[dataArgs.component_id]

            -- Handle 'arm' case
            if clothingInfo and clothingInfo.name == 'arm' then
                armHandlers.torso = dataArgs.model or dataArgs.drawable or 4
                return
            end
        end

        -- Check if prop_id exists in dataArgs
        if dataArgs.prop_id then
            accessoryInfo = accessoryMappings[dataArgs.prop_id]
        end

        -- Handle clothing case
        if clothingInfo then
            print("FOUND CLOTHES")
            local metadata = {
                mModel = dataArgs.model or dataArgs.drawable,
                mTexture = dataArgs.texture,
                wModel = dataArgs.model or dataArgs.drawable,
                wTexture = dataArgs.texture
            }

            if dataArgs.component_id == 11 then
                metadata.mTorso = dataArgs.torso or armHandlers.torso or dataArgs.model or dataArgs.drawable
                metadata.wTorso = dataArgs.torso or armHandlers.torso or dataArgs.model or dataArgs.drawable
            end

            for key, value in pairs(clothingInfo.components) do
                metadata[key] = value
            end

            TriggerServerEvent('BX:server:addClothesTemp', {
                name = clothingInfo.name,
                count = 1,
                metadata = metadata
            })

            return
        end

        -- Handle accessory case
        if accessoryInfo then
            print("FOUND ACCESSORY")
            local metadata = {
                mPropModel = dataArgs.model or dataArgs.drawable,
                mPropTexture = dataArgs.texture,
                wPropModel = dataArgs.model or dataArgs.drawable,
                wPropTexture = dataArgs.texture
            }

            for key, value in pairs(accessoryInfo.components) do
                metadata[key] = value
            end

            TriggerServerEvent('BX:server:addClothesTemp', {
                name = accessoryInfo.name,
                count = 1,
                metadata = metadata
            })

            return
        end
    end

Server

RegisterServerEvent('BX:server:addClothesTemp')
    AddEventHandler('BX:server:addClothesTemp', function(data)
        local _source = source;
        local xPlayer = ESX.GetPlayerFromId(_source)
        local name, count, metadata
        local IDC = xPlayer.identifier
        IDC = IDC:sub(#IDC - 4, #IDC)
        local serialNumber = genSerial(IDC)

        if data ~= nil then
            name = data.name or 'blank'
            count = data.count or 0
            metadata = data.metadata or {}
        end

        if not data.permanent then
            metadata.serial = serialNumber
            metadata.workClothes = true
            tClothesData[serialNumber] = 1
        end

        if name == 'blank' and count <= 0 or not ESX.Items[name] then
            print('^0[ERROR] Something is wrong',name)
            return false
        end

        local inventory = 'content-' .. xPlayer.coreIdentity
        local aI
        --aI = exports['core_inventory']:addItem(inventory, name, count, metadata, 'content')
        xPlayer.xpcall(function()
            aI = exports['core_inventory']:addItem(inventory, name, count, metadata, 'content')
        end)
        if not aI then
            print('SUM TING WONG')
        end
    end)
modify as you see fit, my code is very clunky but i am too lazy to fix it.
Hope this might help.