Documentação

Documentação do Barber shop

Uma barbearia encenada de ponta a ponta, com uma câmera que o jogador controla de verdade. O personagem entra, senta na cadeira, e o barbeiro começa a trabalhar enquanto uma câmera orbital enquadra a cabeça. Cabelo, barba, overlays e todo o conjunto de detalhes de pele, com preview em tempo real antes de você gastar um dólar.

  • ESX
  • QBCore
  • vRP
  • Standalone
  • oxmysql
01

Instalação

  1. Coloque o resource

    Baixe o script pela sua conta Tebex, copie a pasta avenida_barber/ para o seu diretório de resources e adicione ensure avenida_barber 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. Confira a config

    Abra config/config.lua. Os padrões funcionam na maioria dos servidores, a única linha que vale olhar é Config.Locale. Preços, lojas e comportamento da cadeira ficam no arquivo do lado, config/barber.lua.

  4. Verifique as integrações

    Coloque Config.Debug = true, reinicie e leia o console: uma linha por categoria de bridge nomeia o alvo escolhido. Volte para false quando as linhas baterem com o seu servidor, os comandos de diagnóstico que ele libera custam um engasgo no frame.

  5. Libere os poderes de admin para você

    Adicione add_ace group.admin avenida_barber.admin allow na config do servidor e depois rode /avenida_barber_check no jogo para o relatório completo.

02

Configuração

Forçar uma integração em vez de detectar

A detecção automática cobre a maioria dos servidores, e ela testa o export real em vez do estado do resource. Numa stack customizada, force o alvo e a detecção é pulada por completo.

lua
-- config/config.lua
Config.Locale    = 'en'
Config.UseOxLib  = true

Config.Framework = 'auto'   -- 'qbcore' | 'esx' | 'vrp' | 'standalone' | 'custom'
Config.Notif     = 'ox_lib' -- 'qbcore' | 'esx' | 'ox_lib' | 'okok' | 'vrp' | 'chat' | 'custom'
Config.Interact  = 'auto'   -- 'avenida' | 'ox_target' | 'qb-target' | 'standalone' | 'custom'
Config.Clothing  = 'auto'   -- 'qb' | 'illenium' | 'fivem-appearance' | 'esx_skin' | 'vrp' | 'table' | 'custom'

Config.Camera = {
    Sensitivity = 1.0,      -- rotation, zoom and height, clamped to 0.1 - 5.0
    InvertY     = false,
}
03

Exports

Client

  • GetHairbase
    exports['avenida_barber']:GetHairbase() --> { c = collection, t = nameHash } | nil

    A hairbase que o ped usa neste momento, ou nil quando o corte não precisa de nenhuma. Leia ela antes de chamar ClearPedDecorations e devolva depois: assim o cabelo mantém o sombreado em vez de virar um capacete liso.

  • GetTattoos
    exports['avenida_barber']:GetTattoos() --> { { c, t }, ... }

    Todas as tatuagens que este resource mantém no ped. A barbearia compartilha o único slot de decoração com a tinta, então um redraw que esquece essa lista apaga tatuagens que o jogador pagou.

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

    O personagem do jeito que a barbearia guarda ele na memória, com cabelo, barba, sobrancelhas e as cores de cada um. Útil para guardar o visual antes de um uniforme de trabalho tomar o lugar dele.

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

    Escreve uma aparência completa num ped. Passe o ped que você quer vestir, que pode ser um clone de preview em vez do jogador, para um espelho ou uma tela de seleção de personagem mostrar o mesmo rosto.

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

    Aplica só a parte de roupas e deixa o rosto e o cabelo intactos. Coloque temporary como true para uma roupa que não deve ir para o banco, tipo um uniforme de presidiário ou um disfarce.

04

Receitas

Ajustar a câmera e o visual da cena

A câmera gira em torno da cabeça, então os mesmos valores de altura servem em pé ou sentado. Valor negativo de altura desce pelo corpo. A iluminação e a profundidade de campo são o que faz o personagem virar o assunto da cena, e não um ped num cômodo escuro.

lua
-- config/config.lua
Config.Camera = {
    Sensitivity = 1.4,          -- faster drag
    InvertY     = true,
}

