Skip to content

Pricing Shared

Pricing is a shared module to normalize and manipulate prices in your scripts.

TIP

You can use the Price Generator to build price tables and paste the generated Lua code into your config files.

Quick usage

lua
local price = jo.pricing.formatPrice({
  money = 5,
  item = "acid"
})

price:add({ gold = 1 })

local prices = jo.pricing.formatPrices({
  operator = "or",
  { money = 10 },
  { gold = 1 }
})

Price and Prices remain classic Lua numeric tables, so existing table access is still valid:

lua
print(price[1].item)
print(prices[1][1].money)

JO Functions

jo.pricing.formatPrice()

A function to format a single price

Formats one payment expression and returns a Price object.

A Price is still a numeric Lua table. Each entry inside it is paid together.

Accepted formats include:

  • 10 for a money price.
  • { money = 10 }, { gold = 1 } or { rol = 5 }.
  • { money = 2.75, gold = 2 } for an AND price.
  • { item = "water" } for one item.
  • { money = 5, item = "acid" } for money plus one item.
  • { money = 2, { item = "acid", quantity = 3 } } for money plus multiple items.

If quantity is missing on an item, it defaults to 1. If keep is missing on an item, it defaults to false.

Syntax

lua
jo.pricing.formatPrice(price)

Parameters

price : table|integer|number

The price to format

Return Value

Type : Price

The formatted price

Example

lua
local moneyPrice = jo.pricing.formatPrice(10)
print(moneyPrice[1].money) -- 10

local currencyPrice = jo.pricing.formatPrice({
  money = 2.75,
  gold = 2
})
-- $2.75 AND 2 gold

local itemPrice = jo.pricing.formatPrice({
  item = "water",
  quantity = 2
})
-- 2 water items

local mixedPrice = jo.pricing.formatPrice({
  money = 5,
  item = "acid"
})
-- $5 AND 1 acid item

local mixedWithQuantity = jo.pricing.formatPrice({
  money = 2,
  { item = "acid", quantity = 3 }
})
-- $2 AND 3 acid items

jo.pricing.formatPrices()

A function to format price variations.
Only a root operator = "or" creates alternatives; every other shape is a single AND price.

Formats a list of payment expressions and returns a Prices object.

Prices is a numeric table containing one or more Price objects. Its operator property is either "and" or "or".

Without a root operator = "or", the input is formatted as a single AND option. This means { money = 2, gold = 1 } and { { money = 2 }, { gold = 1 } } both become one option.

Only a root operator = "or" creates alternatives. Nested operators are ignored.

Syntax

lua
jo.pricing.formatPrices(prices)

Parameters

prices : table|integer|number

The prices to format

Return Value

Type : Prices

The formatted prices

Example

lua
local andPrices = jo.pricing.formatPrices({
  money = 2,
  gold = 1
})
-- One option: $2 AND 1 gold

local alsoAndPrices = jo.pricing.formatPrices({
  { money = 2 },
  { gold = 1 }
})
-- One option: $2 AND 1 gold

local orPrices = jo.pricing.formatPrices({
  operator = "or",
  { money = 2 },
  { gold = 1 }
})
-- Option 1: $2
-- Option 2: 1 gold

local complexOrPrices = jo.pricing.formatPrices({
  operator = "or",
  { money = 5, item = "acid" },
  { gold = 5 },
  { money = 2, { item = "acid", quantity = 3 } }
})
-- Option 1: $5 AND 1 acid
-- Option 2: 5 gold
-- Option 3: $2 AND 3 acid

print(orPrices.operator)     -- "or"
print(orPrices[1][1].money)  -- 2

jo.pricing.isPriceFree()

Checks if a price is free

Returns true only when the formatted price is free.

For a Prices object, it returns true only when the set contains one free option.

Syntax

lua
jo.pricing.isPriceFree(price)

Parameters

price : table|integer|number

The price to check

Return Value

Type : boolean

Return true if the price is free

Example

lua
print(jo.pricing.isPriceFree(0))           -- true
print(jo.pricing.isPriceFree({ money = 1 })) -- false

local prices = jo.pricing.formatPrices({ money = 0 })
print(jo.pricing.isPriceFree(prices)) -- true

jo.pricing.mergePrices()

Merge prices

Merges multiple prices into one AND Price.

This is useful when you need to add several price fragments and keep the result as a single payment expression.

Syntax

lua
jo.pricing.mergePrices(...)

Parameters

... : table

The prices to merge

Return Value

Type : Price

The merged prices

Example

lua
local price = jo.pricing.mergePrices(
  { money = 10 },
  { gold = 1 },
  { item = "water", quantity = 2 }
)

-- $10 AND 1 gold AND 2 water

jo.pricing.tax()

Gets the tax price from a price and a percentage

Returns a new taxed Price based on the provided value.

percentage is a multiplier. For example, 0.2 returns 20% of the price and 1.2 returns 120% of the price. Item quantities are rounded down by default, or rounded up when roundUpItems is true.

Syntax

lua
jo.pricing.tax(price, percentage, roundUpItems)

Parameters

price : table|integer|number

The price to tax

percentage : number

The percentage to apply. Example: 0.2 returns 20% of the price

roundUpItems : boolean Optional

Whether item quantities should be rounded up. Defaults to false

Return Value

Type : Price

The taxed price

Example

lua
local price = jo.pricing.tax({
  money = 10,
  item = "water",
  quantity = 3
}, 0.5)

