Developer
Developer
ML Inventory keeps the ox_inventory API as it is and adds a few entry points of its own. ML Clothing has its own exports plus the open/ files you edit in place. Only symbols that exist in the source are listed here.
The ox_inventory API is unchanged
The resource answers to the name ox_inventory. Every export, event and hook of your ox_inventory install keeps working under the same name with the same arguments, so no script of yours needs an edit.
1local count = exports.ox_inventory:GetItemCount(source, 'water')The additions below are reached the same way.
Hook bus
Any resource can register a handler. Handlers are dropped when the resource that registered them stops, so a restart during development leaves nothing behind.
1exports.ox_inventory:mlRegisterHook('beforeItemDelete', function(ctx)
2 if ctx.itemName == 'evidence_bag' then
3 return 'Evidence cannot be destroyed'
4 end
5end)The handler is a function, or a table { fn = handler, priority = 50 }. Lower priority runs first and the default is 50. The call returns an id for mlUnregisterHook(name, id).
Three ways a hook runs
mlRunHook(name, context): every handler runs. A handler returningfalsestops the action; returning a string stops it and hands the string back as the reason.mlEmitHook(name, context): every handler runs and return values are ignored.mlTransformHook(name, context): a handler returning a table replaces the context for the handlers after it and for the caller. Returningfalsecancels.
Hook points
beforeItemDeleteon the server, run:source,inventoryId,slot,itemName,count,metadata. Returningfalseor a string blocks the deletion.afterItemDeleteon the server, emit:source,inventoryId,slot,itemName.afterInventoryOpenon the client, emit:inventory.afterInventoryCloseon the client, emit, with no fields.
Turning features off for one player
1exports.ox_inventory:mlDisableFeature(source, 'give', true)The features are grid, clothing, loot, give and admin. Read the current state with mlIsFeatureDisabled(source, feature) and cover all five at once with mlDisableAllFeatures(source, disabled). The block is dropped when the player leaves.
Columns of a single inventory
1exports.ox_inventory:mlSetInventoryCols('gang_stash_1', 5)Sets the grid width of one inventory by id. Without an override, the player grid uses playerCols, a ground drop uses dropCols, anything else uses secondaryCols, and a stash or container takes a width from its slot count.
Registering a stash with a width
RegisterStash takes the width in two ways. Pass the slots as a table:
1exports.ox_inventory:RegisterStash('gang_stash_1', 'Gang Stash', { slots = 30, cols = 5 }, 100000)Or, when the call already passes an instance as the ninth argument, the eighth is the width:
1exports.ox_inventory:RegisterStash('gang_stash_1', 'Gang Stash', 30, 100000, nil, nil, nil, 5, instanceId)A call with eight arguments keeps the stock meaning, where the eighth argument is the instance. CreateTemporaryStash reads cols from its properties table.
Loot stashes
1local id = exports.ox_inventory:OpenLootStash(source, 'stash', { id = 'crate_01' }, { persistent = true })Opens an inventory for one player as a loot container: what is inside stays hidden until the player uncovers it. The fourth argument is passed on to the interface; persistent is the field the server itself checks, and it is required before a loot config is accepted on a stored inventory. On a temporary inventory it is not needed. The call returns the inventory id.
ML Clothing server exports
Wear and durability
1exports.ml_clothing:GetWornDurability(src, slot)Returns the durability value from the item metadata in the given inventory slot, or nil if the slot is empty or has no metadata.
1exports.ml_clothing:IsGearBroken(src, slot)Returns true if the worn piece in that slot is currently flagged broken, otherwise false.
1exports.ml_clothing:RepairGear(src, slot, amount)Repairs the worn piece in that slot by amount, clamped 1 to 100 and defaulting to 100. Returns false if the arguments are not numbers or the slot is not wear managed, otherwise the result of the repair.
Equipment stashes
1exports.ml_clothing:RegisterEquipmentStash(stashType, uniqueId, slots, maxWeight, cols)stashType is 'plateCarrier' or 'bag'. The id is built from the matching prefix in Config.Stash plus uniqueId. Returns the full stash id. cols is optional.
1exports.ml_clothing:GetEquipmentStashId(stashType, uniqueId)Returns the stash id that RegisterEquipmentStash would produce for the same arguments, without registering it.
Reserved slots
1exports.ml_clothing:GetReservedSlots()Returns the sorted list of clothing slot numbers, 11 to 25. Use it to keep other scripts from writing into a reserved slot.
ML Clothing client exports
Appearance
1exports.ml_clothing:getCurrentAppearance()Returns the current ped appearance snapshot, components and props.
1exports.ml_clothing:applyAppearance(appearanceData)Applies an appearance table to the local ped, setting components and props.
1exports.ml_clothing:saveAppearance()Captures the current ped appearance and sends it to the server to persist.
1exports.ml_clothing:syncFromNUI(appearanceData)Sends an appearance table to the server as a new outfit to turn into inventory items. This is the call to add inside the appearance script wherever an outfit is saved.
1exports.ml_clothing:syncFromPed()Reads the live ped components and props and syncs them into inventory items. Use it instead of syncFromNUI when the appearance data is not at hand or its format has no adapter.
1exports.ml_clothing:clearSkin()Resets the ped clothing components to their default state.
Vest and plate carrier
1exports.ml_clothing:useVest(item, data)Equips or removes the plate carrier. Plays the tie animation, registers the carrier if needed, and sets ped armor from the sum of inserted plate health, capped at 100.
Give mode and loot feedback
1exports.ml_clothing:openGiveMode(data)Starts hand item to player targeting. The player aims at someone nearby and confirms to give the item.
1exports.ml_clothing:lootTrapEffect()Plays a trap reaction on the local ped: animation, screen effect, sound and a small amount of damage.
1exports.ml_clothing:PlayLootSound(data)Plays a named loot sound. data is an event name string, or a table with an event field. Recognized events include container_open, scan_tick, slot_unlock, reveal_common, reveal_uncommon, reveal_rare, reveal_epic, reveal_legendary and loot_all.
Preview ped positioning
1exports.ml_clothing:OnPedScreenPosition(data)
2exports.ml_clothing:OnPedZoom(data)
3exports.ml_clothing:OnTargetPedScreenPosition()Drive the placement and zoom of the preview ped shown next to the inventory. OnTargetPedScreenPosition is a stub that does nothing.
Admin gizmo
1exports.ml_clothing:UseGizmo(...)
2exports.ml_clothing:StopGizmo()
3exports.ml_clothing:IsGizmoActive()Start, stop and query the placement gizmo used by the admin panel.
Owner hooks
These live in open/ and are meant to be edited. ML Clothing calls them at fixed points.
Server hooks (open/server.lua)
1function OpenServer.PunishPlayer(source, reason) end
2function OpenServer.BeforeGiveItem(src, item, amount) end
3function OpenServer.OnActionComplete(src, actionType, data) end
4function OpenServer.OnGearBroken(src, itemName, slot, key) end
5function OpenServer.OnGearRepaired(src, slot) endPunishPlayer: called when a suspicious action is detected. Put your ban, kick or log logic here. The default prints a debug line.BeforeGiveItem: returntrueto allow orfalseto block, before an item is given. Defaults totrue.OnActionComplete: called after an action completes.OnGearBroken: fired once when a worn piece reaches zero durability. Thekeyisc:<component>:<drawable>:<texture>for components orp:<prop>:<drawable>:<texture>for props.OnGearRepaired: fired when a worn piece is repaired back above zero.
Client hooks (open/client.lua)
1function OpenClient.BeforeOpenUI(data) endBeforeOpenUI: returntrueto let the interface open. Defaults totrue.
Shared hooks (open/shared.lua)
1function OpenHandlers.OnPlayerAction(src, data) end
2function OpenHandlers.ValidateAction(src, actionType) endOnPlayerActionandValidateAction: returntrueto allow the action. Both default totrue.
Notifications from ML Clothing are sent through ml_bridge, which picks the notification system your server runs.
Appearance adapters (open/adapters/)
One file per appearance format. Two ship with the resource: standard.lua and bl_appearance.lua. Each defines a function on Config.DataAdapters that takes the appearance data and returns entries of { type, id, drawable, texture }, where type is component or prop. The server tries the adapters in turn and the first one that returns entries wins. To support another format, add a file to the folder, then run refresh and restart the resource so the new file is picked up.
State bag
A worn out piece is exposed through a player state bag so other scripts can react.
1local broken = LocalPlayer.state.ml_clothingBrokenml_clothingBroken holds the broken worn drawables, keyed c:<component>:<drawable>:<texture> for components and p:<prop>:<drawable>:<texture> for props. ml_radiation reads it to drop the protection of a worn out mask or suit when its RespectWear option is on.
Examples
1exports.ox_inventory:mlRegisterHook('beforeItemDelete', function(ctx)
2 if ctx.itemName ~= 'evidence_bag' then return end
3
4 return 'Evidence cannot be destroyed'
5end)1local uniqueId = 'trunk_' .. plate
2local slots, maxWeight, cols = 20, 40000, 5
3
4local stashId = exports.ml_clothing:RegisterEquipmentStash('bag', uniqueId, slots, maxWeight, cols)1local reserved = exports.ml_clothing:GetReservedSlots()
2
3local function isReserved(slot)
4 for i = 1, #reserved do
5 if reserved[i] == slot then return true end
6 end
7
8 return false
9end1if exports.ml_clothing:IsGearBroken(src, slot) then
2 exports.ml_clothing:RepairGear(src, slot, 100)
3end1function OpenServer.OnGearBroken(src, itemName, slot, key)
2
3end