Documentação

Documentação do Clothing store

Uma loja de roupas com outfits salvos, guarda-roupas de empresa e um editor que define os preços do catálogo de dentro do jogo. Todos os componentes e todos os props, comprados peça por peça ou como look inteiro, com um registro no servidor que impede qualquer um de vestir o que não pagou.

  • ESX
  • QBCore
  • vRP
  • Standalone
  • oxmysql
01

Instalação

  1. Coloque o resource

    Baixe o script pela sua conta Tebex, copie a pasta avenida_clotheshops/ para o seu diretório de resources e adicione ensure avenida_clotheshops na config do servidor, depois de ensure oxmysql.

  2. Rode o SQL

    Rode a seção [A] do INSTALL.sql no seu banco. A seção [B] é condicional, o cabeçalho do arquivo diz quando você precisa dela.

  3. Dê as permissões de admin

    Adicione add_ace group.admin avenida_clotheshops.admin allow e add_ace group.admin avenida_clotheshops.vip allow na config do servidor. A primeira abre o editor de catálogo, a segunda libera o que você colocar atrás da lista VIP.

  4. Defina os preços do catálogo de dentro do jogo

    Coloque Config.DevMode.Enabled = true, entre numa loja e abra o editor. Defina preços, esconda o que você não vende, reserve o que pertence a um emprego. Tudo cai em config/clothes_overrides.lua. Desligue o DevMode quando terminar, ele é checado de novo no servidor a cada save.

  5. Verifique as integrações

    Coloque Config.Debug = true, reinicie e leia o console: uma linha por categoria de bridge nomeia o alvo escolhido. Config.Debug só controla os logs, não é a flag do editor.

02

Configuração

Precificar uma seção de três jeitos

Cada loja declara as próprias seções, e cada seção declara o próprio modo de preço. Uma taxa fixa para a seção inteira, um multiplicador que encarece os drawables seguintes, ou uma tabela quando só algumas peças merecem preço próprio.

lua
-- config/clothes_shops.lua
categories = {
    tops = {
        enabled = true,
        price   = { mode = 'fixed', base = 300 },
    },
    pants = {
        enabled = true,
        -- price = base + index * mult
        price   = { mode = 'multiplier', base = 100, mult = 2 },
    },
    mask = {
        enabled = true,
        price   = { mode = 'table', map = { [12] = 900, [45] = 1500 } },
        -- only these drawables are offered
        whitelist = { 12, 45, 51 },
    },
}
03

Exports

Client

  • GetSkinData
    exports['avenida_clotheshops']:GetSkinData()

    A roupa que o jogador usa, componente por componente, props incluídos. É o que a loja escreve na compra, então bate sempre com o que o guarda-roupa mostra.

  • ApplySkin
    exports['avenida_clotheshops']:ApplySkin(data, ped)

    Aplica uma aparência completa num ped. Vestir uma roupa esvazia o slot de decoração, então essa chamada recoloca depois o trabalho da barbearia e da tatuagem em vez de deixar a pele nua.

  • ApplyClothing
    exports['avenida_clotheshops']:ApplyClothing(data, ped, temporary)

    Troca a roupa e mais nada. Com temporary em true a roupa só vale durante a sessão, e é assim que um uniforme entregue por um emprego tem que funcionar.

Server

  • GetBagStorage
    exports['avenida_clotheshops']:GetBagStorage(sex, drawable) --> { weight, slots } | nil

    A capacidade que um drawable de mochila dá, peso e slots, ou nil quando esse drawable não carrega nada. Chame esse export do seu resource de inventário para que uma mochila comprada na loja guarde alguma coisa de verdade.

04

Receitas

Abrir uma loja com imposto e desconto próprios

Uma loja é uma entrada só. Ela carrega o nome de exibição, o meio de pagamento, o símbolo da moeda, um imposto e um desconto opcionais sobre o total do carrinho, e as seções que oferece. Mantenha a chave estável: ela é o id de loja salvo dentro dos outfits, e renomear ela depois que os jogadores já compraram ali quebra os dados deles.

lua
-- config/clothes_shops.lua
Config.Clothes.Shops[22] = {
    name       = 'Ponsonbys - Rockford Hills',
    payment    = 'bank',
    currency   = '$',
    tax        = 0.20,        -- +20% on the cart
    discount   = 0.00,
    outfitMode = true,
    blip = { sprite = 73, color = 4, scale = 0.7, coords = vec3(-708.2, -152.2, 37.4) },
    categories = {
        tops  = { enabled = true, price = { mode = 'fixed', base = 900 } },
        shoes = { enabled = true, price = { mode = 'fixed', base = 450 } },
    },
}

Reservar uma farda para um emprego

