> For the complete documentation index, see [llms.txt](https://docs.cuxial.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.cuxial.com/scripts/es/nucleo/cuxial-appearance/developers.md).

# Exports y eventos

API pública de Cuxial Appearance: exports y eventos para leer, aplicar y guardar apariencias desde otros recursos.

Lee el aspecto de un personaje, aplícalo a cualquier ped, abre el creador o un menú y reacciona a las compras desde tus propios recursos.

## Datos de apariencia

Una apariencia es una sola tabla. Todos los exports que reciben o devuelven una apariencia usan estos campos:

| Campo           | Contenido                                                                                                                                                                                                                    |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `model`         | Hash del modelo de ped.                                                                                                                                                                                                      |
| `headBlend`     | Padres y mezcla: `shapeFirst`, `shapeSecond`, `shapeThird`, `skinFirst`, `skinSecond`, `skinThird`, `shapeMix`, `skinMix`, `thirdMix`, `hasParent`.                                                                          |
| `headStructure` | Rasgos de la cara, por nombre. Cada uno tiene `id`, `index` y `value`.                                                                                                                                                       |
| `hairColor`     | `{ color, highlight }`.                                                                                                                                                                                                      |
| `headOverlay`   | Capas (barba, cejas, maquillaje…), por nombre.                                                                                                                                                                               |
| `drawables`     | Componentes por nombre: `face`, `masks`, `hair`, `torsos`, `legs`, `bags`, `shoes`, `neck`, `shirts`, `vest`, `decals`, `jackets`. Cada uno tiene `id`, `index`, `value`, `texture`, `palette`, `collection` y `localIndex`. |
| `props`         | Accesorios por nombre: `hats`, `glasses`, `earrings`, `mouth`, `lhand`, `rhand`, `watches`, `bracelets`. Mismos campos; `value = -1` significa ninguno.                                                                      |
| `tattoos`       | Lista de tatuajes, cuando se usan los tatuajes propios.                                                                                                                                                                      |

«Skin» es la parte del cuerpo (`model`, `headBlend`, `headStructure`, `hairColor`); «clothes» es `drawables`, `props` y `headOverlay`. Un outfit es `{ drawables, props }`.

Los personajes se identifican con el identificador de personaje de tu framework (`citizenid` en QBox y QBCore).

## Exports de cliente

### SetPedAppearance

Aplica una apariencia completa a un ped.

```lua
exports.cuxial_appearance:SetPedAppearance(ped, appearance)
```

| Parámetro    | Tipo   | Descripción          |
| ------------ | ------ | -------------------- |
| `ped`        | number | Handle del ped.      |
| `appearance` | table  | Tabla de apariencia. |

En el ped del propio jugador cambia además el modelo, conserva la vida y el blindaje y aplica los tatuajes. En cualquier otro ped aplica cuerpo, ropa y color de pelo.

{% hint style="warning" %}
El modelo de un ped que no es el jugador no se cambia. Crea ese ped con `appearance.model`.
{% endhint %}

```lua
local appearance = lib.callback.await('myresource:getAppearance', false, citizenid)
local model = appearance.model
lib.requestModel(model)
local ped = CreatePed(4, model, coords.x, coords.y, coords.z, heading, false, true)
exports.cuxial_appearance:SetPedAppearance(ped, appearance)
```

### GetPedAppearance

Lee la apariencia actual de un ped.

```lua
local appearance = exports.cuxial_appearance:GetPedAppearance(ped)
```

**Devuelve:** `table`. La tabla de apariencia sin `tattoos`, más `modelIndex`, `headOverlayTotal`, `drawTotal` y `propTotal` (el número de variaciones disponibles en ese ped).

### SetPlayerPedAppearance

Aplica una apariencia al jugador local.

```lua
exports.cuxial_appearance:SetPlayerPedAppearance(appearance)
```

| Parámetro    | Tipo         | Descripción                                                                                                    |
| ------------ | ------------ | -------------------------------------------------------------------------------------------------------------- |
| `appearance` | table \| nil | Tabla de apariencia. Sin tabla, se carga del servidor la apariencia guardada del personaje actual y se aplica. |

```lua
-- recargar el aspecto guardado, por ejemplo tras una cinemática
exports.cuxial_appearance:SetPlayerPedAppearance()
```

### GetPlayerPedAppearance

Devuelve la apariencia guardada del personaje actual, leída del servidor.

```lua
local appearance = exports.cuxial_appearance:GetPlayerPedAppearance()
```

**Devuelve:** `table | nil`. `nil` cuando el personaje no tiene apariencia guardada.

### PrepareCreator

Pone el modelo freemode del género del personaje y carga por adelantado los datos del menú, para que el creador se abra al instante. Opcional; los datos preparados se usan si se llama a `InitialCreation` en menos de 60 segundos.

```lua
local ready = exports.cuxial_appearance:PrepareCreator()
```

**Devuelve:** `boolean`. `false` cuando ya hay un menú abierto o no se pudieron montar los datos.

### InitialCreation

Abre el creador de personaje y espera hasta que el jugador termina.

```lua
exports.cuxial_appearance:InitialCreation(cb)
```

| Parámetro | Tipo     | Descripción                                     |
| --------- | -------- | ----------------------------------------------- |
| `cb`      | function | Opcional. Se llama cuando el creador se cierra. |

La llamada no vuelve hasta que el creador se cierra, así que ejecútala dentro de un hilo. Mientras el creador está abierto, un personaje sin apariencia guardada pasa a un routing bucket propio y después vuelve al bucket `0`. El creador no se puede cancelar y no se cobra nada. Al final siempre se guarda un aspecto, el de por defecto si hace falta. Si ya hay otro menú abierto, `cb` se llama enseguida.

```lua
CreateThread(function()
    exports.cuxial_appearance:PrepareCreator()
    DoScreenFadeIn(500)
    exports.cuxial_appearance:InitialCreation(function()
        TriggerEvent('myresource:characterReady')
    end)
end)
```

### OpenMenu

Abre un menú de apariencia.

```lua
exports.cuxial_appearance:OpenMenu(menuType)
```

| Parámetro  | Tipo   | Descripción                                                          |
| ---------- | ------ | -------------------------------------------------------------------- |
| `menuType` | string | `'appearance'`, `'clothing'`, `'barber'`, `'surgeon'` u `'outfits'`. |

**Devuelve:** `true` cuando el menú se abrió; `nil` cuando hay otro menú abierto o el tipo no existe.

Guardar se cobra según la tienda en la que esté el jugador. Fuera de una tienda se cobra `prices.outfitPrice`.

```lua
exports.cuxial_appearance:OpenMenu('outfits')
```

### OpenWardrobe

Abre el vestuario, igual que el comando de vestuario.

```lua
exports.cuxial_appearance:OpenWardrobe()
```

### Utilidades de ped

Piezas más pequeñas de la misma API, para cualquier ped.

| Export                | Firma                                                    | Notas                                                                                                           |
| --------------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `GetPedSkin`          | `(ped) → { headBlend, headStructure, hairColor, model }` |                                                                                                                 |
| `GetPedClothes`       | `(ped) → { drawables, props, headOverlay }`              |                                                                                                                 |
| `GetPedDrawables`     | `(ped) → { drawables, totals }`                          | Una lista con dos tablas.                                                                                       |
| `GetPedProps`         | `(ped) → { props, totals }`                              | Una lista con dos tablas.                                                                                       |
| `GetPedHeadOverlay`   | `(ped) → { headOverlay, totals }`                        | Una lista con dos tablas.                                                                                       |
| `GetPedHeadBlend`     | `(ped) → headBlend`                                      |                                                                                                                 |
| `GetPedHeadStructure` | `(ped) → headStructure`                                  |                                                                                                                 |
| `GetPedHairColor`     | `(ped) → { color, highlight }`                           |                                                                                                                 |
| `SetPedSkin`          | `(ped, skin)`                                            | Modelo, mezcla de padres y rasgos de la cara.                                                                   |
| `SetPedClothes`       | `(ped, clothes)`                                         | Drawables, props y capas.                                                                                       |
| `SetPedModel`         | `(ped, model) → ped`                                     | `model` es un nombre, un hash o una tabla con `model`. En el jugador el handle del ped cambia: usa el devuelto. |
| `SetPedDrawable`      | `(ped, { index, value, texture, palette })`              | Devuelve el número de texturas de ese drawable.                                                                 |
| `SetPedProp`          | `(ped, { index, value, texture })`                       | `value = -1` quita el accesorio.                                                                                |
| `SetPedHeadBlend`     | `(ped, headBlend)`                                       | Solo modelos freemode.                                                                                          |
| `SetPedHeadOverlay`   | `(ped, overlay)`                                         |                                                                                                                 |
| `SetPedFaceFeature`   | `(ped, { index, value })`                                |                                                                                                                 |
| `SetPedFaceFeatures`  | `(ped, headStructure)`                                   |                                                                                                                 |
| `SetPedHairColors`    | `(ped, { color, highlight })`                            |                                                                                                                 |

### onClothesApplied / offClothesApplied

Ejecuta una función cada vez que se aplica ropa al jugador local.

```lua
local handle = exports.cuxial_appearance:onClothesApplied(function(ped, index)
    -- index es el componente que cambió, o nil tras un cambio completo
end)

exports.cuxial_appearance:offClothesApplied(handle)
```

**Devuelve:** `number`. Un identificador para quitar la escucha.

### Bolsa de outfits e integración con el inventario

| Export                                                                                                                                      | Qué hace                                                                |
| ------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `PlaceOutfitBag()`                                                                                                                          | Coloca en el suelo la bolsa de outfits que lleva el jugador.            |
| `PickupOutfitBag()`                                                                                                                         | Recoge de nuevo la bolsa colocada.                                      |
| `useClothing(data, slot)`                                                                                                                   | Función de uso del ítem de prenda. Ponla como `client.export` del ítem. |
| `GetWardrobePanel()`, `StripPiece(id, toSlot, toInv)`, `GiveSlot(id, target)`, `WearSlot(slot)`, `StoreAll(inv)`, `WearAllFrom(inv, slots)` | Los usa el panel de ropa del inventario. Solo en modo inventario.       |
| `config()`                                                                                                                                  | Devuelve la tabla de configuración del recurso.                         |

## Exports de servidor

### GetPlayerAppearance

Devuelve la apariencia guardada de un personaje.

```lua
local appearance = exports.cuxial_appearance:GetPlayerAppearance(citizenid)
```

| Parámetro   | Tipo   | Descripción                  |
| ----------- | ------ | ---------------------------- |
| `citizenid` | string | Identificador del personaje. |

**Devuelve:** `table | nil`. La tabla de apariencia con un campo extra `id` (el identificador). `nil` cuando no hay ninguna. Con `compat.legacySkins = true`, antes se importa la skin antigua de ese personaje si existe.

```lua
lib.callback.register('myresource:getAppearance', function(source, citizenid)
    return exports.cuxial_appearance:GetPlayerAppearance(citizenid)
end)
```

### GetPlayerSkin / GetPlayerClothes

Devuelven solo una mitad de la apariencia guardada.

```lua
local skin = exports.cuxial_appearance:GetPlayerSkin(citizenid)
local clothes = exports.cuxial_appearance:GetPlayerClothes(citizenid)
```

**Devuelve:** `table | nil`.

### SavePlayerAppearance

Guarda una apariencia para un personaje. Los campos que faltan conservan su valor guardado.

```lua
local ok = exports.cuxial_appearance:SavePlayerAppearance(citizenid, appearance)
```

| Parámetro    | Tipo   | Descripción                              |
| ------------ | ------ | ---------------------------------------- |
| `citizenid`  | string | Identificador del personaje.             |
| `appearance` | table  | Tabla de apariencia, completa o parcial. |

**Devuelve:** `boolean`. `false` cuando los datos no son válidos. No se cobra nada y no se aplica ninguna restricción de modelo.

{% hint style="info" %}
Esto solo escribe en la base de datos. Para actualizar a un jugador conectado, dispárale después `cuxial_appearance:client:reloadSkin`.
{% endhint %}

### SavePlayerSkin / SavePlayerClothes

Guardan una mitad de la apariencia y la sustituyen entera.

```lua
exports.cuxial_appearance:SavePlayerSkin(citizenid, skin)
exports.cuxial_appearance:SavePlayerClothes(citizenid, clothes)
```

**Devuelve:** `boolean`.

### Outfits

| Export         | Firma                                             | Notas                                                                                                                           |
| -------------- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `GetOutfits`   | `(source, citizenid) → outfit[]`                  | Outfits personales más los de trabajo que permite el rango del jugador. Cada entrada tiene `id`, `label`, `outfit` y `jobname`. |
| `SaveOutfit`   | `(source, { label, outfit, job? }) → id \| false` | `job = { name, rank }` lo convierte en outfit de trabajo. No se cobra nada ni se comprueba el límite de outfits.                |
| `RenameOutfit` | `(source, { id, label }) → number`                | Filas modificadas.                                                                                                              |
| `UpdateOutfit` | `(source, { id, outfit }) → boolean`              |                                                                                                                                 |
| `DeleteOutfit` | `(source, id) → boolean`                          |                                                                                                                                 |

Los outfits pertenecen siempre al personaje de `source`.

```lua
local id = exports.cuxial_appearance:SaveOutfit(source, {
    label = 'Uniforme de patrulla',
    outfit = { drawables = drawables, props = props },
})
```

### Registro corporal

Solo en modo inventario.

| Export        | Firma                                                        | Notas                                                                                                                                          |
| ------------- | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `SearchPanel` | `(target) → table[] \| false`                                | Piezas de `wardrobe.search.pieces` de ese jugador: `piece`, `label`, `worn`, y `drawable`, `texture`, `image` cuando la lleva puesta.          |
| `SearchStrip` | `(source, target, piece, toSlot?) → { ok, reason?, panel? }` | Quita a `target` una pieza puesta y se la da a `source` como ítem. `reason` es un código corto como `protected`, `not_worn`, `full` o `error`. |

### Apariencias aleatorias

| Export                  | Firma                               | Notas                                                                                        |
| ----------------------- | ----------------------------------- | -------------------------------------------------------------------------------------------- |
| `GetRandomAppearances`  | `(count) → { model, appearance }[]` | Aspectos de personajes reales, para vestir NPC. Se repiten cuando `count` supera la reserva. |
| `RefreshAppearancePool` | `() → boolean`                      | Reconstruye la reserva desde la base de datos.                                               |

### getSetting

Devuelve un bloque de ajustes en vivo, tal como se editan desde el panel de staff.

```lua
local prices = exports.cuxial_appearance:getSetting('config.prices')
```

| Parámetro | Tipo   | Descripción                                                                                        |
| --------- | ------ | -------------------------------------------------------------------------------------------------- |
| `id`      | string | `'config.prices'`, `'config.wardrobe'`, `'config.secondHand'`, `'config.trimmer'` o `'config.ui'`. |

**Devuelve:** `table | nil`.

### Hooks

Ejecutan una función cuando ocurre algo en el servidor. Hay un export por grupo.

```lua
exports.cuxial_appearance:onShop('purchased', function(source, shop, price)
    print(('%s pagó %d'):format(GetPlayerName(source), price))
end)
```

| Export         | Evento      | Argumentos                                                                             |
| -------------- | ----------- | -------------------------------------------------------------------------------------- |
| `onAppearance` | `saved`     | `citizenid, appearance`                                                                |
| `onOutfit`     | `saved`     | `source, citizenid, id, label`                                                         |
| `onOutfit`     | `used`      | `source, citizenid, outfit` (se usó un ítem de outfit)                                 |
| `onOutfit`     | `deleted`   | `source, citizenid, id`                                                                |
| `onWardrobe`   | `stripped`  | `source, piece`                                                                        |
| `onWardrobe`   | `worn`      | `source, piece`                                                                        |
| `onWardrobe`   | `searched`  | `by, target, piece, kind` (`kind`: `search`, `give` o `admin`)                         |
| `onWardrobe`   | `trimmed`   | `source, target`                                                                       |
| `onWardrobe`   | `resold`    | `source, shop, sold, total`                                                            |
| `onShop`       | `purchased` | `source, shop, price`. `shop` es `nil` fuera de una tienda. Solo cuando se cobró algo. |
| `onShop`       | `changed`   | ninguno. Se editó la lista de tiendas.                                                 |

## Eventos

### Eventos de cliente

Dispáralos desde el servidor sobre un jugador.

| Evento                                   | Parámetros        | Qué hace                                      |
| ---------------------------------------- | ----------------- | --------------------------------------------- |
| `cuxial_appearance:client:open`          | `menuType`        | Abre un menú. Mismos valores que `OpenMenu`.  |
| `cuxial_appearance:client:reloadSkin`    | ninguno           | Recarga la apariencia guardada del personaje. |
| `qb-clothing:client:loadPlayerClothing`  | `appearance, ped` | Aplica una apariencia a un ped.               |
| `qb-clothes:client:CreateFirstCharacter` | ninguno           | Abre el creador.                              |
| `qb-clothing:client:openOutfitMenu`      | ninguno           | Abre el menú de outfits.                      |

```lua
TriggerClientEvent('cuxial_appearance:client:open', source, 'barber')
```

### Eventos locales

Escúchalos con `AddEventHandler`.

| Evento                                    | Lado     | Parámetros   | Cuándo                               |
| ----------------------------------------- | -------- | ------------ | ------------------------------------ |
| `cuxial_appearance:client:clothesApplied` | Cliente  | `ped, index` | Se aplicó ropa al jugador local.     |
| `cuxial_appearance:client:menuClosed`     | Cliente  | ninguno      | Se cerró un menú de apariencia.      |
| `cuxial_appearance:settingsApplied`       | Ambos    | `id`         | Cambió un bloque de ajustes en vivo. |
| `cuxial_appearance:server:dbReady`        | Servidor | ninguno      | Las tablas están listas.             |

```lua
AddEventHandler('cuxial_appearance:client:clothesApplied', function(ped, index)
    exports.cuxial_chat:refreshMask()
end)
```

### State bag

Una bolsa de outfits colocada lleva el estado de entidad `cuxialOutfitBag`, con el id de servidor de su dueño en `owner`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.cuxial.com/scripts/es/nucleo/cuxial-appearance/developers.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
