Developer
Overview
Props Carry provides client exports for reading and managing carried props, a server export for position data, and handler hooks in the open/ folder for your own rules. Props sync to nearby players through state bags. Admins manage the live item catalog in game with /carryadmin, and the changes persist to oxmysql and reach every player without a restart.
Server Exports
lua
1local positions = exports.ml_propscarry:GetPlayerPositions(source)GetPlayerPositions(source): all custom positions of a player, as{ [itemName] = { x, y, z, rx, ry, rz, bone? } }.boneis set when the player moved the item to another bone
Client Exports
Prop State
lua
1local props = exports.ml_propscarry:GetCarriedProps()
2local positions = exports.ml_propscarry:GetCustomPositions()
3local otherProps = exports.ml_propscarry:GetOtherPlayersProps()GetCarriedProps(): Returns{ itemName = propEntity, ... }for the local playerGetCustomPositions(): the local player's custom positions, in the same shapeGetOtherPlayersProps(): Returns{ serverId = { itemName = propEntity, ... }, ... }for nearby players
Prop Management
lua
1exports.ml_propscarry:AddCarriedProp(itemName, propEntity)
2exports.ml_propscarry:RemoveCarriedProp(itemName)
3exports.ml_propscarry:RefreshProps()
4exports.ml_propscarry:ForceBroadcast()AddCarriedProp(itemName, prop): Registers a prop entity as carriedRemoveCarriedProp(itemName): stops tracking the prop without deleting it, and returns the entity so you can handle itRefreshProps(): Deletes all props and recreates them (full reset)ForceBroadcast(): Forces a StateBag update to sync with other players
Spawning and Releasing
lua
1local entity = exports.ml_propscarry:SpawnProp(itemConfig)
2exports.ml_propscarry:ReleaseCarriedProp(itemName)SpawnProp(itemConfig): creates and attaches the prop of aConfig.Itemsentry on the local player. Returns the entity ornilReleaseCarriedProp(itemName): deletes the carried prop of that item, matched without case
Local Positions
lua
1exports.ml_propscarry:SetCustomPosition(itemName, pos)
2exports.ml_propscarry:ClearCustomPosition(itemName)
3exports.ml_propscarry:SetPendingPosition(itemName, pos)
4local pending = exports.ml_propscarry:GetPendingPosition(itemName)
5exports.ml_propscarry:ClearPendingPosition(itemName)SetCustomPosition,ClearCustomPosition: change the position the local client uses for an item. They do not save to the serverSetPendingPosition,GetPendingPosition,ClearPendingPosition: the position waiting to be saved by the editor
pos is { x, y, z, rx, ry, rz, bone? } with named fields.
Gizmo
lua
1exports.ml_propscarry:UseGizmo(itemData, propEntity, positionData, onComplete)
2exports.ml_propscarry:StopGizmo()
3local active = exports.ml_propscarry:IsGizmoActive()UseGizmo(itemData, propEntity, positionData, onComplete): opens the 3D gizmo on an entity, starting frompositionData.onCompleteruns when the player confirms or cancelsStopGizmo(): closes the gizmoIsGizmoActive():truewhile the gizmo is open
Weapon Entity
lua
1local entity, hadComponents = exports.ml_propscarry:CreateWeaponEntity(itemConfig)CreateWeaponEntity(itemConfig): Creates a weapon object for aConfig.Itemsentry, with components and tint resolved from inventory metadata. Returns the entity and whether any components/tint were applied
Editor
lua
1exports.ml_propscarry:StartEditing(itemName)
2exports.ml_propscarry:StopEditing()
3local busy = exports.ml_propscarry:IsEditing()
4exports.ml_propscarry:MLAdminOpen()StartEditing(itemName): Opens the position editor on one carried item, the same one/carryeditopensStopEditing(): Closes the editor without savingIsEditing():truewhile the player editor or the admin editor is open. Check it before starting an animation or a menu that would fight with itMLAdminOpen(): opens the admin catalog manager, permission checked. Use it to add a button to your own staff menuMLAdminPanel(): label and icon of the catalog manager, for a staff menu that lists admin tools
Client Handlers
Located in open/client.lua.
open/client.lua
1function Handlers.CanShowProp(itemConfig)
2 return true -- return false to prevent spawning
3end
4
5function Handlers.OnPropSpawned(itemName, entity)
6end
7
8function Handlers.OnPropRemoved(itemName)
9end
10
11function Handlers.CanUseEditor(itemName)
12 return true -- return false to block editor
13endCanShowProp: returnfalseto hide the prop, for example while cuffed or on dutyOnPropSpawned: Fires after a prop is created and attached to the player.OnPropRemoved: Fires after a prop is deleted.CanUseEditor: returnfalseto block the editor for that item
Server Handlers
Located in open/server.lua.
open/server.lua
1function Handlers.CanSavePosition(src, itemName, position)
2 return true -- return false to block save
3end
4
5function Handlers.OnPositionSaved(src, itemName, position)
6end
7
8function Handlers.IsAdmin(src)
9 return nil -- return true/false to override, nil for default
10endCanSavePosition: Validate position before saving to KVP. Returnfalseto reject.OnPositionSaved: Fires after a position is saved.IsAdmin: Override the admin check used by/carryadminand the live catalog callbacks. Returnnilto keep the default, the admin permissions of your framework read throughml_bridge. On standalone, returntruehere for your staff, for example withIsPlayerAceAllowed(src, 'ml_propscarry.admin').
Examples
open/client.lua
1function Handlers.CanShowProp(itemConfig)
2 if LocalPlayer.state.isCuffed then
3 return false
4 end
5 return true
6endyour_script/client.lua
1local carried = exports.ml_propscarry:GetCarriedProps()
2for itemName, entity in pairs(carried) do
3 print(itemName .. ' is visible on player')
4end