Config.UI = {
    Tutorial          = true,   -- first-run tour, replayable from the toolbar
    Sounds            = true,
    Blips             = true,

    Timecycle         = 'casino_brightroom',
    TimecycleStrength = 1.0,
    TimecycleFadeMs   = 400,    -- 0 makes it snap like a light switch

    DofStrength       = 0.1,    -- false drops the per-frame SetUseHiDof call
    DofPlanes         = { 0.4, 0.7, 2.2, 4.5 },
}

Adicionar uma loja, ou tirar a encenação

As lojas ficam num arquivo aberto, uma entrada cada, cada uma com o seu barbeiro e os seus preços. Desligar a cena da cadeira mantém a câmera e o menu, e só pula a parte de entrar andando.

lua
-- config/barber.lua
Config.Barber.ChairScene = false   -- menu opens on the spot

Config.Barber.Shops[9] = {
    BarberPedModel = 's_m_m_hairdress_01',
    Welcome        = vec3(-1282.60, -1116.60, 6.99),
    Blip           = { sprite = 71, color = 4, scale = 0.7 },
}

Redesenhar decorações a partir do seu script

O ped tem um único slot de decorações para o servidor inteiro. Se o seu script chama ClearPedDecorations, leia antes o que este resource possui e devolva depois, senão você apaga a hair base.

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

ClearPedDecorations(PlayerPedId())
-- your own decoration 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

Esconder o seu HUD enquanto uma loja está aberta

O resource dispara um evento de client ao abrir e fechar um menu. Escute esse evento em vez de ficar checando num loop, é o mesmo sinal que o tratamento interno de HUD usa.

lua
AddEventHandler('avenida_barber:client:uiStateChanged', function(hidden)
    if hidden then
        exports['myhud']:hide()
    else
        exports['myhud']:show()
    end
end)
05

Perguntas

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.

O que o vRP me custa?

O vRP salva componentes de roupa e props, e nada mais. Ele não tem campo para overlays de cabeça, traços do rosto, cor de cabelo, cor de olhos nem decorações de ped, então no vRP o personagem inteiro fica na tabela do próprio resource. O vRP continua recebendo a parte de roupas, atualizada logo depois de cada mudança. Consequência prática: um skinshop nativo do vRP não vai mostrar o trabalho do barbeiro, porque o vRP não tem onde guardar isso. vRP 2 e vRP 0.5 não são suportados, e o resource avisa no console em vez de dar problema em silêncio.

Funciona com a stack ox?

Funciona, onde importa: ox_lib para as notificações via Config.UseOxLib, ox_target para o prompt de interação, ox_inventory para os itens de roupa, e o oxmysql como única dependência de verdade. Fora ele, nada disso é obrigatório, e o bridges/compat.lua entrega os fallbacks em natives quando o ox_lib está desligado. O que não tem caminho dedicado é o ox_core como framework: num servidor ox_core o resource roda em standalone, ou pelo caminho custom de bridges/framework.lua se você quiser que ele leia os dados do seu jogador.

Posso rodar junto com avenida_tattoo e avenida_clotheshops?

Pode, é para isso que foram feitos. Cada um é dono da sua metade do único slot de decorações do ped e recoloca os outros depois de cada redraw. O que não dá é rodar os resources separados e o pacote avenida_skin ao mesmo tempo: cada um colocaria o próprio blip e escreveria a própria cópia do mesmo personagem. O resource detecta a sobreposição e avisa no console no start.

Falta um corte de cabelo na lista

As hair bases são filtradas pela build do jogo. Um estilo que o seu cliente não consegue renderizar nunca é listado, de propósito: se ele aparecesse, o jogador escolheria uma opção que sai quebrada. Rode /avenida_barber_check para ver a build que o seu servidor realmente roda.

A cabeça não segue o meu cursor

O head tracking é preso a uma sessão de câmera orbital: a thread começa com a câmera e termina com ela. Ele também precisa de foco NUI, já que lê o cursor pelo GetNuiCursorPosition. Se outro resource tomou conta da câmera, o tracking fica desligado de propósito.

Posso adicionar outro idioma?

Quinze vêm preenchidos, na pasta aberta locales/. Copie um arquivo, traduza os valores e aponte Config.Locale para o seu novo código de idioma. en.lua é o fallback de qualquer chave que você deixar de fora, então um arquivo parcial nunca mostra um rótulo vazio.

Quanto custa quando não tem ninguém na loja?

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. Entre um corte e outro, não roda nada.

Carrinho
Spirit RP
Discord