> For the complete documentation index, see [llms.txt](https://visionstore.gitbook.io/visionstore-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://visionstore.gitbook.io/visionstore-docs/scripts/advanced-clothing/developers/integration-examples.md).

# Integration examples

Ready-to-use examples for housing, multicharacter, job lockers, admin menus and custom chairs.

{% tabs %}
{% tab title="Housing wardrobe" %}

### Housing: wardrobe inside a house

```lua
-- client side of your housing resource, when the player enters a house
local wardrobeZone = exports.ox_target:addBoxZone({
    coords = houseWardrobeCoords,          -- vector3 inside the interior
    size = vec3(1.5, 1.0, 2.0),
    rotation = 0,
    options = {
        {
            name = "house_wardrobe",
            icon = "fas fa-tshirt",
            label = "Open Wardrobe",
            onSelect = function()
                exports.Chapo_advanced_clothing:OpenWardrobe({
                    mode = "home",
                    title = "MY WARDROBE",
                })
            end,
        },
    },
})

-- when leaving the house
exports.ox_target:removeZone(wardrobeZone)
```

`mode = "home"`: no checkout, save / share / import on, equipping is saved right away. No `Config.Wardrobes` entry is needed.
{% endtab %}

{% tab title="Multicharacter" %}

### Multicharacter: character creator

**With the illenium guards** ([illenium-appearance setup](/visionstore-docs/scripts/advanced-clothing/illenium-setup.md), step 3) nothing changes in your multicharacter: whatever it uses to create a character ends in illenium's `InitializeCharacter()`, which hands the creator to Vision Clothing, and your own `onSubmit` / `onCancel` run as before.

**Without the guards**, or from a script of your own:

```lua
-- before:  TriggerEvent("qb-clothes:client:CreateFirstCharacter")
TriggerEvent("Chapo_advanced_clothing:client:openCharacterCreator", {})

-- continue your spawn flow when the player is done
AddEventHandler("Chapo_advanced_clothing:client:characterCreated", function(appearance)
    print("character finished as " .. tostring(appearance and appearance.model))
    -- teleport / fade in / hand over to your spawn manager here
end)

-- optional: the creator closed without saving (only possible with allowCancel, death or a forced close)
AddEventHandler("Chapo_advanced_clothing:client:sessionClosed", function(mode, reason)
    if mode == "character_creator" and reason ~= "confirm" then
        -- send the player back to the character selection
    end
end)
```

The creator refuses ESC by default, so the player can't skip it. The appearance is already saved through illenium when `characterCreated` fires.
{% endtab %}

{% tab title="Job locker" %}

### Job script: locker room

Reuse a configured wardrobe (restrictions, label and distance check come from `Config.Wardrobes`):

```lua
exports.Chapo_advanced_clothing:OpenJobWardrobe({ wardrobeId = "police_locker" })
```

Or open a locker from your own interaction. Do your own job check first: without a `wardrobeId` the server only checks that the player is loaded.

```lua
local job = QBCore.Functions.GetPlayerData().job   -- or your framework's equivalent
if job.name == "police" then
    exports.Chapo_advanced_clothing:OpenJobWardrobe({
        title = job.label:upper() .. " LOCKER",
        allowSaving = false,
    })
end
```

The outfits shown are `Config.JobOutfits[<player job>]` filtered by grade, plus illenium's boss-managed outfits.
{% endtab %}

{% tab title="Admin menu" %}

### Admin menu: open the clothing menu on a player

```lua
-- server side of your admin resource
RegisterNetEvent("myadmin:server:clothing", function(targetId)
    local src = source
    -- IsPlayerAceAllowed does not match a principal name such as "group.admin";
    -- ox_lib grants the restricted group the "command.clothingshop" ace, so check that
    if not IsPlayerAceAllowed(src, "command.clothingshop") then return end
    ExecuteCommand(("clothingshop %d"):format(targetId))   -- console context: grants + opens on the target
end)
```

Going through the command gives the target the 60-second grant, so they don't need the ace themselves.
{% endtab %}

{% tab title="Custom chair" %}

### Custom barber chair, tattoo bench or doctor

Any interaction can open a typed context without a `Config.Shops` entry. Without an entry there is no distance check, so do your own.

```lua
exports.Chapo_advanced_clothing:OpenBarber({ title = "MOBILE STYLIST" })                 -- charges the barber profile
exports.Chapo_advanced_clothing:OpenBarber({ title = "FREE TRIM", pricingProfile = false })
exports.Chapo_advanced_clothing:OpenTattooShop({ title = "BACK ROOM", pricingProfile = "tattoos" })

-- A doctor NPC that only allows face adjustments
exports.Chapo_advanced_clothing:OpenAppearance({
    mode = "surgeon",
    sections = { "face_adjustments" },
    title = "PILLBOX SURGERY",
})
```

The server re-resolves the sections and the pricing profile from the mode / entry when the menu opens, so a client can't ask for a free surgeon by passing `pricingProfile = false` on a real surgeon entry.
{% endtab %}

{% tab title="Give a ped" %}

### Another resource: give a character a ped

```lua
-- server side of your resource
RegisterNetEvent("my_resource:server:becomeBusinessman", function()
    local src = source
    -- your own permission / job check here: the export does not check who is asking
    local ok, result = exports.Chapo_advanced_clothing:SetCustomPed(src, "a_m_m_business_01", "my_resource")
    if ok then
        print(("player %d is now %s"):format(src, result))       -- result = the model
    else
        print(("could not give the ped: %s"):format(result))     -- result = localized reason
    end
end)

-- read / remove it later (server side, inside a thread or handler)
local ped = exports.Chapo_advanced_clothing:GetCustomPed(src)    -- { model, components, props } or nil
local removed, message = exports.Chapo_advanced_clothing:RemoveCustomPed(src)
```

The ped is saved per character and comes back on every load, multicharacter preview included, until it is removed.
{% endtab %}
{% endtabs %}

## Scripts that open illenium directly

A script that calls illenium's `startPlayerCustomization` export skips the illenium guards. Point it at Vision Clothing's exports instead: `OpenClothingShop`, `OpenBarber`, `OpenTattooShop`, `OpenSurgeon`, `OpenWardrobe` or `OpenCharacterCreator`.


---

# 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://visionstore.gitbook.io/visionstore-docs/scripts/advanced-clothing/developers/integration-examples.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.