-- $5 AND 1 water, because item quantities are rounded down by default

local roundedUpPrice = jo.pricing.tax({
  item = "water",
  quantity = 3
}, 0.5, true)

-- 2 water, because roundUpItems is true

PriceClass Methods

PriceClass:add()

Adds a price to the current price.

Mutates the current Price by adding another price to it.

Currencies and compatible items are normalized after the addition. Items are merged only when they use the same item name, keep value and metadata.

Syntax

lua
PriceClass:add(price)

Parameters

price : table|integer|number

The price to add

Return Value

Type : Price

The mutated price

Example

lua
local price = jo.pricing.formatPrice({ money = 10 })

price:add({ gold = 1 })
price:add({ item = "water", quantity = 2 })

-- price is now: $10 AND 1 gold AND 2 water

PriceClass:copy()

Copies the price.

Creates an independent Price copy.

Mutating the copy does not mutate the original price.

Syntax

lua
PriceClass:copy()

Return Value

Type : Price

The copied price

Example

lua
local original = jo.pricing.formatPrice({ money = 10 })
local copy = original:copy()

copy:add({ gold = 1 })

print(original[1].money) -- 10

PriceClass:isFree()

Checks if the price is free.

Checks whether this Price is free.

Syntax

lua
PriceClass:isFree()

Return Value

Type : boolean

Return true if the price is free

Example

lua
local freePrice = jo.pricing.formatPrice(0)
local paidPrice = jo.pricing.formatPrice(10)

print(freePrice:isFree()) -- true
print(paidPrice:isFree()) -- false

PriceClass:remove()

Removes a price from the current price.

Strictly removes another price from the current Price.

If one currency amount or item quantity is missing, the method returns false, reason and the original Price is not mutated.

Syntax

lua
PriceClass:remove(price)

Parameters

price : table|integer|number

The price to remove

Return Value

Type : Price|boolean,string?

The mutated price, or false and the reason

Example

lua
local price = jo.pricing.formatPrice({
  money = 10,
  item = "water",
  quantity = 2
})

price:remove({ money = 5 })
-- price is now: $5 AND 2 water

local success, reason = price:remove({ money = 15 })

if not success then
  print(reason) -- "not_enough_money"
end

PriceClass:tax()

Applies a percentage to the current price.

Mutates the current Price by applying a multiplier.

Currencies are multiplied directly. Item quantities are rounded down by default, or rounded up when roundUpItems is true.

Syntax

lua
PriceClass:tax(percentage, roundUpItems)

Parameters

percentage : number

The percentage to apply

roundUpItems : boolean Optional

Whether item quantities should be rounded up

Return Value

Type : Price

The mutated price

Example

lua
local price = jo.pricing.formatPrice({
  money = 10,
  item = "water",
  quantity = 3
})

price:tax(0.5)
-- price is now: $5 AND 1 water

PriceClass:toTable()

Converts the price to a plain table.

Returns a deep plain table copy without object methods.

Use it when you explicitly need to serialize or pass a price without its metatable.

Syntax

lua
PriceClass:toTable()

Return Value

Type : table

The plain table

Example

lua
local price = jo.pricing.formatPrice({
  money = 10,
  item = "water"
})

local plainPrice = price:toTable()
print(plainPrice[1].money or plainPrice[2].money)

PricesClass Methods

PricesClass:addPrice()

Adds a price option to the prices set.

Adds a price option to this Prices object.

When operator is "or", this adds a new option. When operator is "and", this merges the price into the single AND option.

Syntax

lua
PricesClass:addPrice(price)

Parameters

price : table|integer|number

The price to add

Return Value

Type : Prices

The mutated prices set

Example

lua
local prices = jo.pricing.formatPrices({
  operator = "or",
  { money = 10 }
})

prices:addPrice({ gold = 1 })
-- prices now has two options

local andPrices = jo.pricing.formatPrices({ money = 10 })
andPrices:addPrice({ gold = 1 })
-- andPrices still has one option: $10 AND 1 gold

PricesClass:copy()

Copies the prices set.

Creates an independent copy of the Prices object and all its nested Price objects.

Syntax

lua
PricesClass:copy()

Return Value

Type : Prices

The copied prices set

Example

lua
local prices = jo.pricing.formatPrices({
  operator = "or",
  { money = 10 },
  { gold = 1 }
})

local copy = prices:copy()
copy:addPrice({ rol = 5 })

print(#prices) -- 2
print(#copy)   -- 3

PricesClass:removePrice()

Removes a price option from the prices set.

Removes one option from this Prices object by numeric index.

Syntax

lua
PricesClass:removePrice(index)

Parameters

index : integer

The price option index

Return Value

Type : Prices

The mutated prices set

Example

lua
local prices = jo.pricing.formatPrices({
  operator = "or",
  { money = 10 },
  { gold = 1 }
})

prices:removePrice(1)
-- only the gold option remains

PricesClass:toTable()

Converts the prices set to a plain table.

Returns a deep plain table copy without object methods.

The returned table keeps the operator field.

Syntax

lua
PricesClass:toTable()

Return Value

Type : table

The plain table

Example

lua
local prices = jo.pricing.formatPrices({
  operator = "or",
  { money = 10 },
  { gold = 1 }
})

local plainPrices = prices:toTable()

print(plainPrices.operator) -- "or"

Last updated: