Module:RecursiveExchange

-- -- Calculates the exchange price of an item recursively: -- If the item is tradeable return the GE price -- If it is not and can be made from other items return the sum of the price of the ingredients

local recipes = require("Module:Recipes/Data")

local price = require("Module:Exchange")._price local addcommas = require("Module:Addcommas")._add local yesno = require( 'Module:Yesno' )

local p = {}

-- See p._price in Module:Exchange -- Returns 0 if the item doesn't have any known combinations or if it isn't tradeable function p._price(item, multi, format, return_nan, is_potion_guess) multi = type(multi) == "number" and multi or 1 format = type(format) == "boolean" and format or false -- Note: We can't use and & or when we default to true if type(return_nan) ~= "boolean" then return_nan = true end is_potion_guess = type(is_potion_guess) == "boolean" and is_potion_guess or false local tradeable, ge_price = pcall(function return price(item, multi, format) end) if tradeable then return ge_price end local recipe = recipes[item] if recipe == nil then if is_potion_guess then return 0/0 elseif item:match(" %(%d%)$") then local potion_name = item:sub(1, -4) local doses = tonumber(item:sub(-2, -2)) for i=1, 6 do local name = potion_name .. "(" .. i .. ")" local result = p._price(name, multi, false, false, true) if result == result then mw.log("Calculated price of " .. item .. " based on the price of " .. name) return result * (doses / i)				end end end mw.log("Couldn't get price of " .. item) return return_nan and 0/0 or 0 end local amount_created = recipe[1] local ingredients = recipe[2] local sum = 0 for _, ingredient in ipairs(ingredients) do		local n = ingredient[1] local name = ingredient[2] sum = sum + p._price(name, n, false, false) end local ret = (sum * multi) / amount_created if format then ret = addcommas(ret) end return ret end

-- -- -- -- @example --d function p.price( frame ) -- usage: or     local args = frame.args local pargs = frame:getParent.args local item = pargs[1] if item then item = mw.text.trim( item ) else error( '"item" argument not specified', 0 ) end -- default to formatted for backwards compatibility with old GE templates local format = true local multi = 1 -- format is set with #invoke -- so set it first to allow it to be overridden by template args if args.format ~= nil then format = yesno( args.format ) end if tonumber( pargs[2] ) ~= nil then multi = tonumber( pargs[2] ) -- indicated someone is trying to pass an equation as a mulitplier -- known use cases are fractions, but pass it to #expr to make sure it's handled correctly elseif pargs[2] ~= nil and mw.ustring.find( pargs[2], '[/*+-]' ) then multi = tonumber( frame:preprocess( '' ) ) -- uses elseif to prevent something like -- causing a formatted output, as 1 casts to true when passed to yesno elseif type( yesno( pargs[2] ) ) == 'boolean' then format = yesno( pargs[2] ) if tonumber( pargs[3] ) ~= nil then multi = tonumber( pargs[3] ) end end return p._price( item, multi, format ) end

return p