Developer
Overview
ML Random Cloth exposes two client exports (usePack, useCustomPack) used by item systems and two server-side net events that perform the validated give (ml_random_cloth:server:packOpened, ml_random_cloth:server:customPackOpened). There are no server exports and no client-facing callbacks. All framework and inventory calls go through ml_bridge.
Client Exports
Both exports are called by an item use through ox_inventory: standard packs use usePack and custom packs use useCustomPack. Both take the data table that the inventory passes on item use.
usePack
1exports['ml_random_cloth']:usePack(data)usePack(data) handles the 15 standard packs. It reads data.name, strips the pack_ prefix to get the clothing type, rolls a random drawable and texture on the local ped, runs the progress bar, then triggers the server to give the item. Wire it in ox_inventory with client = { export = 'ml_random_cloth.usePack' } on each pack_* item.
data(table, required): the item-use payload. Must containdata.name, for examplepack_jacket.
useCustomPack
1exports['ml_random_cloth']:useCustomPack(data)useCustomPack(data) handles a pack defined in Config.CustomPacks. It looks up the pack by data.name, and depending on giveAll rolls one or all item types from the pack, runs the progress bar, then triggers the server. Wire it in ox_inventory with client = { export = 'ml_random_cloth.useCustomPack' } on each custom pack item.
data(table, required): the item-use payload.data.namemust match a key inConfig.CustomPacks.
Events
ml_random_cloth:server:packOpened (server, net)
1TriggerServerEvent('ml_random_cloth:server:packOpened', packType, meta)Fired by the client after the standard-pack progress bar completes. packType is the clothing type, for example jacket or bag and meta is the rolled { drawable, texture, sexRaw }. The server validates the type against Config.ClothingItems, applies the 3 second cooldown, confirms the player holds pack_<type>, sanitizes the metadata, checks carry space, removes the pack, then gives the clothing item with Bridge.GiveItem.
ml_random_cloth:server:customPackOpened (server, net)
1TriggerServerEvent('ml_random_cloth:server:customPackOpened', packName, itemsList)Fired by the client after a custom-pack progress bar completes. packName is the pack key, itemsList is an array of { type, meta } entries. The server re-validates every entry: the type must belong to the pack, no duplicate types, metadata is sanitized, and for keyed packs the drawable must be in the pack's allowed list for that gender. It enforces the expected item count for giveAll packs, checks carry space for all items, removes the pack, then gives each item.
How a Pack Gives Clothing
Standard pack:
- Player uses
pack_jacket.ox_inventorycalls theusePackclient export. - The client strips
pack_to getjacket, counts drawable and texture variations for that type on the player ped, removes excluded drawables and the default-outfit drawable, and picks a random drawable plus texture. Forpantsandjacketthe texture pool is capped at 3. - The progress bar runs for
Config.Progress.OpenDurationwith aPROP_HUMAN_PARKING_METERscenario. - On completion the client triggers
ml_random_cloth:server:packOpenedwith the rolled metadata. - The server validates ownership, cooldown, carry space, removes the pack, and calls
Bridge.GiveItem(src, packType, 1, meta).ml_clothingreceives the item and enriches bag metadata (bag id, cols, rows, weight) through its own create hook.
Custom pack:
- The pack item calls the
useCustomPackexport on use, wired inox_inventorywithclient = { export = 'ml_random_cloth.useCustomPack' }. - The client rolls one type or all types depending on
giveAll, using the pack's curated drawable lists for keyed packs or full random for string-array packs. - The progress bar runs, then the client triggers
ml_random_cloth:server:customPackOpenedwith the item list. - The server re-validates each drawable against the pack definition, checks carry space, removes the pack, and gives each item with
Bridge.GiveItem.
This resource does not register any server-side exports. All server work happens inside the two net-event handlers above. Integrate by giving players the pack items, not by calling a server export.
The client rolls the drawable and texture and sends them to the server. The server sanitizes types, floors numeric metadata, enforces gender, ownership, cooldown, and carry space, and for keyed custom packs rejects any drawable not in the pack's allowed list. Standard packs and legacy string-array packs do not re-verify the specific drawable server-side, so the trust boundary for those is the sanitized numeric metadata plus item ownership.