> ## Documentation Index
> Fetch the complete documentation index at: https://docs.fivenetwork.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# five-bennys

> Oficina de tunagem (estilo Benny's) para vRP. Jogadores e mecânicos modificam visual e performance dos veículos via NUI em React, com orçamentos, múltiplas oficinas, pintura, neon, som de motor e reparo. Persistência por placa + modelo.

O **five-bennys** é um menu de customização acessível por marcadores no mundo ou por comandos. As modificações são salvas por **placa + modelo** em `five_bennys_tuning` e reaplicadas pelo `five-vehicles` (ou pelo seu sistema de garagem) ao tirar o veículo da garagem.

<Info>
  Esta é uma visão geral. Para os detalhes completos, veja as páginas dedicadas: [Apresentação](/five-bennys/apresentacao), [Instalação](/five-bennys/instalacao), [Configuração](/five-bennys/configuracao), [Exports](/five-bennys/api/exports) e [Eventos](/five-bennys/api/eventos).
</Info>

## Funcionalidades

<CardGroup cols={2}>
  <Card title="Tunagem direta" icon="wrench">
    Cliente paga e aplica na hora (quando não há mecânicos e `TuningCarIfNotMechanics = true`, ou `OnlyMechanic = false`).
  </Card>

  <Card title="Orçamentos (mecânico)" icon="file-invoice-dollar">
    Cliente envia pedido → mecânico aceita, cobra, instala cada peça e finaliza, recebendo uma porcentagem.
  </Card>

  <Card title="Múltiplas oficinas" icon="warehouse">
    Quantas oficinas quiser em `Bennys.Mechanics`, cada uma com tipo de serviço, permissão de acesso e de trabalho.
  </Card>

  <Card title="Modo admin" icon="user-shield">
    `/bennys` aplica as modificações direto no veículo, sem orçamento nem custo.
  </Card>
</CardGroup>

<Note>
  **Interação com five-vehicles:** quando `five-bennys` está `started`, a mecânica nativa do `five-vehicles` é desativada. Ao spawnar veículos, o `five-vehicles` verifica `exports["five-bennys"]:HasTuning(plate)` e, havendo tunagem, chama `ApplyStoredTuning`.
</Note>

***

## Dependências

<CardGroup cols={2}>
  <Card title="vrp" icon="layer-group">
    Framework base (`@vrp/lib/utils.lua`, `@vrp/config/Global.lua`, `exports.vrp:Avatar(...)`). Trocável adaptando os dois `framework.lua`.
  </Card>

  <Card title="oxmysql" icon="database">
    Acesso ao banco de dados (`@oxmysql/lib/MySQL.lua`).
  </Card>
</CardGroup>

***

## Configuração

Arquivos em `config/`: `config.lua` (identidade, acesso, regras, oficinas), `language.lua` (textos), `mods.lua` (catálogo), `prices.lua` (preços) e `engines.lua` (sons de motor). Detalhes na página de [Configuração](/five-bennys/configuracao).

<AccordionGroup>
  <Accordion title="config/config.lua — Regras e permissões" icon="sliders">
    ```lua theme={null}
    Bennys.MinMechanics            = 1     -- mín. de mecânicos online p/ liberar o orçamento
    Bennys.OnlyOwner               = false -- só o dono da placa pode tunar
    Bennys.OnlyMechanic            = false -- só quem trabalha na oficina usa o menu
    Bennys.TuningCarIfNotMechanics = true  -- sem mecânico, cliente tuna pagando na hora
    Bennys.PercentageMechanic      = 70    -- % do valor que o mecânico recebe

    Bennys.TimeInstallMod    = 10  -- tempo (s) p/ instalar cada peça
    Bennys.RequestRepairTime = 30  -- cooldown (s) entre reparos
    Bennys.TimeRepairMotor   = 5   -- tempo (s) do reparo de motor

    -- Permissões GLOBAIS. As permissões POR OFICINA ficam em Bennys.Mechanics.
    Bennys.Permissions = {
        Admin = "Admin",  -- exigido pelo /bennys (exige grupo nível >= 2)
    }

    Bennys.Commands = {
        OpenBennys      = "bennys",   -- admin: tunagem direta
        OpenBudgetPanel = "pedidos",  -- mecânico: serviço em andamento ou orçamentos
    }
    ```
  </Accordion>

  <Accordion title="config/config.lua — Oficinas" icon="map-pin">
    `Bennys.Marker` define o estilo do marcador (compartilhado). Cada entrada de `Bennys.Mechanics` é uma oficina — duplique para criar mais.

    ```lua theme={null}
    Bennys.Mechanics = {
        ["motorworks"] = {
            Label            = "Benny's Motorworks",
            Type             = "allCustoms",   -- allCustoms | customization | performance
            AccessPermission = false,          -- quem ABRE o balcão (false = público)
            WorkPermission   = "Bennys",       -- quem TRABALHA como mecânico aqui
            Coords = { vector3(-213.95, -1348.08, 31.54), --[[ ... ]] },
        },
    }
    ```

    <Note>
      O `Type` da oficina define o modo (`MechanicType`): `allCustoms` (tudo), `customization` (só visual) ou `performance` (só performance). No padrão vêm 3 oficinas: **Benny's Motorworks**, **North Sport** e **Siatlle Customs**.
    </Note>
  </Accordion>

  <Accordion title="config/mods.lua — Catálogo e desativar tunagens" icon="list">
    `Bennys.Mods` define o catálogo (`modTypes` 0–49, cores, neon, níveis, camaleão em primária/secundária). Para **desligar uma tunagem globalmente**, adicione `enabled = false` na entrada da categoria — ela some do menu e o servidor recusa aplicá-la (`Bennys.IsCategoryEnabled`).
  </Accordion>

  <Accordion title="config/prices.lua e engines.lua" icon="money-bill">
    `Bennys.Prices`: `initialPrice` (taxa fixa), `repairPrice` e o preço por categoria (`price + increaseBy * nível`, item opcional). `Bennys.EngineSounds` lista os sons (`name`, `model`, `price`); os `model` precisam existir como banks de áudio no servidor.
  </Accordion>
</AccordionGroup>

***

## Comandos

| Comando         | Config                            | Permissão                   | Descrição                                                                                           |
| --------------- | --------------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------- |
| `/bennys`       | `Bennys.Commands.OpenBennys`      | `Admin` (nível >= 2)        | Abre a tunagem e aplica **direto** no veículo (sem orçamento nem custo). Exige estar em um veículo. |
| `/pedidos`      | `Bennys.Commands.OpenBudgetPanel` | Mecânico (`WorkPermission`) | Abre o **serviço em andamento** ou, se não houver, a lista de **orçamentos**.                       |
| `convertBennys` | —                                 | Console                     | Migra tunagens antigas de `entitydata` para a tabela nova (execução única).                         |

***

## Exports

Server-side, para o seu sistema de veículos reaplicar a tunagem salva no spawn. Detalhes em [Exports](/five-bennys/api/exports).

```lua theme={null}
-- existe tunagem salva? (model é opcional; sem ele, true p/ qualquer modelo da placa)
exports["five-bennys"]:HasTuning(plate, model)

-- reaplica a customização COMPLETA (incl. som de motor) e sincroniza p/ todos os clients.
-- casa o modelo do veículo com o salvo; com 1 tunagem na placa, aplica mesmo sem casar.
exports["five-bennys"]:ApplyStoredTuning(netVehId, plate)

-- som de motor salvo (interface do resource)
Core.GetStoredEngineSound(plate, model)
```

<Note>
  O `ApplyStoredTuning` já restaura o **som de motor** junto com o resto — **não** é preciso disparar `five-bennys:syncEngineSound` no spawn.
</Note>

```lua theme={null}
-- integração típica no spawn (garagem/aluguel/admin)
if networkVehicle then
    local hasBennys = GetResourceState("five-bennys") == "started"
        and exports["five-bennys"]:HasTuning(plate)

    -- se o Bennys tem a tunagem, não aplique os mods legados do seu sistema:
    setupVehicle(networkVehicle, hasBennys and {} or mods, health, damages)

    if hasBennys then
        exports["five-bennys"]:ApplyStoredTuning(networkVehicle, plate)
    end
end
```

***

## Banco de Dados

Criada automaticamente. Cada tunagem é única por **placa + modelo** (bancos antigos com PK só na `plate` são migrados no boot).

```sql theme={null}
five_bennys_tuning ( plate, model, passport, custom (LONGTEXT JSON), PRIMARY KEY (plate, model) )
```

***

## Customização

* **Grupo da oficina:** `WorkPermission`/`AccessPermission` por entrada em `Bennys.Mechanics`; `Bennys.Permissions.Admin` para o `/bennys`.
* **Modo de operação:** combine `OnlyMechanic`, `TuningCarIfNotMechanics`, `MinMechanics`, `OnlyOwner`.
* **Tipo de serviço:** campo `Type` de cada oficina (`allCustoms`/`customization`/`performance`).
* **Desativar tunagens:** `enabled = false` na categoria em `config/mods.lua`.
* **Preços:** `config/prices.lua` (`initialPrice`, `repairPrice`, categorias).
* **Sons de motor:** `Bennys.EngineSounds` (+ banks de áudio).
* **Outra base (ESX/QB/…):** adapte a tabela `Framework` em `server/framework.lua` e `client/framework.lua`.