Uma peça restrita fica escondida de quem não passa na checagem, então um civil nunca vê a jaqueta da polícia na grade. Os guarda-roupas de empresa vão além: o chefe edita uma lista compartilhada e cada membro veste sem pagar, e é isso que você quer para um recruta no primeiro turno.

lua
-- config/clothes_overrides.lua, or write it from the in-game editor
Overrides['tops'] = {
    [56] = { job = 'police', label = 'LSPD jacket' },
    [12] = { hidden = true },
    [31] = { restricted = true },   -- ACE permission
}

Desligar o registro de propriedade

Ele vem ligado e é o que impede um client adulterado de vestir o catálogo de graça. Desligue só se outro resource seu vestir os jogadores com peças que eles nunca compraram e você preferir não inicializar esses personagens. Os personagens que já existem são inicializados com o que já estão vestindo, então ligar depois não tira nada de ninguém.

lua
-- config/clothes.lua
Config.Clothes.RequireOwnership = false

-- how far from a store the server still accepts a purchase
Config.Clothes.PurchaseRange = 30.0

-- saved outfits per character, enforced server side
Config.Clothes.MaxOutfits = 30
Config.Clothes.MaxOutfitsRestricted = 50

Redesenhar decorações a partir do seu script

Aplicar um outfit completo limpa o slot de decorações do ped, que é compartilhado pelo servidor inteiro. Se o seu script veste um jogador, leia antes o que esse resource possui e devolva depois, senão as tatuagens e a hair base vão embora junto com a mudança.

lua
local hairbase = exports['avenida_clotheshops']:GetHairbase()
local tattoos  = exports['avenida_clotheshops']:GetTattoos()

-- your own clothing work here

if hairbase then
    AddPedDecorationFromHashes(PlayerPedId(), hairbase.c, hairbase.t)
end
for _, dec in ipairs(tattoos) do
    AddPedDecorationFromHashes(PlayerPedId(), dec.c, dec.t)
end
05

Perguntas

Um jogador diz que perdeu roupas que tinha

Confira o Config.Clothes.RequireOwnership. O registro inicializa um personagem com o que ele já está vestindo na primeira vez que o vê, então ligar isso não tira o guarda-roupa de ninguém. O que ele recusa é uma escrita para uma peça sem compra por trás, que é justamente o que um client adulterado manda. Se um resource seu vestir jogadores com peças que eles nunca compraram, registre essas compras ou coloque a flag em false.

O editor de catálogo não abre

Ele precisa de duas coisas ao mesmo tempo: a permissão ACE avenida_clotheshops.admin e Config.DevMode.Enabled = true. Config.Debug é outra flag e só controla os logs. Cada save é checado de novo no servidor, então não adianta só se dar a permissão dentro do jogo.

A mesma jaqueta aparece várias vezes

Isso é o GTA. O jogo repete um drawable em vários índices, e a maioria das lojas lista todos eles. Aqui os drawables fantasma são filtrados, então se você ainda vê uma duplicata, normalmente é um pack de roupa que entrega o mesmo asset duas vezes. Esconda a cópia extra pelo editor no jogo, ela cai em config/clothes_overrides.lua.

O cabelo atravessa um capacete

O corte é declarado por item, então um capacete ou uma máscara que você mesmo adicionou ainda não tem regra. Configure o comportamento do cabelo pelo editor de catálogo, e lembre que existe a preferência do jogador: quem quiser manter o penteado pode dizer isso, e a escolha dele ganha do corte automático.

As fotos de outfit precisam de alguma coisa?

Precisam do screenshot-basic, e só para isso. É a única integração opcional da tabela de requisitos cuja falta o jogador percebe: sem ela os outfits salvos funcionam igualzinho, só que a lista mostra nomes em vez de previews.

Quais frameworks ele realmente suporta?

QBCore, ESX e vRP, mais um modo standalone que não precisa de framework nenhum e um caminho custom em bridges/framework.lua para qualquer outro caso. A detecção roda no start e testa o export real. Qbox e ox_core não têm caminho dedicado: eles passam pelo caminho standalone ou custom, não por um alvo testado.

Posso rodar junto com avenida_barber e avenida_tattoo?

Pode, é para isso que foram feitos. Esse é o mais invasivo dos três, já que aplicar um outfit limpa o slot de decorações, e por isso ele recoloca o que pertence aos outros dois depois de cada mudança. O que não dá é rodar os resources separados e o pacote avenida_skin ao mesmo tempo. O resource detecta a sobreposição e avisa no console no start.

Quanto custa quando ninguém está comprando?

0.00ms. Os pontos de interação compartilham uma thread que passa a rodar de segundo em segundo quando não tem ninguém por perto, os blips são criados uma vez, e toda thread de sessão morre na saída. O debounce de preview só existe enquanto um menu está aberto, e dá para ajustar ele em máquinas mais fracas.

Carrinho
Spirit RP
Discord