Developer
Overview
ML Tattoos exposes server exports for the uses economy, a client export to open the shop, and override hooks in open/. Mutating use exports are restricted to the resources listed in Config.AllowedConsumerResources; read exports are open.
Server Exports
All under exports.ml_tattoos:<Name>(...). identifier is the player's framework id; ctype is 'solo', 'faction' or 'ytd'.
GrantTattooCredit(identifier, ctype, amount, reason?): Grants uses to a player (capped per type). Caller must be an allowed resource. Returnsok, grantedGetTattooCredits(identifier): Returns the player's balances:{ solo, faction, ytd, total_granted, total_consumed }. Open to any resourceConsumeTattooCredit(identifier, ctype): Consumes one use of a type. Caller must be an allowed resource. Returnsok, reason?RefundTattooCredit(identifier, ctype, reason?): Refunds one use of a type (capped). Caller must be an allowed resource
Two server exports are reserved for the Tebex hub and are called only by the ml_tebex dispatcher: OnTebexPackage(ev) (grants the package's uses) and OnTebexRefund(ev) (reverses a refunded transaction, returning { status, detail }). You do not call these yourself.
Client Exports
openShop(opts): Opens the tattoo shop.optsmay carrymode('shop'/'item'), alimit, and preset filters (zones,categories,hashes,allowCustom,customOnly). Returnsfalseif the shop is already open
open/ Handlers
Override these in the open/ files. They are not escrowed.
Client
1function OpenClient.BeforeOpenShop(shopData)
2 return true -- return false to block the shop from opening
3end
4
5function OpenClient.OnTattooPurchased(tattoos)
6 -- runs client-side after a successful checkout
7endServer
1function OpenServer.OnCheckout(src, tattoos, totalCost)
2 -- runs after a successful checkout (src, full tattoo list, money charged)
3end
4
5function OpenServer.OnCustomApproved(src, data)
6 return true -- return false to block a custom tattoo submission
7endShared
1function OpenShared.CanBuyTattoo(tattooHash, tattooDlc)
2 return true -- return false to block a specific tattoo
3endExamples
Add your resource to Config.AllowedConsumerResources first, then:
1-- e.g. inside a coin-donator redemption, server-side:
2local identifier = exports.ml_bridge:GetPlayerId(src)
3local ok, granted = exports.ml_tattoos:GrantTattooCredit(identifier, 'solo', 1, 'coin_redeem')
4if ok then
5 print(('granted %d solo use(s)'):format(granted))
6end1local identifier = exports.ml_bridge:GetPlayerId(src)
2local bal = exports.ml_tattoos:GetTattooCredits(identifier)
3print(('solo=%d faction=%d ytd=%d'):format(bal.solo, bal.faction, bal.ytd))1function OpenShared.CanBuyTattoo(tattooHash, tattooDlc)
2 -- block one DLC pack entirely:
3 if tattooDlc == 'mpluxe2_overlays' then return false end
4 return true
5endClient examples use ox_lib cache.* for player state.
1-- open the full shop:
2exports.ml_tattoos:openShop({ mode = 'shop' })
3
4-- open filtered to one zone, one tattoo:
5exports.ml_tattoos:openShop({
6 mode = 'item', limit = 1,
7 zones = { 'ZONE_LEFT_ARM' }, allowCustom = false,
8})1function OpenServer.OnCheckout(src, tattoos, totalCost)
2 if totalCost > 0 then
3 print(('player %d paid %d for %d tattoo(s)'):format(src, totalCost, #tattoos))
4 end
5end