Module:Infobox cooking
Documentation for this module may be created at Module:Infobox cooking/doc
--<nowiki>
--[=[<pre>
-- Implements [[Template:Databox Cooking]]
--]=]
local p = {}
local yesno = require('Module:Yesno')
local params = require('Module:Paramtest')
local commas = require('Module:Addcommas')
local geprice = require('Module:Exchange')._price
local skillpic = require('Module:Skill_clickpic')._main
local mapicons = require('Module:Map_clickpic')
local editbutton = require('Module:Edit button')
local onmain = require('Module:Mainonly').on_main
local cookimg = '[[File:Cooking-icon.png|21x21px|link=Cooking|alt=Cooking]]'
function p.main(frame)
local args = frame:getParent().args
--[[
Function to handle all the materials listed
Creates a table to pass to _main() consisting of
* Item name, as a wikilink
* Item image, as a wikilink, includes link to page
* Quantity
* Formatted price for display
* Clean price for calculations
If the parameter mat# is defined and not blank
Every parameter (mat#img, mat#qty, mat#price) will be looked for as well
--]]
local function mat_list()
local ret_list = {}
for i=1,10,1 do
local mat = args['mat'..i]
if mat and params.has_content(mat) then
local name = mat
-- 2 separate prices
-- 1 for display
-- 1 for calculation
local price,price_raw
local qty = params.default_to(args['mat'..i..'qty'],'1')
local img = params.default_to(args['mat'..i..'img'],
name..'.png')
:gsub('File:','')
local price_v = params.default_to(args['mat'..i..'price'],'/')
-- gemw = use exchange price
if price_v:lower() == 'gemw' then
price_raw = geprice(name)
price = commas._add(price_raw)
-- parseable as number = use that
elseif tonumber(commas._strip(price_v),10) then
price_raw = tonumber(commas._strip(price_v),10)
price = commas._add(price_raw)
-- Some untradeables have a distinct market price
-- because of their materials
-- The template {{GETotal}} will help here
-- Look for template call
elseif price_v:find('{{.*}}') then
price_raw = frame:preprocess(price_v)
price = commas._add(price_raw)
-- price disabled
-- use N/A for display and 0 for calculations
elseif yesno(price_v, true) == false then
price_raw = 0
price = 'N/A'
-- everything else
else
price_raw = geprice(name)
price = commas._add(price_raw)
end
table.insert(ret_list, {
name = '[['..name..']]',
name_raw = name,
price = price,
price_raw = price_raw,
quantity = qty,
image = '[[File:'..img..'|link='..name..']]',
image_raw = img
} )
end
end
return ret_list
end
-- Fetching and formatting parameters starting here
local item_name,item_image,
ticks,level,
burnlevel,gauntlets,
fireburn,firegaunt,
cookmatic,
experience,xpfire,
tools,method,
quest,
servings,lphealed,
instructions,totalvar = params.defaults{
{args.name,mw.title.getCurrentTitle().text},
{args.image,nil},
{args.ticks,editbutton('?')},
{args.level,editbutton('?')},
{args.noburnlevel,nil},
{args.gauntlets,nil},
{args.fireburn,nil},
{args.firegaunt,nil},
{args.cookmatic,nil},
{args.xp,editbutton('?')},
{args.xpfire,nil},
{args.tools,nil},
{args.method,nil},
{args.quest,nil},
{args.servings,1},
{args.lphealed,nil},
{args.instructions,nil},
{args.totalvar,nil}
}
local item_link = mw.title.getCurrentTitle().text
local members = yesno(args.members) and '[[File:P2P icon.png|21px|link=]] Members only' or '[[File:F2P icon.png|21px|link=]] Free-to-play'
-- Add [[File: and |link=...]] to image, if it's defined
if item_image then
item_image = '[[File:'..item_image:gsub('File:','')..'|link='..item_link..']]'
-- anti-redlink
elseif mw.title.getCurrentTitle().text == 'Databox Recipe/preload'
or mw.title.getCurrentTitle().text == 'PreloadPage/Orphanage' then
item_image = ''
else
item_image = '[[File:'..item_name..'.png|link='..item_name..']]'
end
-- Heat source
local heat = yesno(args.heat,true)
if heat == nil then
heat = true
end
-- Requires range or fire
if yesno(args.range,false) == true then
heat = 'range'
elseif yesno(args.range,false) == false then
heat = 'fire'
end
-- Brewing
local brewing = false
if yesno(args.brewing,false) then
brewing = true
heat = false
end
-- Water source
local water = false
if yesno(args.water,false) then
water = true
end
-- Tables to pass; call above functions
local materials = mat_list()
-- Check servings and lp are numbers
if tonumber(servings,10) then
servings = tonumber(servings,10)
else
servings = 1
end
if lphealed and tonumber(lphealed,10) then
lphealed = tonumber(lphealed,10)
else
lphealed = nil
end
-- Burn level
if burnlevel then
if tonumber(burnlevel,10) then
burnlevel = tonumber(burnlevel,10)
elseif string.lower(burnlevel) == 'none' or yesno(burnlevel) == false then
burnlevel = nil
end
else
burnlevel = nil
end
-- Look for GE price unless disabled, nil if disabled
local item_ge_v = string.lower(args.geValue or 'yes')
local item_gep
if item_ge_v == 'gemw' then
item_gep = geprice(item_name)
elseif tonumber(item_ge_v,10) then
item_gep = tonumber(item_ge_v,10)
elseif yesno(item_ge_v) == false then
item_gep = nil
else
item_gep = geprice(item_name)
end
return p._main{ frame,
item_name,
item_image,
item_link,
item_gep,
level,
burnlevel,
gauntlets,
fireburn,
firegaunt,
cookmatic,
experience,
xpfire,
tools,
brewing,
water,
heat,
quest,
members,
ticks,
method,
materials,
instructions,
servings,
lphealed,
totalvar
}
end
function p._main(...)
-- Unpack parameters
local frame,
item_name,item_image,
item_link,item_gep,
level,burnlevel,
gauntlets,fireburn,
firegaunt,cookmatic,
experience,xpfire,
tools,brewing,water,
heat,quest,members,
ticks,method,
materials,instructions,
servings,lphealed,
totalvar = unpack(...)
local ret = mw.html.create('table')
ret:addClass('wikitable')
:css({ width = '50%',
['max-width'] = '450px' })
-- Caption header
local caption = item_image..' '..item_name
if method then
caption = caption..string.format('<br /><i>(%s)</i>', method)
end
ret:tag('caption'):wikitext(caption):done()
ret :tag('tr')
:css('text-align','center')
:tag('th')
:css('width','20%')
:wikitext(cookimg..' Level')
:done()
:tag('th')
:css('width','20%')
:wikitext(cookimg..' XP')
:done()
:tag('th')
:css('width','30%')
:attr('title','Ticks per action')
:attr('colspan','2')
:css('cursor', 'help')
:wikitext('[[File:Hourglass.png|link=]]')
:done()
:tag('th')
:css('width','30%')
:css('cursor', 'help')
:attr('title','Grand Exchange median price')
:attr('colspan','2')
:wikitext('[[File:Make-X GE icon.png|link=]]')
:done()
:done()
local xpdisp = experience
if xpfire then
xpdisp = '<span title="Normal xp" style="cursor: help;">'..experience..' </span><span title="Cooking on bonfire" style="cursor: help;"> ('..xpfire..')</span>'
end
local ticktd = mw.html.create('td')
:attr('colspan','2')
if tonumber(ticks,10) then
local secs = tonumber(ticks,10) * 0.6
ticktd:attr('title',ticks..' ticks ('..secs..' seconds) per action')
:css('cursor', 'help')
:wikitext(ticks..' ('..secs..'s) ')
else
ticktd:wikitext(ticks)
end
local gedisp = '-'
if item_gep then
gedisp = commas._add(item_gep)
end
ret :tag('tr')
:css('text-align','center')
:tag('td') :wikitext(level) :done()
:tag('td') :wikitext(xpdisp) :done()
:node(ticktd)
:tag('td') :attr('colspan','2'):wikitext(gedisp) :done()
:done()
if lphealed then
local lptxt = '<span title="Life points healed" style="cursor: help;">'..lphealed..'</span>'
if servings > 1 then
lptxt = '<span title="Per serving" style="cursor: help;">'..commas._add(lphealed)..' </span><span title="Total" style="cursor: help;"> ('..commas._add(lphealed * servings)..')</span>'
end
ret:tag('tr')
:tag('th')
:wikitext('Servings')
:done()
:tag('td')
:attr('colspan','2')
:wikitext(servings)
:done()
:tag('th')
:attr('title','Life points')
:css('cursor', 'help')
:wikitext('[[File:Constitution-icon.png|21x21px|link=Life points|alt=Life points]] LP')
:done()
:tag('td')
:attr('colspan','2')
:wikitext(lptxt)
:done()
elseif servings > 1 then
ret:tag('tr')
:tag('th')
:wikitext('Servings')
:done()
:tag('td')
:attr('colspan','5')
:wikitext(servings)
:done()
end
ret:tag('tr')
:css('text-align','center')
:tag('th')
:attr('colspan','6')
:wikitext('Requirements')
:done()
:done()
if gauntlets or cookmatic then
local gctitle = '[[File:Cooking gauntlets.png|21x21px|link=Cooking gauntlets|alt=Cooking gauntlets]] Gauntlets'
if cookmatic then
gctitle = '[[File:Cooking range (Lumbridge Castle).png|21x21px|link=Cooking range (Lumbridge Castle)|alt=Cook-o-matic 25]] Cook-o-matic 25'
end
ret:tag('tr')
:tag('td')
:attr('colspan','2')
:wikitext('Burn level')
:done()
:tag('td')
:css('text-align','center')
:wikitext(burnlevel or editbutton('?'))
:done()
:tag('td')
:attr('colspan','2')
:wikitext(gctitle)
:done()
:tag('td')
:css('text-align','center')
:wikitext(gauntlets or cookmatic)
:done()
elseif burnlevel or heat then
ret:tag('tr')
:tag('td')
:attr('colspan','5')
:wikitext('Burn Level')
:done()
:tag('td')
:css('text-align','center')
:wikitext(burnlevel or editbutton('?'))
:done()
end
if fireburn or firegaunt then
if firegaunt then
ret:tag('tr')
:tag('td')
:attr('colspan','2')
:wikitext('[[File:Bonfire map icon.png|21x21px|link=Fire|alt=Fire]] Burn level (fire)')
:done()
:tag('td')
:css('text-align','center')
:wikitext(fireburn or editbutton('?'))
:done()
:tag('td')
:attr('colspan','2')
:wikitext('[[File:Bonfire map icon.png|21x21px|link=Fire|alt=Fire]][[File:Cooking gauntlets.png|21x21px|link=Cooking gauntlets|alt=Cooking gauntlets]] Gauntlets (f)')
:done()
:tag('td')
:css('text-align','center')
:wikitext(firegaunt or editbutton('?'))
:done()
else
ret:tag('tr')
:tag('td')
:attr('colspan','5')
:wikitext('[[File:Bonfire map icon.png|21x21px|link=Fire|alt=Fire]] Burn level (fire)')
:done()
:tag('td')
:css('text-align','center')
:wikitext(fireburn or editbutton('?'))
:done()
end
end
-- Quest requirement
if quest then
ret:tag('tr')
:tag('td')
:attr('colspan','6')
:wikitext(skillpic('quest')..' '..quest)
:done()
:done()
end
ret:tag('tr'):
tag('td')
:attr('colspan','6')
:wikitext(members)
:done()
:done()
if heat == 'range' then
ret:tag('tr')
:tag('td')
:attr('colspan','6')
:wikitext(mapicons._main('Range')..' Can only be cooked at a [[Range]]')
elseif heat == 'fire' then
ret:tag('tr')
:tag('td')
:attr('colspan','6')
:wikitext(mapicons._main('Bonfire')..' Can only be cooked at a [[fire]]')
elseif heat then
ret:tag('tr')
:tag('td')
:attr('colspan','6')
:wikitext('Requires a [[Range|range]] '..mapicons._main('Range')..' or a [[Fire|fire]] '..mapicons._main('Bonfire'))
end
if brewing then
ret:tag('tr')
:tag('td')
:attr('colspan','6')
:wikitext(mapicons._main('Brewing')..' Can only be brewed at a [[Brewery]]')
end
if water then
ret:tag('tr')
:tag('td')
:attr('colspan','6')
:wikitext(mapicons._main('Water source')..' Must be made at a [[water source]]')
end
if tools then
ret:tag('tr')
:tag('td')
:wikitext('Tools')
:done()
:tag('td')
:attr('colspan','5')
:wikitext(tools)
end
ret:tag('tr')
:tag('th')
:attr('colspan','6')
:css('text-align','center')
:wikitext('Ingredients')
:done()
:done()
:tag('tr')
:tag('th')
:attr('colspan','3')
:wikitext('Item')
:done()
:tag('th')
:css('width','15%')
:wikitext('Quantity')
:done()
:tag('th')
:css('width','15%')
:wikitext('Price')
:done()
:tag('th')
:wikitext('Total')
:done()
:done()
-- Materials
local total_price = 0
local valued_items = 0
-- Iterates through the tables in the table of materials
for i, v in ipairs(materials) do
-- Fetch all the variables
local mat_name = v.name
local mat_price = v.price
local mat_raw = v.price_raw
local mat_ttl
local mat_qty = v.quantity
local mat_img = v.image
-- If no price is given for item, delete total
-- Otherwise quantity * price each
if mat_raw == 0 then
mat_ttl = '-'
else
mat_ttl = mat_qty * mat_raw
end
-- If item total is a number
-- Add it to the overall total
-- Indicate this by incrementing valued item count
-- Done with total calculations, add commas to total for formatting
if type(mat_ttl) == 'number' then
total_price = total_price + mat_ttl
mat_ttl = commas._add(mat_ttl)
if mat_raw > 0 then
valued_items = valued_items + 1
end
end
ret:tag('tr')
:tag('td')
:css({ ['border-right'] = 'none',
['text-align'] = 'center' })
:wikitext(mat_img)
:done()
:tag('td')
:attr('colspan','2')
:css({ ['border-left'] = 'none',
['border-right'] = 'none',
['text-align'] = 'left' })
:wikitext(mat_name)
:done()
:tag('td')
:css({ ['border-left'] = 'none',
['border-right'] = 'none',
['text-align'] = 'right' })
:wikitext(commas._add(mat_qty))
:done()
:tag('td')
:css({ ['border-left'] = 'none',
['text-align'] = 'right' })
:wikitext(mat_price)
:done()
:tag('td')
:css('text-align','right')
:wikitext(mat_ttl)
:done()
:done()
end
-- If no materials found
-- Indicate nothing listed, add an edit button for the page
if #materials == 0 then
ret:tag('tr')
:tag('td')
:attr('colspan','6')
:css({ ['font-style'] = 'italic',
['text-align'] = 'center' })
:wikitext('Ingredients unlisted '..editbutton())
:done()
:done()
end
-- Total
-- Hide if less than 2 items have a value
if valued_items > 1 then
ret:tag('tr')
:tag('th')
:attr('colspan','5')
:css('text-align','right')
:wikitext('Total price')
:done()
:tag('td')
:css('text-align','right')
:wikitext(commas._add(total_price))
:done()
:done()
end
if type(totalvar) == 'string' and #totalvar > 0 then
mw.ext.VariablesLua.vardefine(totalvar, total_price)
end
-- Profit
if valued_items >= 1 and item_gep then
local profit = item_gep - total_price
local profclass = 'text-green'
if profit < 0 then
profclass = 'text-red'
end
ret:tag('tr')
:tag('th')
:attr('colspan','5')
:css('text-align','right')
:wikitext('Profit')
:done()
:tag('td')
:css('text-align','right')
:addClass(profclass)
:wikitext(commas._add(profit))
:done()
:done()
end
if instructions then
ret:tag('tr')
:tag('th')
:attr('colspan','6')
:css('text-align','center')
:wikitext('Instructions')
:done()
:done()
:tag('tr')
:tag('td')
:attr('colspan','6')
:wikitext(instructions)
end
-- SMW
if onmain then
local smw = {}
local jsonmats = {}
if materials then
smw['Made from item'] = {}
for _, v in ipairs(materials) do
table.insert(jsonmats, {
name = v.name_raw,
quantity = v.quantity,
image = v.image_raw
})
table.insert(smw['Made from item'],v.name_raw)
end
end
if tonumber(ticks,10) then
smw['Production ticks'] = ticks
end
local facilities = ''
if heat == 'range' then
facilities = 'Range'
elseif heat == 'fire' then
facilities = 'Fire'
elseif heat then
facilities = 'Range or Fire'
end
if brewing then
facilities = 'Brewing'
end
if water then
facilities = 'Water source'
end
local prodjson = {
product = item_name,
link = item_link,
image = item_image,
ticks = ticks,
improved = '',
method = method or '',
facility = facilities,
mats = jsonmats,
skill = 'Cooking',
level = tonumber(level) or '?',
exp = tonumber(experience) or '?',
skill2 = '?',
exp2 = '?',
level2 = '?',
skill3 = '?',
exp3 = '?',
level3 = '?',
quantity = 1
}
prodjson = mw.text.jsonEncode( prodjson )
smw['Production JSON'] = prodjson
mw.smw.set(smw)
end
-- Add categories
cats = {}
if not experience then
table.insert(cats,'Recipes missing xp')
end
if not tonumber(level,10) then
table.insert(cats,'Recipes missing skill level')
end
if not tonumber(ticks,10) and string.lower(ticks) ~= 'varies' then
table.insert(cats,'Recipes missing ticks')
end
for i, v in ipairs(cats) do
if (v ~= '') then
cats[i] = string.format('[[Category:%s]]',v)
end
end
return tostring(ret)..table.concat(cats,'')
end
return p