Module:Sandbox/User:The Gaffer/Modules/Infobox Recipe: Difference between revisions
Jump to navigation
Jump to search
Content added Content deleted
The Gaffer (talk | contribs) No edit summary |
The Gaffer (talk | contribs) No edit summary |
||
(53 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
require('strict') |
|||
-- Lua module to replicate the functionality of the Infobox Recipe template |
|||
require('Module:Mw.html extension') |
|||
local currency = require('Module:Currency') |
|||
local hc = require('Module:Param Parse').has_content |
|||
local yn = require('Module:Yesno') |
|||
local editButton = require('Module:Edit button') |
|||
local function currency_cell(amount) |
|||
return currency._cell(amount, { html = 'yes' }) |
|||
end |
|||
local p = {} |
local p = {} |
||
function p. |
function p._main(frame) |
||
local args = frame:getParent().args |
|||
local mw = require('mw') |
|||
--If set to true, will check if any of the items passed as a rawmaterialparam are actually intermediate materials. Will then change the display order of the infobox. |
|||
-- Define raw material costs based on Semantic MediaWiki queries |
|||
local showFullRecipe = yn(args.showFull or 'no', false) |
|||
-- local function getCost(queryResult) |
|||
-- if type(queryResult) == "table" and queryResult[1] then |
|||
-- return tonumber(queryResult[1]) or 0 |
|||
-- end |
|||
-- return 0 |
|||
-- end |
|||
-- local rawmat1cost = args.rawmat1 and mw.smw.ask('[[:+]][[Sold item::' .. args.rawmat1 .. ']]|?Shop buy price|sort=Shop buy price|order=asc|limit=1') or "0" |
|||
-- local rawmat2cost = args.rawmat2 and mw.smw.ask('[[:+]][[Sold item::' .. args.rawmat2 .. ']]|?Shop buy price|sort=Shop buy price|order=asc|limit=1') or "0" |
|||
-- local rawmat3cost = args.rawmat3 and mw.smw.ask('[[:+]][[Sold item::' .. args.rawmat3 .. ']]|?Shop buy price|sort=Shop buy price|order=asc|limit=1') or "0" |
|||
--Get each of the rawmatX parameters from params and store their values in a new table |
|||
-- Calculate total cost and output cost |
|||
local argsMaterials = p._extractRawMaterials(args) |
|||
-- local totalCost = (tonumber(rawmat1cost) or 0) * (tonumber(args.rawmat1qty) or 1) + |
|||
-- (tonumber(rawmat2cost) or 0) * (tonumber(args.rawmat2qty) or 1) + |
|||
--empty tables to hold materials |
|||
-- (tonumber(rawmat3cost) or 0) * (tonumber(args.rawmat3qty) or 1) |
|||
local rawMaterials = {} |
|||
-- local output1cost = args.output1 and mw.smw.ask('[[:+]][[' .. args.output1 .. ']]|?Value|limit=1') or "0" |
|||
local intermediateMaterials = {} |
|||
--counter for total price of raw materials |
|||
local rawMaterialCost = 0 |
|||
--get the value for the output product |
|||
-- -- Calculate output cost total and profit |
|||
local output1Value = 0 |
|||
-- local output1costTotal = (tonumber(output1cost) or 0) * (tonumber(args.output1qty) or 1) |
|||
if args.output1 then |
|||
-- local profit = output1costTotal - totalCost |
|||
output1Value = mw.smw.ask('[[:+]][[' .. args.output1 .. ']]|?Value|limit=1') or 0 |
|||
end |
|||
--Calculate total value of output material(s) |
|||
local output1TotalValue = 0 |
|||
if type(output1Value) == "table" then |
|||
if output1Value[1]['Value'] ~= nil then |
|||
output1TotalValue = output1Value[1]['Value'] * (tonumber(args.output1qty) or 1) |
|||
else |
|||
output1TotalValue = 0 |
|||
end |
|||
end |
|||
-- -- Generate the output table |
|||
local out = {} |
|||
-- table.insert(out, '{| class="wikitable"') |
|||
-- table.insert(out, '! colspan="4" | Requirements') |
|||
-- table.insert(out, '|-') |
|||
-- table.insert(out, '! colspan="2" | Facility') |
|||
-- table.insert(out, '! colspan="2" | ' .. (args.facility and '[[' .. args.facility .. ']]' or 'Unknown')) |
|||
-- table.insert(out, '|-') |
|||
-- table.insert(out, '! colspan="2" | Profession') |
|||
-- table.insert(out, '! Level') |
|||
-- table.insert(out, '! XP') |
|||
-- table.insert(out, '|-') |
|||
-- table.insert(out, '| colspan="2" | ' .. (args.profession and '[[' .. args.profession .. ']]' or 'Unknown')) |
|||
-- table.insert(out, '| style="text-align: center;" | ' .. (args.level or 'Unknown')) |
|||
-- table.insert(out, '| style="text-align: center;" | ' .. (args.exp or 'Unknown')) |
|||
-- table.insert(out, '|-') |
|||
-- table.insert(out, '! colspan="2" | Raw Ingredient') |
|||
-- table.insert(out, '! Quantity') |
|||
-- table.insert(out, '! Cost') |
|||
-- table.insert(out, '|-') |
|||
-- -- Add each raw material to the table |
|||
-- if args.rawmat1 then |
|||
-- table.insert(out, '| [[File:' .. args.rawmat1 .. '.png|30px]]') |
|||
-- table.insert(out, '| [[' .. args.rawmat1 .. ']]') |
|||
-- table.insert(out, '| style="text-align: right;" | ' .. (args.rawmat1qty or 1)) |
|||
-- table.insert(out, '| style="text-align: right;" | ' .. rawmat1cost) |
|||
-- table.insert(out, '|-') |
|||
-- end |
|||
-- if args.rawmat2 then |
|||
-- table.insert(out, '| [[File:' .. args.rawmat2 .. '.png|30px]]') |
|||
-- table.insert(out, '| [[' .. args.rawmat2 .. ']]') |
|||
-- table.insert(out, '| style="text-align: right;" | ' .. (args.rawmat2qty or 1)) |
|||
-- table.insert(out, '| style="text-align: right;" | ' .. rawmat2cost) |
|||
-- table.insert(out, '|-') |
|||
-- end |
|||
-- if args.rawmat3 then |
|||
-- table.insert(out, '| [[File:' .. args.rawmat3 .. '.png|30px]]') |
|||
-- table.insert(out, '| [[' .. args.rawmat3 .. ']]') |
|||
-- table.insert(out, '| style="text-align: right;" | ' .. (args.rawmat3qty or 1)) |
|||
-- table.insert(out, '| style="text-align: right;" | ' .. rawmat3cost) |
|||
-- table.insert(out, '|-') |
|||
-- end |
|||
--Check if any of the raw mats provided are intermediate products, if they are, return their own raw materials |
|||
-- -- Add total raw cost |
|||
if showFullRecipe then |
|||
-- table.insert(out, '! colspan="3" | Total Raw cost') |
|||
local Materials = p._getTrueRawMaterials(argsMaterials) |
|||
-- table.insert(out, '| style="text-align: right;" | ' .. totalCost) |
|||
if next(Materials) ~= nil then |
|||
-- table.insert(out, '|-') |
|||
rawMaterials = Materials.rawMaterials |
|||
intermediateMaterials = p._reverseTable(Materials.intermediateMaterials) |
|||
end |
|||
else |
|||
rawMaterials = argsMaterials |
|||
end |
|||
-- -- Add output data and profit |
|||
-- table.insert(out, '! colspan="2" | Output') |
|||
-- table.insert(out, '! Quantity') |
|||
-- table.insert(out, '! Value') |
|||
-- table.insert(out, '|-') |
|||
-- table.insert(out, '| ' .. (args.output1 and '[[' .. args.output1 .. ']]' or 'Unknown')) |
|||
-- table.insert(out, '| style="text-align: right;" | ' .. (args.output1qty or 1)) |
|||
-- table.insert(out, '| style="text-align: right;" | ' .. output1costTotal) |
|||
-- table.insert(out, '|-') |
|||
-- table.insert(out, '! colspan="3" | Profit') |
|||
-- table.insert(out, '| style="text-align: right;" | ' .. profit) |
|||
-- table.insert(out, '|}') |
|||
-- Add debug information to the output as a simple paragraph |
|||
--Simple query to get the shop buy price for the provided material, if no buy price is available returns 0 |
|||
local debugMessage = 'Debug Info:<br>' .. |
|||
local function getBuyPrice(material) |
|||
'facility: ' .. (args.facility) .. '<br>' .. |
|||
local queryResult = mw.smw.ask('[[:+]][[Sold item::' .. material['name'] .. ']]|?Shop buy price|sort=Shop buy price|order=asc|limit=1') or 0 |
|||
'profession: ' .. (args.profession) .. '<br>' .. |
|||
if type(queryResult) == "table" and queryResult[1]['Shop buy price'] then |
|||
'level: ' .. (args.level) .. '<br>' .. |
|||
return tonumber(queryResult[1]['Shop buy price']) or 0 |
|||
'exp: ' .. (args.exp) .. '<br>' .. |
|||
end |
|||
'rawmat1: ' .. (args.rawmat1) .. '<br>' .. |
|||
return 0 |
|||
'rawmat1qty: ' .. (args.rawmat1qty) .. '<br>' .. |
|||
end |
|||
'rawmat2: ' .. (args.rawmat2) .. '<br>' .. |
|||
'rawmat2qty: ' .. (args.rawmat3qty) .. '<br>' .. |
|||
'rawmat3: ' .. (args.rawmat3) .. '<br>' .. |
|||
'rawmat3qty: ' .. (args.rawmat3qty) .. '<br>' .. |
|||
'preparedmat1: ' .. (args.preparedmat1) .. '<br>' .. |
|||
'preparedmat1qty: ' .. (args.preparedmat1qty) .. '<br>' .. |
|||
'preparedmat1fac: ' .. (args.preparedmat1fac) .. '<br>' .. |
|||
'output1: ' .. (args.output1) .. '<br>' .. |
|||
'output1qty: ' .. (args.output1qty) .. '<br>' .. |
|||
table.insert(out, debugMessage) |
|||
return table.concat(out, '\n') |
|||
--If one of the raw materials provided as a param has been identified as an intermediate material then get the facility it is created at to display in the intermediate Ingredient row |
|||
local function getFacility(material) |
|||
local result = mw.smw.ask('[[:+]][[' .. material .. ']]|?Uses facility|limit=1') or 'unknown' |
|||
local pageName = '' |
|||
if result and result[1] and result[1]["Uses facility"] then |
|||
local usesFac = result[1]["Uses facility"] |
|||
pageName = usesFac:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "") |
|||
end |
|||
return pageName |
|||
end |
|||
--Set SMW properties |
|||
for _,material in ipairs(argsMaterials) do |
|||
mw.smw.set({ |
|||
["Uses item"] = material.name, |
|||
["Uses item_and_quantity"] = material.name .. ',' .. tostring(material.quantity) |
|||
}) |
|||
end |
|||
if args.facility then |
|||
mw.smw.set({ |
|||
["Uses facility"] = args.facility |
|||
}) |
|||
end |
|||
--Creates a row suitable for the raw materials section of the infobox. |
|||
local function createRawMaterialRow(item) |
|||
local materialBuyPrice = getBuyPrice(item) * (item.quantity or 1) |
|||
rawMaterialCost = rawMaterialCost + materialBuyPrice |
|||
return mw.html.create('tr') |
|||
:tag('td') |
|||
:css{ ['border-right'] = 'none' } |
|||
:wikitext('[[File:' .. item.name .. '.png|30px|link=' .. item.name .. ']]') |
|||
:done() |
|||
:tag('td') |
|||
:css{ ['border-left'] = 'none' } |
|||
:wikitext('[[' .. item.name .. ']]') |
|||
:done() |
|||
:tag('td') |
|||
:css{ ['text-align'] = 'right' } |
|||
:wikitext(item.quantity or 1) |
|||
:done() |
|||
:wikitext(currency_cell(materialBuyPrice)) |
|||
:done() |
|||
end |
|||
--Creates a row suitable for the intermediate materials section of the infobox. |
|||
local function createIntermediateMaterialRow(item) |
|||
local facility = getFacility(item.name) |
|||
return mw.html.create('tr') |
|||
:tag('td') |
|||
:css{ ['border-right'] = 'none' } |
|||
:wikitext('[[File:' .. item.name .. '.png|30px|link=' .. item.name .. ']]') |
|||
:done() |
|||
:tag('td') |
|||
:css{ ['border-left'] = 'none' } |
|||
:wikitext('[[' .. item.name .. ']]') |
|||
:done() |
|||
:tag('td') |
|||
:css{ ['text-align'] = 'right' } |
|||
:wikitext(item.quantity or 1) |
|||
:done() |
|||
:tag('td') |
|||
:attr{ colspan = '10' } |
|||
:css{ ['text-align'] = 'left' } |
|||
:wikitext('[[File:' .. facility .. '.png|30px|link=' .. facility .. ']] [[' .. facility .. ']]') |
|||
:done() |
|||
:done() |
|||
end |
|||
-- Recipe Table Head |
|||
local out = mw.html.create('table') |
|||
:addClass('wikitable') |
|||
:tag('tr') |
|||
:tag('th') |
|||
:attr{ colspan = '13' } |
|||
:wikitext('Requirements') |
|||
:done() |
|||
:done() |
|||
:tag('tr') |
|||
:tag('th') |
|||
:attr{ colspan = '2' } |
|||
:wikitext('Facility') |
|||
:done() |
|||
:tag('td') |
|||
:attr{ colspan = '11' } |
|||
:wikitext(hc(args.facility) and ('[[File:%s.png|link=%s|30px]] [[%s]]'):format(args.facility, args.facility, args.facility) or editButton("'''?''' (edit)")) |
|||
:done() |
|||
:done() |
|||
:tag('tr') |
|||
:tag('th') |
|||
:attr{ colspan = '2' } |
|||
:wikitext('Profession') |
|||
:done() |
|||
:tag('th') |
|||
:wikitext('Level') |
|||
:done() |
|||
:tag('th') |
|||
:attr{ colspan = '10' } |
|||
:wikitext('XP') |
|||
:done() |
|||
:done() |
|||
:tag('tr') |
|||
:tag('td') |
|||
:attr{ colspan = '2' } |
|||
:css{ ['text-align'] = 'center' } |
|||
:wikitext(hc(args.profession) and ('[[' .. args.profession .. ']]') or editButton("'''?''' (edit)")) |
|||
:done() |
|||
:tag('td') |
|||
:css{ ['text-align'] = 'center' } |
|||
:wikitext(hc(args.level) and (args.level) or editButton("'''?''' (edit)")) |
|||
:done() |
|||
:tag('td') |
|||
:attr{ colspan = '10' } |
|||
:css{ ['text-align'] = 'center' } |
|||
:wikitext(hc(args.exp) and (args.exp) or editButton("'''?''' (edit)")) |
|||
:done() |
|||
:done() |
|||
-- Add raw materials |
|||
-- Headers |
|||
:tag('tr') |
|||
:tag('th') |
|||
:attr{ colspan = '2' } |
|||
:wikitext('Raw Ingredient') |
|||
:done() |
|||
:tag('th') |
|||
:wikitext('Quantity') |
|||
:done() |
|||
:tag('th') |
|||
:attr{ colspan = '10' } |
|||
:wikitext('Cost') |
|||
:done() |
|||
:done() |
|||
-- Values |
|||
for _, material in ipairs(rawMaterials) do |
|||
out:node(createRawMaterialRow(material)) |
|||
end |
|||
-- Add total raw cost |
|||
out |
|||
:tag('tr') |
|||
:tag('th') |
|||
:attr{ colspan = '3' } |
|||
:wikitext('Total Raw cost') |
|||
:done() |
|||
:wikitext(currency_cell(rawMaterialCost)) |
|||
:done() |
|||
-- Add Intermediate steps if required |
|||
-- Headers |
|||
if next(intermediateMaterials) ~= nil then |
|||
-- Headers |
|||
out |
|||
:tag('tr') |
|||
:tag('th') |
|||
:attr{ colspan = '2' } |
|||
:wikitext('Intermediate Ingredient') |
|||
:done() |
|||
:tag('th') |
|||
:wikitext('Quantity') |
|||
:done() |
|||
:tag('th') |
|||
:attr{ colspan = '10' } |
|||
:wikitext('Faciltity') |
|||
:done() |
|||
:done() |
|||
-- Values |
|||
for _, material in ipairs(intermediateMaterials) do |
|||
out:node(createIntermediateMaterialRow(material)) |
|||
end |
|||
end |
|||
-- Add output data |
|||
-- Headers |
|||
out |
|||
:tag('tr') |
|||
:tag('th') |
|||
:attr{ colspan = '2' } |
|||
:wikitext('Output') |
|||
:done() |
|||
:tag('th') |
|||
:wikitext('Quantity') |
|||
:done() |
|||
:tag('th') |
|||
:attr{ colspan = '10' } |
|||
:wikitext('Value') |
|||
:done() |
|||
:done() |
|||
:IF(args.output1) |
|||
-- Values |
|||
:tag('tr') |
|||
:tag('td') |
|||
:css{ ['border-right'] = 'none' } |
|||
:wikitext('[[File:' .. args.output1 .. '.png|30px|link=' .. args.output1 .. ']]' or 'Unknown') |
|||
:done() |
|||
:tag('td') |
|||
:css{ ['border-left'] = 'none' } |
|||
:wikitext('[[' .. args.output1 .. ']]' or 'Unknown') |
|||
:done() |
|||
:tag('td') |
|||
:css{ ['text-align'] = 'right' } |
|||
:wikitext(args.output1qty or 1) |
|||
:done() |
|||
:wikitext(currency_cell(output1TotalValue)) |
|||
:done() |
|||
:END() |
|||
-- Add profit data |
|||
:tag('tr') |
|||
:addClass('currency') |
|||
:tag('th') |
|||
:attr{ colspan = '3' } |
|||
:wikitext('Profit') |
|||
:done() |
|||
:wikitext(currency_cell(output1TotalValue - rawMaterialCost)) |
|||
:done() |
|||
return out |
|||
end |
end |
||
function p._extractRawMaterials(args) |
|||
local rawMaterials = {} |
|||
for i = 1, 9 do |
|||
local materialKey = "rawmat" .. i |
|||
local quantityKey = "rawmat" .. i .. "qty" |
|||
local materialValue = args[materialKey] |
|||
if materialValue and materialValue ~= "" then |
|||
local quantityValue = tonumber(args[quantityKey]) or 1 |
|||
table.insert(rawMaterials, { name = materialValue, quantity = quantityValue }) |
|||
end |
|||
end |
|||
return rawMaterials |
|||
end |
|||
--This function takes a table containing the raw materials params received from the calling template. |
|||
--For each of the raw materials, a query will be executed to see if it has the property 'Uses item'. |
|||
--If it does, that means that the 'raw material' is actually an 'intermediate material' as it is itself created. |
|||
--The materials required to create this intermediate material will be retrieved and added to the rawMaterials table. |
|||
--This allows for a full recipe to be shown where only intermediate ingredients were provided. |
|||
function p._getTrueRawMaterials(argsMaterials) |
|||
local rawMaterials = {} |
|||
local intermediateMaterials = {} |
|||
local function _processMaterial(material, quantity) |
|||
if material then |
|||
local result = mw.smw.ask('[[:+]][[' .. material .. ']]|?Uses item|?Uses item_and_quantity') |
|||
if result and result[1] and result[1]["Uses item"] then |
|||
-- The item is an intermediate material, add it to intermediateMaterials |
|||
table.insert(intermediateMaterials, { ["name"] = material, ["quantity"] = quantity }) |
|||
-- Add the raw materials used by this intermediate material to rawMaterials |
|||
local usesItems = result[1]["Uses item"] |
|||
local quantities = result[1]["Uses item and quantity"] |
|||
if type(usesItems) == "table" then |
|||
for index, usedItem in ipairs(usesItems) do |
|||
local pageName = usedItem:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "") |
|||
local qty = 1 |
|||
if quantities and type(quantities) == "table" then |
|||
local quantityString = quantities[index] |
|||
local _, q = quantityString:match("(.-),(%d+)") |
|||
qty = tonumber(q) or 1 |
|||
end |
|||
_processMaterial(pageName, qty) |
|||
end |
|||
else |
|||
local pageName = usesItems:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "") |
|||
local qty = 1 |
|||
if quantities and type(quantities) == "string" then |
|||
local _, q = quantities:match("(.-),(%d+)") |
|||
qty = tonumber(q) or 1 |
|||
end |
|||
_processMaterial(pageName, qty) |
|||
end |
|||
else |
|||
-- The item is a raw material, add it to rawMaterials |
|||
table.insert(rawMaterials, { ["name"] = material, ["quantity"] = quantity }) |
|||
end |
|||
end |
|||
end |
|||
-- Iterate over the initial argsMaterials |
|||
for _, item in pairs(argsMaterials) do |
|||
if item["name"] then |
|||
_processMaterial(item["name"], item["quantity"]) |
|||
end |
|||
end |
|||
return { rawMaterials = rawMaterials, intermediateMaterials = intermediateMaterials } |
|||
end |
|||
function p._reverseTable(t) |
|||
local reversed = {} |
|||
for i = #t, 1, -1 do |
|||
table.insert(reversed, t[i]) |
|||
end |
|||
return reversed |
|||
end |
|||
return p |
return p |
Latest revision as of 20:03, 24 November 2024
Module documentation
This documentation is transcluded from Module:Sandbox/User:The Gaffer/Modules/Infobox Recipe/doc. [edit] [history] [purge]
Module:Sandbox/User:The Gaffer/Modules/Infobox Recipe requires
.TODO
require('strict')
require('Module:Mw.html extension')
local currency = require('Module:Currency')
local hc = require('Module:Param Parse').has_content
local yn = require('Module:Yesno')
local editButton = require('Module:Edit button')
local function currency_cell(amount)
return currency._cell(amount, { html = 'yes' })
end
local p = {}
function p._main(frame)
local args = frame:getParent().args
--If set to true, will check if any of the items passed as a rawmaterialparam are actually intermediate materials. Will then change the display order of the infobox.
local showFullRecipe = yn(args.showFull or 'no', false)
--Get each of the rawmatX parameters from params and store their values in a new table
local argsMaterials = p._extractRawMaterials(args)
--empty tables to hold materials
local rawMaterials = {}
local intermediateMaterials = {}
--counter for total price of raw materials
local rawMaterialCost = 0
--get the value for the output product
local output1Value = 0
if args.output1 then
output1Value = mw.smw.ask('[[:+]][[' .. args.output1 .. ']]|?Value|limit=1') or 0
end
--Calculate total value of output material(s)
local output1TotalValue = 0
if type(output1Value) == "table" then
if output1Value[1]['Value'] ~= nil then
output1TotalValue = output1Value[1]['Value'] * (tonumber(args.output1qty) or 1)
else
output1TotalValue = 0
end
end
--Check if any of the raw mats provided are intermediate products, if they are, return their own raw materials
if showFullRecipe then
local Materials = p._getTrueRawMaterials(argsMaterials)
if next(Materials) ~= nil then
rawMaterials = Materials.rawMaterials
intermediateMaterials = p._reverseTable(Materials.intermediateMaterials)
end
else
rawMaterials = argsMaterials
end
--Simple query to get the shop buy price for the provided material, if no buy price is available returns 0
local function getBuyPrice(material)
local queryResult = mw.smw.ask('[[:+]][[Sold item::' .. material['name'] .. ']]|?Shop buy price|sort=Shop buy price|order=asc|limit=1') or 0
if type(queryResult) == "table" and queryResult[1]['Shop buy price'] then
return tonumber(queryResult[1]['Shop buy price']) or 0
end
return 0
end
--If one of the raw materials provided as a param has been identified as an intermediate material then get the facility it is created at to display in the intermediate Ingredient row
local function getFacility(material)
local result = mw.smw.ask('[[:+]][[' .. material .. ']]|?Uses facility|limit=1') or 'unknown'
local pageName = ''
if result and result[1] and result[1]["Uses facility"] then
local usesFac = result[1]["Uses facility"]
pageName = usesFac:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
end
return pageName
end
--Set SMW properties
for _,material in ipairs(argsMaterials) do
mw.smw.set({
["Uses item"] = material.name,
["Uses item_and_quantity"] = material.name .. ',' .. tostring(material.quantity)
})
end
if args.facility then
mw.smw.set({
["Uses facility"] = args.facility
})
end
--Creates a row suitable for the raw materials section of the infobox.
local function createRawMaterialRow(item)
local materialBuyPrice = getBuyPrice(item) * (item.quantity or 1)
rawMaterialCost = rawMaterialCost + materialBuyPrice
return mw.html.create('tr')
:tag('td')
:css{ ['border-right'] = 'none' }
:wikitext('[[File:' .. item.name .. '.png|30px|link=' .. item.name .. ']]')
:done()
:tag('td')
:css{ ['border-left'] = 'none' }
:wikitext('[[' .. item.name .. ']]')
:done()
:tag('td')
:css{ ['text-align'] = 'right' }
:wikitext(item.quantity or 1)
:done()
:wikitext(currency_cell(materialBuyPrice))
:done()
end
--Creates a row suitable for the intermediate materials section of the infobox.
local function createIntermediateMaterialRow(item)
local facility = getFacility(item.name)
return mw.html.create('tr')
:tag('td')
:css{ ['border-right'] = 'none' }
:wikitext('[[File:' .. item.name .. '.png|30px|link=' .. item.name .. ']]')
:done()
:tag('td')
:css{ ['border-left'] = 'none' }
:wikitext('[[' .. item.name .. ']]')
:done()
:tag('td')
:css{ ['text-align'] = 'right' }
:wikitext(item.quantity or 1)
:done()
:tag('td')
:attr{ colspan = '10' }
:css{ ['text-align'] = 'left' }
:wikitext('[[File:' .. facility .. '.png|30px|link=' .. facility .. ']] [[' .. facility .. ']]')
:done()
:done()
end
-- Recipe Table Head
local out = mw.html.create('table')
:addClass('wikitable')
:tag('tr')
:tag('th')
:attr{ colspan = '13' }
:wikitext('Requirements')
:done()
:done()
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('Facility')
:done()
:tag('td')
:attr{ colspan = '11' }
:wikitext(hc(args.facility) and ('[[File:%s.png|link=%s|30px]] [[%s]]'):format(args.facility, args.facility, args.facility) or editButton("'''?''' (edit)"))
:done()
:done()
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('Profession')
:done()
:tag('th')
:wikitext('Level')
:done()
:tag('th')
:attr{ colspan = '10' }
:wikitext('XP')
:done()
:done()
:tag('tr')
:tag('td')
:attr{ colspan = '2' }
:css{ ['text-align'] = 'center' }
:wikitext(hc(args.profession) and ('[[' .. args.profession .. ']]') or editButton("'''?''' (edit)"))
:done()
:tag('td')
:css{ ['text-align'] = 'center' }
:wikitext(hc(args.level) and (args.level) or editButton("'''?''' (edit)"))
:done()
:tag('td')
:attr{ colspan = '10' }
:css{ ['text-align'] = 'center' }
:wikitext(hc(args.exp) and (args.exp) or editButton("'''?''' (edit)"))
:done()
:done()
-- Add raw materials
-- Headers
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('Raw Ingredient')
:done()
:tag('th')
:wikitext('Quantity')
:done()
:tag('th')
:attr{ colspan = '10' }
:wikitext('Cost')
:done()
:done()
-- Values
for _, material in ipairs(rawMaterials) do
out:node(createRawMaterialRow(material))
end
-- Add total raw cost
out
:tag('tr')
:tag('th')
:attr{ colspan = '3' }
:wikitext('Total Raw cost')
:done()
:wikitext(currency_cell(rawMaterialCost))
:done()
-- Add Intermediate steps if required
-- Headers
if next(intermediateMaterials) ~= nil then
-- Headers
out
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('Intermediate Ingredient')
:done()
:tag('th')
:wikitext('Quantity')
:done()
:tag('th')
:attr{ colspan = '10' }
:wikitext('Faciltity')
:done()
:done()
-- Values
for _, material in ipairs(intermediateMaterials) do
out:node(createIntermediateMaterialRow(material))
end
end
-- Add output data
-- Headers
out
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('Output')
:done()
:tag('th')
:wikitext('Quantity')
:done()
:tag('th')
:attr{ colspan = '10' }
:wikitext('Value')
:done()
:done()
:IF(args.output1)
-- Values
:tag('tr')
:tag('td')
:css{ ['border-right'] = 'none' }
:wikitext('[[File:' .. args.output1 .. '.png|30px|link=' .. args.output1 .. ']]' or 'Unknown')
:done()
:tag('td')
:css{ ['border-left'] = 'none' }
:wikitext('[[' .. args.output1 .. ']]' or 'Unknown')
:done()
:tag('td')
:css{ ['text-align'] = 'right' }
:wikitext(args.output1qty or 1)
:done()
:wikitext(currency_cell(output1TotalValue))
:done()
:END()
-- Add profit data
:tag('tr')
:addClass('currency')
:tag('th')
:attr{ colspan = '3' }
:wikitext('Profit')
:done()
:wikitext(currency_cell(output1TotalValue - rawMaterialCost))
:done()
return out
end
function p._extractRawMaterials(args)
local rawMaterials = {}
for i = 1, 9 do
local materialKey = "rawmat" .. i
local quantityKey = "rawmat" .. i .. "qty"
local materialValue = args[materialKey]
if materialValue and materialValue ~= "" then
local quantityValue = tonumber(args[quantityKey]) or 1
table.insert(rawMaterials, { name = materialValue, quantity = quantityValue })
end
end
return rawMaterials
end
--This function takes a table containing the raw materials params received from the calling template.
--For each of the raw materials, a query will be executed to see if it has the property 'Uses item'.
--If it does, that means that the 'raw material' is actually an 'intermediate material' as it is itself created.
--The materials required to create this intermediate material will be retrieved and added to the rawMaterials table.
--This allows for a full recipe to be shown where only intermediate ingredients were provided.
function p._getTrueRawMaterials(argsMaterials)
local rawMaterials = {}
local intermediateMaterials = {}
local function _processMaterial(material, quantity)
if material then
local result = mw.smw.ask('[[:+]][[' .. material .. ']]|?Uses item|?Uses item_and_quantity')
if result and result[1] and result[1]["Uses item"] then
-- The item is an intermediate material, add it to intermediateMaterials
table.insert(intermediateMaterials, { ["name"] = material, ["quantity"] = quantity })
-- Add the raw materials used by this intermediate material to rawMaterials
local usesItems = result[1]["Uses item"]
local quantities = result[1]["Uses item and quantity"]
if type(usesItems) == "table" then
for index, usedItem in ipairs(usesItems) do
local pageName = usedItem:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
local qty = 1
if quantities and type(quantities) == "table" then
local quantityString = quantities[index]
local _, q = quantityString:match("(.-),(%d+)")
qty = tonumber(q) or 1
end
_processMaterial(pageName, qty)
end
else
local pageName = usesItems:gsub("%[%[", ""):gsub("%]%]", ""):gsub("|.*", ""):gsub("^:", "")
local qty = 1
if quantities and type(quantities) == "string" then
local _, q = quantities:match("(.-),(%d+)")
qty = tonumber(q) or 1
end
_processMaterial(pageName, qty)
end
else
-- The item is a raw material, add it to rawMaterials
table.insert(rawMaterials, { ["name"] = material, ["quantity"] = quantity })
end
end
end
-- Iterate over the initial argsMaterials
for _, item in pairs(argsMaterials) do
if item["name"] then
_processMaterial(item["name"], item["quantity"])
end
end
return { rawMaterials = rawMaterials, intermediateMaterials = intermediateMaterials }
end
function p._reverseTable(t)
local reversed = {}
for i = #t, 1, -1 do
table.insert(reversed, t[i])
end
return reversed
end
return p