Module:ItemCategoryTable
Documentation for this module may be created at Module:ItemCategoryTable/doc
local p = {}
local ItemConfig = require('Module:ItemConfig')
-- Query items by type from Cargo (type is a List field, requires HOLDS)
local function getItemsByType(itemType)
local tables = 'Items'
local fields = ItemConfig.cargoFields.itemsTable
local args = {
where = 'type HOLDS "' .. itemType .. '"',
orderBy = 'name',
limit = 500
}
return mw.ext.cargo.query(tables, fields, args)
end
-- Query items by multiple types
local function getItemsByTypes(types)
local tables = 'Items'
local fields = ItemConfig.cargoFields.itemsTable
-- Build OR conditions for each type (using HOLDS for List field)
local conditions = {}
for _, t in ipairs(types) do
table.insert(conditions, 'type HOLDS "' .. t .. '"')
end
local args = {
where = table.concat(conditions, ' OR '),
orderBy = 'name',
limit = 500
}
return mw.ext.cargo.query(tables, fields, args)
end
-- Query all items
local function getAllItems()
local tables = 'Items'
local fields = ItemConfig.cargoFields.itemsTable
local args = {
orderBy = 'name',
limit = 500
}
return mw.ext.cargo.query(tables, fields, args)
end
-- Get numeric value from stat (0 if empty)
local function statNum(value)
if value and value ~= "" then
return tonumber(value) or 0
end
return 0
end
-- Format stat value (return 0 if empty)
local function stat(value)
if value and value ~= "" then
return value
end
return "0"
end
-- Calculate total stat power for an item
local function calcPower(item)
return statNum(item.damage) + statNum(item.armor) + statNum(item.defense) +
statNum(item.health) + statNum(item.mana) + statNum(item.ability) +
statNum(item.magic) + statNum(item.rng) + statNum(item.move_speed) +
statNum(item.attack_speed)
end
-- Sort column mapping
local sortColumns = {
name = function(item) return item.name or "" end,
type = function(item) return item.type or "" end,
slots = function(item) return statNum(item.container) end,
container = function(item) return statNum(item.container) end,
weight = function(item) return statNum(item.weight) end,
damage = function(item) return statNum(item.damage) end,
armor = function(item) return statNum(item.armor) end,
defense = function(item) return statNum(item.defense) end,
health = function(item) return statNum(item.health) end,
mana = function(item) return statNum(item.mana) end,
ability = function(item) return statNum(item.ability) end,
magic = function(item) return statNum(item.magic) end,
rng = function(item) return statNum(item.rng) end,
move_speed = function(item) return statNum(item.move_speed) end,
attack_speed = function(item) return statNum(item.attack_speed) end,
power = function(item) return item._power end,
total = function(item) return item._power end
}
function p.render(frame)
local args = frame:getParent().args
local categoryName = args[1] or args.category or mw.title.getCurrentTitle().text:gsub("^Category:", "")
local sortBy = args.sort or args.sortby
local sortDir = args.dir or args.sortdir or "desc"
-- Check if this is a parent category or all items
local isAllItems = (categoryName == "Items")
local isParent = ItemConfig.isParentCategory(categoryName) or isAllItems
local isContainers = (categoryName == "Containers")
local items
if isAllItems then
items = getAllItems()
elseif ItemConfig.isParentCategory(categoryName) then
items = getItemsByTypes(ItemConfig.getChildTypes(categoryName))
else
local itemType = ItemConfig.singularize(categoryName)
items = getItemsByType(itemType)
end
if not items or #items == 0 then
return '<p class="mw-empty">No items found.</p>'
end
-- Calculate power for each item
for _, item in ipairs(items) do
item._power = calcPower(item)
end
-- Determine sort column
local sortFunc = nil
if sortBy and sortColumns[sortBy] then
sortFunc = sortColumns[sortBy]
elseif isContainers then
sortFunc = sortColumns.slots
else
sortFunc = sortColumns.power
end
-- Sort items
local ascending = (sortDir == "asc")
table.sort(items, function(a, b)
local valA = sortFunc(a)
local valB = sortFunc(b)
if ascending then
return valA < valB
else
return valA > valB
end
end)
-- Build sortable table
local tbl = mw.html.create('table')
tbl:addClass('wikitable')
:addClass('sortable')
:css('width', '100%')
-- Header row
local header = tbl:tag('tr')
header:tag('th')
:css('width', '64px')
:addClass('unsortable')
:wikitext('')
header:tag('th'):wikitext('Item')
if isParent then
header:tag('th'):wikitext('Type')
end
if isContainers then
header:tag('th'):attr('title', 'Container Slots'):wikitext('Slots')
end
header:tag('th'):attr('title', 'Weight'):wikitext('WGT')
header:tag('th'):attr('title', 'Damage'):wikitext('DMG')
header:tag('th'):attr('title', 'Armor'):wikitext('ARM')
header:tag('th'):attr('title', 'Defense'):wikitext('DEF')
header:tag('th'):attr('title', 'Health'):wikitext('HP')
header:tag('th'):attr('title', 'Mana'):wikitext('MP')
header:tag('th'):attr('title', 'Ability'):wikitext('ABL')
header:tag('th'):attr('title', 'Magic'):wikitext('MAG')
header:tag('th'):attr('title', 'Range'):wikitext('RNG')
header:tag('th'):attr('title', 'Move Speed'):wikitext('MS')
header:tag('th'):attr('title', 'Attack Speed'):wikitext('AS')
header:tag('th'):attr('title', 'Total Stats'):wikitext('Total')
-- Data rows
for _, item in ipairs(items) do
local row = tbl:tag('tr')
-- Icon column
local iconCell = row:tag('td')
:css('width', '64px')
:css('text-align', 'center')
local sprite = item.sprite or item.name or "Unknown"
if sprite and sprite ~= "" then
iconCell:wikitext(frame:preprocess('{{Sprite|' .. sprite .. '|x2}}'))
end
-- Item name column
local itemName = item.name or "Unknown"
row:tag('td'):wikitext('[[' .. itemName .. ']]')
-- Type column (for parent categories)
if isParent then
local typeCategory = ItemConfig.pluralize(item.type or "")
row:tag('td'):wikitext('[[:Category:' .. typeCategory .. '|' .. (item.type or "") .. ']]')
end
-- Slots column (for containers)
if isContainers then
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.container))
end
-- Stats
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.weight))
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.damage))
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.armor))
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.defense))
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.health))
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.mana))
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.ability))
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.magic))
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.rng))
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.move_speed))
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.attack_speed))
row:tag('td'):css('text-align', 'right'):wikitext(item._power)
end
return tostring(tbl)
end
return p