:necktie: Mannequin
Documentation relating to the jo_clothingstore_mannequin add-on for Clothing store script.
:::: tabs ::: tab BUY Buy the add-on :::
::: tab PREVIEW <iframe width="560" height="315" src="https://streamable.com/e/agu2uh" title="Streamable video" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe> ::: ::::
1. Installation
::: warning Clothing store script is required to use this add-on. :::
To install jo_clothingstore_mannequin:
- Drag and drop the resource into your resources folder:
jo_clothingstore_mannequin - Add this ensure in your server.cfg after
ensure jo_clothingstore:ensure jo_clothingstore_mannequin
Congratulations, the Mannequin add-on is ready to be used!
2. Usage
The Mannequin add-on lets players sell outfits through persistent mannequins placed in the world. It is an add-on of jo_clothingstore: before a seller can sell an outfit from a mannequin, they must first create and save at least one male or female outfit from the clothing store or wardrobe outfit menu. Mannequins can also be saved without an outfit.
The Premade Outfits add-on can help sellers create outfits faster by buying ready-made outfits and saving them into their clothing-store outfit list before using them on mannequins.
:::: tabs ::: tab ๐งต Seller setup
- Open the clothing store or a wardrobe.
- Go to Outfits and create a saved outfit.
- Choose the outfit sex before creating it. Mannequins can display
maleorfemaleoutfits, and the mannequin sex must match the selected outfit. - To prepare stock faster, use Premade Outfits to purchase ready-made outfits.
- Save the outfit in your clothing-store outfit list. :::
::: tab ๐ง Create a mannequin
- Use
/mannequinMenuto open the mannequin creation menu. - Select the mannequin sex: Male or Female.
- Select one of your saved outfits, or select None to create a mannequin without an outfit. The list only shows outfits compatible with the selected mannequin sex.
- Set the mannequin name. By default, selecting an outfit also fills the mannequin name with the outfit name.
- If an outfit is selected, set the sale price. This opens an in-game NUI price modal where you can define a simple price, a combo of several costs paid together, or several payment options for the buyer to choose from. If you add several payment options, use the Switch price prompt to preview them before saving the mannequin.
- Select a pose.
- Choose Move mannequin, place and rotate it with the gizmo, then confirm the placement.
- Choose Save mannequin to persist it.
The mannequin is saved, synchronized to every player, and will respawn automatically when players are close enough. :::
::: tab ๐ฐ Manage sales When the owner approaches one of their mannequins, owner prompts are displayed:
- Edit mannequin - Reopen the mannequin menu to change its sex, outfit, name, price, pose, or position.
- Delete mannequin - Remove the mannequin from the world and from persistence. If the mannequin has sales to collect, they must be collected before deleting it.
- Collect sales - Recover money, gold, ROL, or items stored from previous purchases when the mannequin has sales to collect.
Editing a mannequin keeps the existing world mannequin while the menu is open. If you cancel the edit, unsaved changes are reverted. :::
::: tab ๐๏ธ Buyer interactions When another player approaches a mannequin with an outfit, buyer prompts are displayed:
- Switch price - Cycle through the available payment options when the mannequin has more than one price.
- Try outfit - Temporarily apply the displayed outfit to the player. The preview is removed when the player moves away from the mannequin.
- Buy outfit - Purchase the outfit with the selected payment option.
Mannequins without outfits do not show try or buy prompts. Trying an outfit only works when the mannequin sex matches the buyer's current character sex. Buying can still save an outfit of either sex in the buyer's clothing-store outfit list. If the main clothing-store outfit-item mode is enabled, the purchase gives an outfit item instead. ::: ::::
3. Configuration
<ScriptConfig scriptPath="redm/mannequin" />
4. For developers > <Badge type="client" text="Client" /> Open Mannequin Creator
Trigger to open the mannequin creator menu for a specific player.
TriggerClientEvent("jo_clothingstore_mannequin:openMannequinMenu", playerId)
4. For developers > Actions
Actions are one of the two types of Hooks. They provide a way to run a function at a specific point in the execution of scripts. Callback functions for an Action do not return anything back to the calling Action hook. They are the counterpart to Filters.
Below is a complete list of all available actions in the jo_clothingstore_mannequin script.
4. For developers > Actions > <Badge type="shared" text="Shared" /> init
Triggered when the add-on is initialized after jo_clothingstore starts.
exports.jo_clothingstore_mannequin:registerAction("init", function()
-- Your code here
end)
4. For developers > Actions > <Badge type="server" text="Server" /> mannequinCreated
Triggered after a mannequin is created and synchronized to clients.
-- @param source - integer server ID of the creator
-- @param mannequin - Mannequin created mannequin instance
exports.jo_clothingstore_mannequin:registerAction("mannequinCreated", function(source, mannequin)
-- Your code here
end)
4. For developers > Actions > <Badge type="server" text="Server" /> mannequinDeleted
Triggered after a mannequin is deleted and removed from clients.
-- @param source - integer server ID of the owner
-- @param mannequinId - integer deleted mannequin ID
exports.jo_clothingstore_mannequin:registerAction("mannequinDeleted", function(source, mannequinId)
-- Your code here
end)
4. For developers > Actions > <Badge type="server" text="Server" /> mannequinUpdated
Triggered after a mannequin is updated and synchronized to clients.
-- @param source - integer server ID of the editor
-- @param mannequin - Mannequin updated mannequin instance
exports.jo_clothingstore_mannequin:registerAction("mannequinUpdated", function(source, mannequin)
-- Your code here
end)
4. For developers > Actions > <Badge type="server" text="Server" /> outfitBought
Triggered after an outfit is purchased from a mannequin.
-- @param source - integer server ID of the buyer
-- @param mannequin - Mannequin purchased mannequin instance
-- @param outfit - table outfit data
-- @param fullPrice - PriceGroupClass full mannequin price group
exports.jo_clothingstore_mannequin:registerAction("outfitBought", function(source, mannequin, outfit, fullPrice)
-- Your code here
end)
4. For developers > Actions > <Badge type="server" text="Server" /> outfitItemGiven
Triggered after a purchase gives the buyer an outfit item.
-- @param source - integer server ID of the buyer
-- @param mannequin - Mannequin purchased mannequin instance
-- @param itemName - string outfit item name
-- @param metadata - table item metadata containing outfit, name, sexe, and description
exports.jo_clothingstore_mannequin:registerAction("outfitItemGiven", function(source, mannequin, itemName, metadata)
-- Your code here
end)
4. For developers > Actions > <Badge type="server" text="Server" /> salesCollected
Triggered after the owner collects stored mannequin sales.
-- @param source - integer server ID of the owner
-- @param mannequin - Mannequin mannequin instance after stored sales are cleared
-- @param priceToRefund - PriceClass price refunded to the owner
exports.jo_clothingstore_mannequin:registerAction("salesCollected", function(source, mannequin, priceToRefund)
-- Your code here
end)
4. For developers > Actions > <Badge type="server" text="Server" /> sellerRevenueStored
Triggered after a purchase stores revenue on the seller's mannequin.
-- @param source - integer server ID of the buyer
-- @param mannequin - Mannequin purchased mannequin instance
-- @param revenuePrice - PriceClass price stored for the seller
-- @param price - PriceClass price paid by the buyer
-- @param priceIndex - integer selected price index
exports.jo_clothingstore_mannequin:registerAction("sellerRevenueStored", function(source, mannequin, revenuePrice, price, priceIndex)
-- Your code here
end)
4. For developers > Filters
Filters allow you to modify data or permissions synchronously at specific points in the script. Below is the complete list of jo_clothingstore_mannequin filters and how to use them.
4. For developers > Filters > <Badge type="server" text="Server" /> canBuyOutfit
Control whether a player can buy an outfit from a mannequin. This filter is called after the selected price has been resolved and before the player is charged.
-- @param canBuy - boolean (default true)
-- @param source - integer server ID of the buyer
-- @param mannequin - Mannequin purchased mannequin instance
-- @param price - PriceClass selected price
-- @param priceIndex - integer selected price index
exports.jo_clothingstore_mannequin:registerFilter("canBuyOutfit", function(canBuy, source, mannequin, price, priceIndex)
return canBuy
end)
4. For developers > Filters > <Badge type="server" text="Server" /> canCollectSales
Control whether the mannequin owner can collect stored sales.
-- @param canCollect - boolean (default true)
-- @param source - integer server ID of the owner
-- @param mannequin - Mannequin mannequin instance
exports.jo_clothingstore_mannequin:registerFilter("canCollectSales", function(canCollect, source, mannequin)
return canCollect
end)
4. For developers > Filters > <Badge type="server" text="Server" /> canCreateMannequin
Control whether a player can create a mannequin. This filter is called after the mannequin owner, sex, limit, and price have been validated.
-- @param canCreate - boolean (default true)
-- @param source - integer server ID of the creator
-- @param mannequin - Mannequin mannequin instance being created
exports.jo_clothingstore_mannequin:registerFilter("canCreateMannequin", function(canCreate, source, mannequin)
return canCreate
end)
4. For developers > Filters > <Badge type="server" text="Server" /> canDeleteMannequin
Control whether a player can delete a mannequin.
-- @param canDelete - boolean (default true)
-- @param source - integer server ID of the owner
-- @param mannequin - Mannequin mannequin instance being deleted
exports.jo_clothingstore_mannequin:registerFilter("canDeleteMannequin", function(canDelete, source, mannequin)
return canDelete
end)
4. For developers > Filters > <Badge type="server" text="Server" /> canUpdateMannequin
Control whether a player can update a mannequin. This filter is called after ownership, sex, and price validation.
-- @param canUpdate - boolean (default true)
-- @param source - integer server ID of the editor
-- @param existing - Mannequin current persisted mannequin instance
-- @param incoming - table incoming mannequin data
exports.jo_clothingstore_mannequin:registerFilter("canUpdateMannequin", function(canUpdate, source, existing, incoming)
return canUpdate
end)
4. For developers > Filters > <Badge type="server" text="Server" /> canOpenMannequinCreator
Control whether a player can open the mannequin creator menu.
-- @param canOpen - boolean (default true)
-- @param source - integer server ID of the player
exports.jo_clothingstore_mannequin:registerFilter("canOpenMannequinCreator", function(canOpen, source)
return canOpen
end)
4. For developers > Filters > <Badge type="server" text="Server" /> overwriteBuyerPrice
Override the selected price before the buyer is charged. The second argument is the order type and is "mannequinOutfit" for Mannequin purchases.
-- @param price - PriceClass selected price
-- @param typeOrder - string "mannequinOutfit"
-- @param source - integer server ID of the buyer
-- @param mannequin - Mannequin purchased mannequin instance
-- @param priceIndex - integer selected price index
exports.jo_clothingstore_mannequin:registerFilter("overwriteBuyerPrice", function(price, typeOrder, source, mannequin, priceIndex)
return price
end)
4. For developers > Filters > <Badge type="server" text="Server" /> overwriteSellerRevenue
Override the amount stored for the mannequin owner after a sale. By default, the stored revenue matches the buyer price, except item costs marked with keep = true.
::: warning
The price argument is the buyer price after overwriteBuyerPrice has already been applied. If you use overwriteBuyerPrice to change what the buyer pays, overwriteSellerRevenue receives that updated buyer price.
:::
Return nil to prevent storing seller revenue for this purchase.
-- @param revenuePrice - PriceClass|nil default seller revenue
-- @param source - integer server ID of the buyer
-- @param mannequin - Mannequin purchased mannequin instance
-- @param price - PriceClass price paid by the buyer
-- @param priceIndex - integer selected price index
exports.jo_clothingstore_mannequin:registerFilter("overwriteSellerRevenue", function(revenuePrice, source, mannequin, price, priceIndex)
return revenuePrice
end)
5. Snippets > Mannequin in item
Here is a snippet to manage the mannequin creation as an item:
- Create the
mannequinitem in your inventory script. - Create a
mannequin_items.luafile inside theconfig/customfolder. - Add the following code to the file:
--Define the mannequin item
local mannequinItem = "mannequin"
--Turn off the command to open the mannequin menu
Config.commands.openMannequinMenu = false
--Create all the server side logic
if jo.isServerSide() then
--load the framework module
jo.require("framework")
--Register the mannequin item has usable
jo.framework:registerUseItem(mannequinItem, true, function(source)
TriggerClientEvent("jo_clothingstore_mannequin:openMannequinMenu", source)
end)
--Register the filter to check if the player has the mannequin item in their inventory
jo.hook.registerFilter("canCreateMannequin", function(canCreate, source)
if jo.framework:getItemCount(source, mannequinItem) <= 0 then
jo.notif.rightError(source, "You don't have a mannequin in your inventory!")
return false
end
return canCreate
end)
--Register the action to remove the mannequin item when a mannequin is created
jo.hook.registerAction("mannequinCreated", function(source)
jo.framework:removeItem(source, mannequinItem, 1)
end)
--Register the action to add the mannequin item when a mannequin is deleted
jo.hook.registerAction("mannequinDeleted", function(source)
jo.framework:giveItem(source, mannequinItem, 1)
end)
end
- Restart your server.
- Done, you can now use the mannequin item to create mannequins.
- When you delete a mannequin, the item will be added back to your inventory.