Module:ItemCategoryTable: Difference between revisions
Move Gloves from Accessories to Equipment (via update-page on MediaWiki MCP Server) |
No edit summary |
||
| (10 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
local ItemConfig = require('Module:ItemConfig') | |||
-- Query items by type from Cargo (type is a List field, requires HOLDS) | |||
-- Query items by type from Cargo | |||
local function getItemsByType(itemType) | local function getItemsByType(itemType) | ||
local tables = 'Items' | local tables = 'Items' | ||
local fields = | local fields = ItemConfig.cargoFields.itemsTable | ||
local args = { | local args = { | ||
where = 'type | where = 'type HOLDS "' .. itemType .. '"', | ||
orderBy = 'name', | orderBy = 'name', | ||
limit = 500 | limit = 500 | ||
} | } | ||
return mw.ext.cargo.query(tables, fields, args) | return mw.ext.cargo.query(tables, fields, args) | ||
end | end | ||
| Line 31: | Line 18: | ||
local function getItemsByTypes(types) | local function getItemsByTypes(types) | ||
local tables = 'Items' | local tables = 'Items' | ||
local fields = | local fields = ItemConfig.cargoFields.itemsTable | ||
-- Build OR conditions for each type | -- Build OR conditions for each type (using HOLDS for List field) | ||
local conditions = {} | local conditions = {} | ||
for _, t in ipairs(types) do | for _, t in ipairs(types) do | ||
table.insert(conditions, 'type | table.insert(conditions, 'type HOLDS "' .. t .. '"') | ||
end | end | ||
local args = { | local args = { | ||
where = table.concat(conditions, ' OR '), | where = table.concat(conditions, ' OR '), | ||
| Line 44: | Line 31: | ||
limit = 500 | limit = 500 | ||
} | } | ||
return mw.ext.cargo.query(tables, fields, args) | return mw.ext.cargo.query(tables, fields, args) | ||
end | end | ||
-- | -- Query all items | ||
local function | local function getAllItems() | ||
local | local tables = 'Items' | ||
local fields = ItemConfig.cargoFields.itemsTable | |||
local args = { | |||
orderBy = 'name', | |||
limit = 500 | |||
} | } | ||
return mw.ext.cargo.query(tables, fields, args) | |||
end | end | ||
| Line 160: | Line 70: | ||
statNum(item.attack_speed) | statNum(item.attack_speed) | ||
end | end | ||
-- Sort column mapping | |||
local sortColumns = { | |||
name = function(item) return item.name or item._pageName 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) | function p.render(frame) | ||
local args = frame | local args = frame.args | ||
local categoryName = args[1] or args.category or mw.title.getCurrentTitle().text:gsub("^Category:", "") | local categoryName = args[1] or args.category or mw.title.getCurrentTitle().text:gsub("^Category:", "") | ||
local sortBy = args.sort or args.sortby | |||
-- Check if this is a parent category | local sortDir = args.dir or args.sortdir or "desc" | ||
local isParent = | |||
-- 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 | local items | ||
if isAllItems then | |||
items = getItemsByTypes( | items = getAllItems() | ||
elseif ItemConfig.isParentCategory(categoryName) then | |||
items = getItemsByTypes(ItemConfig.getChildTypes(categoryName)) | |||
else | else | ||
local itemType = singularize(categoryName) | local itemType = ItemConfig.singularize(categoryName) | ||
items = getItemsByType(itemType) | items = getItemsByType(itemType) | ||
end | end | ||
if not items or #items == 0 then | if not items or #items == 0 then | ||
return '<p class="mw-empty">No items found.</p>' | return '<p class="mw-empty">No items found.</p>' | ||
end | end | ||
-- Calculate power for each item | -- Calculate power for each item | ||
for _, item in ipairs(items) do | for _, item in ipairs(items) do | ||
item._power = calcPower(item) | item._power = calcPower(item) | ||
end | end | ||
table.sort(items, function(a, b) return | |||
-- 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 | -- Build sortable table | ||
local tbl = mw.html.create('table') | local tbl = mw.html.create('table') | ||
| Line 191: | Line 149: | ||
:addClass('sortable') | :addClass('sortable') | ||
:css('width', '100%') | :css('width', '100%') | ||
-- Header row | -- Header row | ||
local header = tbl:tag('tr') | local header = tbl:tag('tr') | ||
header:tag('th') | |||
:css('width', '64px') | |||
:addClass('unsortable') | |||
:wikitext('') | |||
header:tag('th'):wikitext('Item') | header:tag('th'):wikitext('Item') | ||
if isParent then | if isParent then | ||
header:tag('th'):wikitext('Type') | header:tag('th'):wikitext('Type') | ||
end | |||
if isContainers then | |||
header:tag('th'):attr('title', 'Container Slots'):wikitext('Slots') | |||
end | end | ||
header:tag('th'):attr('title', 'Weight'):wikitext('WGT') | header:tag('th'):attr('title', 'Weight'):wikitext('WGT') | ||
| Line 210: | Line 175: | ||
header:tag('th'):attr('title', 'Attack Speed'):wikitext('AS') | header:tag('th'):attr('title', 'Attack Speed'):wikitext('AS') | ||
header:tag('th'):attr('title', 'Total Stats'):wikitext('Total') | header:tag('th'):attr('title', 'Total Stats'):wikitext('Total') | ||
-- Data rows | -- Data rows | ||
for _, item in ipairs(items) do | for _, item in ipairs(items) do | ||
local row = tbl:tag('tr') | local row = tbl:tag('tr') | ||
-- | -- Icon column | ||
local | local iconCell = row:tag('td') | ||
local sprite = item.sprite or item.name | :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) | -- Type column (for parent categories) | ||
if isParent then | if isParent then | ||
local typeCategory = pluralize(item.type or "") | local typeCategory = ItemConfig.pluralize(item.type or "") | ||
row:tag('td'):wikitext('[[:Category:' .. typeCategory .. '|' .. (item.type or "") .. ']]') | row:tag('td'):wikitext('[[:Category:' .. typeCategory .. '|' .. (item.type or "") .. ']]') | ||
end | end | ||
-- Slots column (for containers) | |||
if isContainers then | |||
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.container)) | |||
end | |||
-- Stats | -- Stats | ||
row:tag('td'):css('text-align', 'right'):wikitext(stat(item.weight)) | row:tag('td'):css('text-align', 'right'):wikitext(stat(item.weight)) | ||
| Line 241: | Line 218: | ||
row:tag('td'):css('text-align', 'right'):wikitext(item._power) | row:tag('td'):css('text-align', 'right'):wikitext(item._power) | ||
end | end | ||
return tostring(tbl) | return tostring(tbl) | ||
end | end | ||
return p | return p | ||
Latest revision as of 21:15, 1 February 2026
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 item._pageName 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.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