Difference between revisions of "Module:Sandbox/Broono/Item Recipes"
Jump to navigation
Jump to search
m (Attempt #2) |
m (Get ready for testing) |
||
| (2 intermediate revisions by the same user not shown) | |||
| Line 8: | Line 8: | ||
data.craftingAugmenting = mw.loadData('Module:CraftingAugmenting/data') | data.craftingAugmenting = mw.loadData('Module:CraftingAugmenting/data') | ||
data.items = mw.loadData('Module:Items/data') | data.items = mw.loadData('Module:Items/data') | ||
| + | |||
local COLLAPSIBLE = 7 | local COLLAPSIBLE = 7 | ||
local COLLAPSED = 15 | local COLLAPSED = 15 | ||
| + | local SORTABLE = 7 | ||
| Line 16: | Line 18: | ||
return s:match('^%s*(.-)%s*$') | return s:match('^%s*(.-)%s*$') | ||
end | end | ||
| − | |||
local function split(s, sep) | local function split(s, sep) | ||
| Line 28: | Line 29: | ||
return t | return t | ||
end | end | ||
| − | |||
function table.length(t) | function table.length(t) | ||
| Line 35: | Line 35: | ||
return count | return count | ||
end | end | ||
| − | |||
local function addItemIds(t, names) | local function addItemIds(t, names) | ||
| Line 46: | Line 45: | ||
table.insert(t, {['id'] = id}) | table.insert(t, {['id'] = id}) | ||
else | else | ||
| − | table.insert(t, {[' | + | table.insert(t, {['error'] = {'name', name}}) |
end | end | ||
end | end | ||
end | end | ||
end | end | ||
| − | |||
local function addOtherItemFields(t) | local function addOtherItemFields(t) | ||
for i in pairs(t) do | for i in pairs(t) do | ||
| − | if | + | if t[i].id then |
local id = tostring(t[i].id) | local id = tostring(t[i].id) | ||
local craftingStats | local craftingStats | ||
| − | if data.items[id].craftingStats then | + | if data.items[id] and data.items[id].craftingStats then |
craftingStats = data.items[id].craftingStats | craftingStats = data.items[id].craftingStats | ||
| + | elseif data.items[id] then | ||
| + | craftingStats = data.items[id] | ||
else | else | ||
| − | + | t[i].error = { 'id', t[i].id } | |
| + | end | ||
| + | if not t[i].error then | ||
| + | t[i].name = data.items[id].name | ||
| + | t[i].level = craftingStats.level | ||
| + | t[i].experience = craftingStats.experience | ||
| + | t[i].category = craftingStats.category | ||
end | end | ||
| − | t[i]. | + | else |
| − | + | t[i].error = {'id', 'nil'} | |
| − | |||
| − | |||
end | end | ||
end | end | ||
end | end | ||
| − | |||
local function addRecipes(t) | local function addRecipes(t) | ||
for i in pairs(t) do | for i in pairs(t) do | ||
| − | + | local id = tostring(t[i].id) | |
| − | + | if data.craftingAugmenting[id] and not t[i].error then | |
t[i].recipes = {} | t[i].recipes = {} | ||
if data.craftingAugmenting[id].crafting then | if data.craftingAugmenting[id].crafting then | ||
| Line 92: | Line 95: | ||
t[i].skill = 'Smithing' | t[i].skill = 'Smithing' | ||
end | end | ||
| + | elseif not t[i].error then | ||
| + | t[i].error = {'recipe', id .. ' (' .. t[i].name .. ')'} | ||
end | end | ||
end | end | ||
end | end | ||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
| − | |||
local function generateTableRecipe(t) | local function generateTableRecipe(t) | ||
local ingredients = {} | local ingredients = {} | ||
| Line 186: | Line 106: | ||
local name = data.items[id].name | local name = data.items[id].name | ||
local image = img._img({name, 30}) | local image = img._img({name, 30}) | ||
| − | |||
table.insert(ingredients, image .. ' x'.. addSeparator._addSeparator({amt})) | table.insert(ingredients, image .. ' x'.. addSeparator._addSeparator({amt})) | ||
end | end | ||
return table.concat(ingredients, ', ') | return table.concat(ingredients, ', ') | ||
end | end | ||
| − | |||
local function generateTableBody(t) | local function generateTableBody(t) | ||
| Line 202: | Line 120: | ||
local rowspan = 0 | local rowspan = 0 | ||
| − | if | + | if t[i].error then |
| − | + | local e | |
| − | + | if t[i].error[1] == 'recipe' then | |
| + | e = 'Could not find a recipe for item with id: ' .. t[i].error[2] | ||
| + | else | ||
| + | e = '\'\'Could not find item with ' .. t[i].error[1] .. ': ' | ||
| + | e = e ..'\'\'\'' .. t[i].error[2] .. '\'\'\'.' | ||
| + | if t[i].error[1] == 'name' then | ||
| + | e = e .. ' Please check spelling or update data modules.' | ||
| + | end | ||
| + | end | ||
row:tag('td') | row:tag('td') | ||
:css('text-align', 'center') | :css('text-align', 'center') | ||
:attr('colspan', 5) | :attr('colspan', 5) | ||
| − | :wikitext( | + | :wikitext(e) |
else | else | ||
rowspan = table.length(t[i].recipes) | rowspan = table.length(t[i].recipes) | ||
| Line 233: | Line 159: | ||
local skill | local skill | ||
if t[i].category then | if t[i].category then | ||
| − | skill = | + | skill = img._img({t[i].skill, 30, word='1', alt=''}) .. ' (' .. t[i].category .. '): ' .. t[i].level |
else | else | ||
| − | skill = | + | skill = img._img({t[i].skill, 30, word='1', alt=''}) .. ': ' .. t[i].level |
end | end | ||
row:node(mw.html.create('td') | row:node(mw.html.create('td') | ||
| Line 266: | Line 192: | ||
return tbody | return tbody | ||
end | end | ||
| − | |||
local function generateTableHead() | local function generateTableHead() | ||
| Line 299: | Line 224: | ||
return thead | return thead | ||
end | end | ||
| − | |||
local function generateTable(t) | local function generateTable(t) | ||
| Line 306: | Line 230: | ||
tbl | tbl | ||
:addClass('wikitable') | :addClass('wikitable') | ||
| − | :addClass('sortable') | + | if table.length(t) > SORTABLE then tbl:addClass('sortable') end |
if table.length(t) > COLLAPSIBLE then tbl:addClass('mw-collapsible') end | if table.length(t) > COLLAPSIBLE then tbl:addClass('mw-collapsible') end | ||
if table.length(t) > COLLAPSED then tbl:addClass('mw-collapsed') end | if table.length(t) > COLLAPSED then tbl:addClass('mw-collapsed') end | ||
| Line 315: | Line 239: | ||
return tbl | return tbl | ||
end | end | ||
| − | |||
function p.itemRecipes(frame) | function p.itemRecipes(frame) | ||
| Line 321: | Line 244: | ||
end | end | ||
| + | --[[ | ||
| + | If item ids are supplied through the named argument 'ids', the table must | ||
| + | be in the following form: | ||
| + | |||
| + | { | ||
| + | { ['id'] = value_1 }, | ||
| + | { ['id'] = value_2 }, | ||
| + | . | ||
| + | . | ||
| + | . | ||
| + | { ['id'] = value_n } | ||
| + | } | ||
| + | The actual id values can be either numbers or strings. | ||
| + | ]] | ||
function p._itemRecipes(args) | function p._itemRecipes(args) | ||
| + | |||
| + | local items = {} | ||
if not args[1] or args[1] == '' then | if not args[1] or args[1] == '' then | ||
| Line 328: | Line 267: | ||
end | end | ||
| − | + | if args['ids'] and type(args['ids']) == 'table' then | |
| + | items = args['ids'] | ||
| + | else | ||
| + | addItemIds(items, args[1]) | ||
| + | end | ||
| − | |||
addOtherItemFields(items) | addOtherItemFields(items) | ||
addRecipes(items) | addRecipes(items) | ||
Latest revision as of 05:11, 25 April 2025
Documentation for this module may be created at Module:Sandbox/Broono/Item Recipes/doc
local p = {}
local addSeparator = require('Module:AddSeparator')
local findId = require('Module:FindId')
local img = require('Module:Img')
local data = {}
data.craftingAugmenting = mw.loadData('Module:CraftingAugmenting/data')
data.items = mw.loadData('Module:Items/data')
local COLLAPSIBLE = 7
local COLLAPSED = 15
local SORTABLE = 7
local function strip(s)
return s:match('^%s*(.-)%s*$')
end
local function split(s, sep)
local t = {}
if sep == nil or sep == '' then
sep = '%s'
end
for m in s:gmatch('([^' .. sep .. ']+)') do
table.insert(t, m)
end
return t
end
function table.length(t)
local count = 0
for _ in pairs(t) do count = count + 1 end
return count
end
local function addItemIds(t, names)
local _names = split(names, ';')
for _, name in pairs(_names) do
name = strip(name)
if name ~= '' then
local id = findId._findId({name, 'item'})
if type(id) == 'number' then
table.insert(t, {['id'] = id})
else
table.insert(t, {['error'] = {'name', name}})
end
end
end
end
local function addOtherItemFields(t)
for i in pairs(t) do
if t[i].id then
local id = tostring(t[i].id)
local craftingStats
if data.items[id] and data.items[id].craftingStats then
craftingStats = data.items[id].craftingStats
elseif data.items[id] then
craftingStats = data.items[id]
else
t[i].error = { 'id', t[i].id }
end
if not t[i].error then
t[i].name = data.items[id].name
t[i].level = craftingStats.level
t[i].experience = craftingStats.experience
t[i].category = craftingStats.category
end
else
t[i].error = {'id', 'nil'}
end
end
end
local function addRecipes(t)
for i in pairs(t) do
local id = tostring(t[i].id)
if data.craftingAugmenting[id] and not t[i].error then
t[i].recipes = {}
if data.craftingAugmenting[id].crafting then
for _, recipe in pairs(data.craftingAugmenting[id].crafting) do
table.insert(t[i].recipes, recipe.recipe)
t[i].skill = 'Crafting'
end
elseif data.craftingAugmenting[id].scrollcrafting then
table.insert(t[i].recipes, data.craftingAugmenting[id].scrollcrafting)
t[i].skill = 'Scrollcrafting'
elseif data.craftingAugmenting[id].runecrafting then
table.insert(t[i].recipes, data.craftingAugmenting[id].runecrafting)
t[i].skill = 'Runecrafting'
elseif data.craftingAugmenting[id].smithing then
table.insert(t[i].recipes, data.craftingAugmenting[id].smithing)
t[i].skill = 'Smithing'
end
elseif not t[i].error then
t[i].error = {'recipe', id .. ' (' .. t[i].name .. ')'}
end
end
end
local function generateTableRecipe(t)
local ingredients = {}
for id, amt in pairs(t) do
local name = data.items[id].name
local image = img._img({name, 30})
table.insert(ingredients, image .. ' x'.. addSeparator._addSeparator({amt}))
end
return table.concat(ingredients, ', ')
end
local function generateTableBody(t)
local tbody = mw.html.create(nil)
for i = 1, table.length(t) do
local row = mw.html.create('tr')
local rowspan = 0
if t[i].error then
local e
if t[i].error[1] == 'recipe' then
e = 'Could not find a recipe for item with id: ' .. t[i].error[2]
else
e = '\'\'Could not find item with ' .. t[i].error[1] .. ': '
e = e ..'\'\'\'' .. t[i].error[2] .. '\'\'\'.'
if t[i].error[1] == 'name' then
e = e .. ' Please check spelling or update data modules.'
end
end
row:tag('td')
:css('text-align', 'center')
:attr('colspan', 5)
:wikitext(e)
else
rowspan = table.length(t[i].recipes)
-- Icon
row:node(mw.html.create('td')
:attr('rowspan', rowspan)
:css('text-align', 'center')
:wikitext(img._img({t[i].name, 30, alt=''})))
-- Name
local name
if t[i].name == mw.title.getCurrentTitle().fullText then
name = '\'\'\'' .. t[i].name .. '\'\'\''
else
name = '\'\'\'[[' .. t[i].name .. ']]\'\'\''
end
row:node(mw.html.create('td')
:attr('rowspan', rowspan)
:attr('scope', 'row')
:wikitext(name))
-- Skill: Level
local skill
if t[i].category then
skill = img._img({t[i].skill, 30, word='1', alt=''}) .. ' (' .. t[i].category .. '): ' .. t[i].level
else
skill = img._img({t[i].skill, 30, word='1', alt=''}) .. ': ' .. t[i].level
end
row:node(mw.html.create('td')
:attr('rowspan', rowspan)
:wikitext(skill))
-- Experience
row:node(mw.html.create('td')
:attr('rowspan', rowspan)
:css('text-align', 'center')
:wikitext(addSeparator._addSeparator({t[i].experience})))
-- Recipe
row:node(mw.html.create('td')
:wikitext(generateTableRecipe(t[i].recipes[1])))
end
tbody:node(row)
-- More recipes if item has more than one
if rowspan > 1 then
for j = 2, rowspan do
tbody
:tag('tr')
:tag('td')
:wikitext(generateTableRecipe(t[i].recipes[j]))
end
end
end
return tbody
end
local function generateTableHead()
local thead = mw.html.create(nil)
local row = mw.html.create('tr')
row
:tag('th')
:attr('scope', 'col')
:wikitext('Icon')
:done()
:tag('th')
:attr('scope', 'col')
:wikitext('Name')
:done()
:tag('th')
:attr('scope', 'col')
:wikitext('Skill: Level')
:done()
:tag('th')
:attr('scope', 'col')
:wikitext('Experience')
:done()
:tag('th')
:attr('scope', 'col')
:wikitext('Recipe')
:done()
thead:node(row)
return thead
end
local function generateTable(t)
local tbl = mw.html.create('table')
tbl
:addClass('wikitable')
if table.length(t) > SORTABLE then tbl:addClass('sortable') end
if table.length(t) > COLLAPSIBLE then tbl:addClass('mw-collapsible') end
if table.length(t) > COLLAPSED then tbl:addClass('mw-collapsed') end
tbl:node(generateTableHead())
tbl:node(generateTableBody(t))
return tbl
end
function p.itemRecipes(frame)
return p._itemRecipes(frame:getParent().args)
end
--[[
If item ids are supplied through the named argument 'ids', the table must
be in the following form:
{
{ ['id'] = value_1 },
{ ['id'] = value_2 },
.
.
.
{ ['id'] = value_n }
}
The actual id values can be either numbers or strings.
]]
function p._itemRecipes(args)
local items = {}
if not args[1] or args[1] == '' then
args[1] = mw.title.getCurrentTitle().fullText
end
if args['ids'] and type(args['ids']) == 'table' then
items = args['ids']
else
addItemIds(items, args[1])
end
addOtherItemFields(items)
addRecipes(items)
return generateTable(items)
end
return p