Module:ItemCategoryTable
Documentation for this module may be created at Module:ItemCategoryTable/doc
local p = {}
-- Parent categories and their child types
local parentCategories = {
["Accessories"] = {"Ring", "Necklace"},
["Weapons"] = {"Sword", "Large Sword", "Dagger", "Knife", "Axe", "Large Axe", "Bow", "Staff", "Orb"},
["Shields"] = {"Small Shield", "Large Shield"},
["Armor"] = {"Heavy Chest", "Heavy Legs", "Heavy Helmet", "Heavy Boots", "Light Chest", "Light Legs", "Light Helmet", "Light Boots", "Light Mask", "Light Neck"},
["Heavy Armor"] = {"Heavy Chest", "Heavy Legs", "Heavy Helmet", "Heavy Boots"},
["Light Armor"] = {"Light Chest", "Light Legs", "Light Helmet", "Light Boots", "Light Mask", "Light Neck"},
["Food"] = {"Cooked Food", "Edible Food", "Raw Food", "Special Food"},
["Consumables"] = {"Potions", "Drinks", "Cooked Food", "Edible Food", "Raw Food", "Special Food"},
["Materials"] = {"Book Products", "Cloth Products", "Cooking Items", "Desert Products", "Forge Products", "Grave Products", "Holy Products", "Monster Products", "North Products", "Plains Products", "Swamp Products"},
["Equipment"] = {"Ring", "Necklace", "Gloves", "Sword", "Large Sword", "Dagger", "Knife", "Axe", "Large Axe", "Bow", "Staff", "Orb", "Small Shield", "Large Shield", "Heavy Chest", "Heavy Legs", "Heavy Helmet", "Heavy Boots", "Light Chest", "Light Legs", "Light Helmet", "Light Boots", "Light Mask", "Light Neck"},
}
-- Query items by type from Cargo
local function getItemsByType(itemType)
local tables = 'Items'
local fields = 'name,sprite,type,weight,damage,armor,defense,health,mana,ability,magic,rng,move_speed,attack_speed,health_regen,mana_regen,container,size,rarity'
local args = {
where = 'type LIKE "%' .. 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 = 'name,sprite,type,weight,damage,armor,defense,health,mana,ability,magic,rng,move_speed,attack_speed,health_regen,mana_regen,container,size,rarity'
-- Build OR conditions for each type
local conditions = {}
for _, t in ipairs(types) do
table.insert(conditions, 'type LIKE "%' .. t .. '%"')
end
local args = {
where = table.concat(conditions, ' OR '),
orderBy = 'name',
limit = 500
}
return mw.ext.cargo.query(tables, fields, args)
end
-- Get the singular type name from a plural category name
local function singularize(plural)
local mapping = {
["Rings"] = "Ring",
["Necklaces"] = "Necklace",
["Staves"] = "Staff",
["Knives"] = "Knife",
["Axes"] = "Axe",
["Large Axes"] = "Large Axe",
["Swords"] = "Sword",
["Large Swords"] = "Large Sword",
["Regular Swords"] = "Regular Sword",
["Daggers"] = "Dagger",
["Bows"] = "Bow",
["Orbs"] = "Orb",
["Small Shields"] = "Small Shield",
["Large Shields"] = "Large Shield",
["Gloves"] = "Gloves",
["Containers"] = "Container",
["Tools"] = "Tools",
["Heavy Helmets"] = "Heavy Helmet",
["Light Helmets"] = "Light Helmet",
["Light Masks"] = "Light Mask",
["Heavy Boots"] = "Heavy Boots",
["Light Boots"] = "Light Boots",
["Heavy Legs"] = "Heavy Legs",
["Light Legs"] = "Light Legs",
["Heavy Chest Armor"] = "Heavy Chest",
["Light Chest Armor"] = "Light Chest",
["Light Neck Armor"] = "Light Neck",
["Potions"] = "Potions",
["Drinks"] = "Drinks",
["Arrows"] = "Arrows",
["Conjured Arrows"] = "Conjured Arrows",
["Books"] = "Book",
["Cooked Food"] = "Cooked Food",
["Edible Food"] = "Edible Food",
["Raw Food"] = "Raw Food",
["Special Food"] = "Special Food",
["Light Sources"] = "Light Sources",
["Flowers"] = "Flowers",
["Currency"] = "Currency",
["Book Products"] = "Book Products",
["Cloth Products"] = "Cloth Products",
["Cooking Items"] = "Cooking Items",
["Desert Products"] = "Desert Products",
["Forge Products"] = "Forge Products",
["Grave Products"] = "Grave Products",
["Holy Products"] = "Holy Products",
["Monster Products"] = "Monster Products",
["North Products"] = "North Products",
["Plains Products"] = "Plains Products",
["Swamp Products"] = "Swamp Products",
}
return mapping[plural] or plural:gsub("s$", "")
end
-- Get the plural/category name from a type
local function pluralize(singular)
local mapping = {
["Ring"] = "Rings",
["Necklace"] = "Necklaces",
["Staff"] = "Staves",
["Knife"] = "Knives",
["Axe"] = "Axes",
["Large Axe"] = "Large Axes",
["Sword"] = "Swords",
["Large Sword"] = "Large Swords",
["Dagger"] = "Daggers",
["Bow"] = "Bows",
["Orb"] = "Orbs",
["Small Shield"] = "Small Shields",
["Large Shield"] = "Large Shields",
["Gloves"] = "Gloves",
["Container"] = "Containers",
["Heavy Helmet"] = "Heavy Helmets",
["Light Helmet"] = "Light Helmets",
["Light Mask"] = "Light Masks",
["Heavy Boots"] = "Heavy Boots",
["Light Boots"] = "Light Boots",
["Heavy Legs"] = "Heavy Legs",
["Light Legs"] = "Light Legs",
["Heavy Chest"] = "Heavy Chest Armor",
["Light Chest"] = "Light Chest Armor",
["Light Neck"] = "Light Neck Armor",
}
return mapping[singular] or singular
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
function p.render(frame)
local args = frame:getParent().args
local categoryName = args[1] or args.category or mw.title.getCurrentTitle().text:gsub("^Category:", "")
-- Check if this is a parent category
local isParent = parentCategories[categoryName] ~= nil
local items
if isParent then
items = getItemsByTypes(parentCategories[categoryName])
else
local itemType = 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 and sort by it (descending)
for _, item in ipairs(items) do
item._power = calcPower(item)
end
table.sort(items, function(a, b) return a._power > b._power 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'):wikitext('Item')
if isParent then
header:tag('th'):wikitext('Type')
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')
-- Item name with sprite
local nameCell = row:tag('td')
local sprite = item.sprite or item.name
nameCell:wikitext(frame:preprocess('{{Sprite|' .. sprite .. '|x2}}'))
nameCell:wikitext(' [[' .. item.name .. ']]')
-- Type column (for parent categories)
if isParent then
local typeCategory = pluralize(item.type or "")
row:tag('td'):wikitext('[[:Category:' .. typeCategory .. '|' .. (item.type or "") .. ']]')
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