Jump to content

Module:ItemCategoryTable: Difference between revisions

From Apogea Wiki
Dane (talk | contribs)
Move Gloves from Accessories to Equipment (via update-page on MediaWiki MCP Server)
Dane (talk | contribs)
Add separate 64px icon column (via update-page on MediaWiki MCP Server)
Line 194: Line 194:
     -- 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
Line 215: Line 219:
         local row = tbl:tag('tr')
         local row = tbl:tag('tr')
          
          
         -- Item name with sprite
         -- Icon column
         local nameCell = row:tag('td')
         local iconCell = row:tag('td')
            :css('width', '64px')
            :css('text-align', 'center')
         local sprite = item.sprite or item.name
         local sprite = item.sprite or item.name
         nameCell:wikitext(frame:preprocess('{{Sprite|' .. sprite .. '|x2}}'))
         iconCell:wikitext(frame:preprocess('{{Sprite|' .. sprite .. '|x2}}'))
         nameCell:wikitext(' [[' .. item.name .. ']]')
          
        -- Item name column
        row:tag('td'):wikitext('[[' .. item.name .. ']]')
          
          
         -- Type column (for parent categories)
         -- Type column (for parent categories)

Revision as of 03:04, 28 January 2026

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')
        :css('width', '64px')
        :addClass('unsortable')
        :wikitext('')
    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')
        
        -- Icon column
        local iconCell = row:tag('td')
            :css('width', '64px')
            :css('text-align', 'center')
        local sprite = item.sprite or item.name
        iconCell:wikitext(frame:preprocess('{{Sprite|' .. sprite .. '|x2}}'))
        
        -- Item name column
        row:tag('td'):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