Module:Infobox Recipe: Difference between revisions
Jump to navigation
Jump to search
Content added Content deleted
(swap positions of XP and Album XP, replace "XP" with "Experience" where there is space, make "Experience", "KP", and "Album" be links to their own pages) |
(quest items will link to the quest instead of displaying xp or kp) |
||
Line 53: | Line 53: | ||
end |
end |
||
end |
end |
||
-- if the recipe is part of a quest |
|||
args.quest = args.quest or false |
|||
--Set SMW properties early, so latter parts can potentially use it. |
--Set SMW properties early, so latter parts can potentially use it. |
||
Line 201: | Line 204: | ||
:done() |
:done() |
||
:done() |
:done() |
||
: |
:IF(not args.quest) |
||
:tag(' |
:tag('tr') |
||
: |
:tag('th') |
||
⚫ | |||
:wikitext('[[Experience]]') |
:wikitext('[[Experience]]') |
||
⚫ | |||
⚫ | |||
:attr{ colspan = '11' } |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
:done() |
:done() |
||
:END() |
|||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
⚫ | |||
:done() |
|||
:tag('tr') |
:tag('tr') |
||
:tag('th') |
:tag('th') |
||
Line 241: | Line 246: | ||
:wikitext('Level') |
:wikitext('Level') |
||
:done() |
:done() |
||
: |
:IF(not args.quest) |
||
: |
:tag('th') |
||
:attr{ colspan = '5' } |
|||
:wikitext('[[Knowledge|KP]]') |
:wikitext('[[Knowledge|KP]]') |
||
⚫ | |||
: |
:done() |
||
: |
:tag('th') |
||
:attr{ colspan = '5' } |
|||
:wikitext('[[Album|Album XP]]') |
:wikitext('[[Album|Album XP]]') |
||
⚫ | |||
⚫ | |||
⚫ | |||
:tag('th') |
|||
:attr{ colspan = '10' } |
|||
⚫ | |||
⚫ | |||
:END() |
|||
:done() |
:done() |
||
:tag('tr') |
:tag('tr') |
||
Line 260: | Line 272: | ||
:wikitext(hc(args.level) and (args.level) or editButton("'''?''' (edit)").. '[[Category:Needs level recipe]]') |
:wikitext(hc(args.level) and (args.level) or editButton("'''?''' (edit)").. '[[Category:Needs level recipe]]') |
||
:done() |
:done() |
||
: |
:IF(not args.quest) |
||
: |
:tag('td') |
||
: |
:attr{ colspan = '5' } |
||
:css{ ['text-align'] = 'center' } |
|||
:wikitext(hc(args.kp) and ('%s%%'):format(args.kp) or editButton("'''?''' (edit)").. '[[Category:Needs knowledge recipe]]') |
:wikitext(hc(args.kp) and ('%s%%'):format(args.kp) or editButton("'''?''' (edit)").. '[[Category:Needs knowledge recipe]]') |
||
⚫ | |||
: |
:done() |
||
: |
:tag('td') |
||
: |
:attr{ colspan = '5' } |
||
:css{ ['text-align'] = 'center' } |
|||
⚫ | |||
:wikitext(album_xp or 'Unknown') |
|||
⚫ | |||
:done() |
|||
:ELSE() |
|||
:tag('td') |
|||
:attr{ colspan = '10' } |
|||
:css{ ['text-align'] = 'center' } |
|||
:wikitext(args.quest) |
|||
:done() |
|||
:END() |
|||
:done() |
:done() |
||
Revision as of 20:48, 9 December 2024
Module documentation
This documentation is transcluded from Module:Infobox Recipe/doc. [edit] [history] [purge]
Module:Infobox Recipe's function _main is invoked by Template:Infobox Recipe.
Module:Infobox Recipe requires
.Module:Infobox Recipe loads data from Module:Experience/data.
This module invoked using the command
{{#invoke:Infobox Recipe|_main}}
It provides this functionality to Template:Infobox Recipe
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 search = require('Module:RecipeTreeSearch')
local editButton = require('Module:Edit button')
local album_xp_data = mw.loadData('Module:Experience/data').album
local lang = mw.language.getContentLanguage()
local function formatNum(n)
if n == nil then
return ''
end
return lang:formatNum(n)
end
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
-- if the recipe is part of a quest
args.quest = args.quest or false
--Set SMW properties early, so latter parts can potentially use it.
local smw_properties = {
['Uses item'] = {},
-- these are for when a recipe is called by a subsequent recipe that uses showFull
['Uses facility'] = args.facility,
-- these are for generating tables of profession xp rates and profits
['Activity XP'] = args.exp,
['Activity album XP'] = album_xp_data[tonumber(args.level)],
['Activity KP'] = args.kp,
['Activity duration'] = args.duration,
['Activity level'] = args.level and tonumber(args.level),
['Recipe JSON'] = mw.text.jsonEncode({
xp = args.exp and tonumber(args.exp),
kp = args.kp and tonumber(args.kp),
duration = args.duration,
materials = argsMaterials,
profession = args.profession,
level = args.level and tonumber(args.level),
-- Make sure to update this when multiple outputs are supported
output = {
{ name = args.output1, quantity = tonumber(args.output1qty) or 1 },
}
}),
-- Make sure to update this when multiple outputs are supported to be a list of all outputs
['Recipe output'] = { args.output1 }
}
for _, material in ipairs(argsMaterials) do
table.insert(smw_properties['Uses item'], material.name)
end
mw.smw.set(smw_properties)
--Check if any of the raw mats provided are intermediate products, if they are, return their own raw materials
if showFullRecipe then
-- Use the RecipeTreeSearch module to get all the rawMaterials needed to make output1
local searchResult = search.treeSearch(argsMaterials)
rawMaterials = searchResult.materials
intermediateMaterials = p._reverseTable(searchResult.intermediateMaterials)
-- display XP and duration totals for multi-step process
args.displayXP = tonumber(args.exp) and searchResult.xp and searchResult.xp + tonumber(args.exp)
args.displayDuration = tonumber(args.duration) and searchResult.duration and searchResult.duration + tonumber(args.duration)
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
local album_xp = album_xp_data[tonumber(args.level)]
if (album_xp) then
album_xp = formatNum(album_xp)..' xp'
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()
:node(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'] = 'center' }
: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' }
:css{ ['text-align'] = 'center' }
:wikitext(hc(args.facility) and ('[[File:%s.png|link=%s|30px]] [[%s]]'):format(args.facility, args.facility, args.facility) or editButton("'''?''' (edit)").. '[[Category:Needs facility recipe]]')
:done()
:done()
:IF(not args.quest)
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('[[Experience]]')
:done()
:tag('td')
:attr{ colspan = '11' }
:css{ ['text-align'] = 'center' }
:wikitext(hc(args.exp) and (formatNum(tonumber(args.exp))) or editButton("'''?''' (edit)").. '[[Category:Needs experience recipe]]')
:IF(showFullRecipe)
:wikitext(' (')
:wikitext(hc(args.displayXP) and (formatNum(tonumber(args.displayXP))) or ("'''?'''"))
:wikitext(' total)')
:END()
:done()
:done()
:END()
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('Duration')
:done()
:tag('td')
:attr{ colspan = '11' }
:css{ ['text-align'] = 'center' }
:wikitext(hc(args.duration) and ('%s seconds'):format(args.duration) or editButton("'''?''' (edit)").. '[[Category:Needs duration recipe]]')
:IF(showFullRecipe)
:wikitext(' (')
:wikitext(hc(args.displayDuration) and (args.displayDuration) or ("'''?'''"))
:wikitext(' total)')
:END()
:done()
:done()
:tag('tr')
:tag('th')
:attr{ colspan = '2' }
:wikitext('Profession')
:done()
:tag('th')
:wikitext('Level')
:done()
:IF(not args.quest)
:tag('th')
:attr{ colspan = '5' }
:wikitext('[[Knowledge|KP]]')
:done()
:tag('th')
:attr{ colspan = '5' }
:wikitext('[[Album|Album XP]]')
:done()
:ELSE()
:tag('th')
:attr{ colspan = '10' }
:wikitext('Quest Recipe')
:done()
:END()
:done()
:tag('tr')
:tag('td')
:attr{ colspan = '2' }
:css{ ['text-align'] = 'center' }
:wikitext(hc(args.profession) and ('[[' .. args.profession .. ']]') or editButton("'''?''' (edit)").. '[[Category:Needs profession recipe]]')
:done()
:tag('td')
:css{ ['text-align'] = 'center' }
:wikitext(hc(args.level) and (args.level) or editButton("'''?''' (edit)").. '[[Category:Needs level recipe]]')
:done()
:IF(not args.quest)
:tag('td')
:attr{ colspan = '5' }
:css{ ['text-align'] = 'center' }
:wikitext(hc(args.kp) and ('%s%%'):format(args.kp) or editButton("'''?''' (edit)").. '[[Category:Needs knowledge recipe]]')
:done()
:tag('td')
:attr{ colspan = '5' }
:css{ ['text-align'] = 'center' }
:wikitext(album_xp or 'Unknown')
:done()
:ELSE()
:tag('td')
:attr{ colspan = '10' }
:css{ ['text-align'] = 'center' }
:wikitext(args.quest)
:done()
:END()
: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()
:node(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
mw.logObject(material)
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()
:node(currency_cell(output1TotalValue))
:done()
:END()
-- Add profit data
:tag('tr')
:addClass('currency')
:tag('th')
:attr{ colspan = '3' }
:wikitext('Profit')
:done()
:node(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
function p._reverseTable(t)
local reversed = {}
for i = #t, 1, -1 do
table.insert(reversed, t[i])
end
return reversed
end
return p