Jump to content

Module:ItemCategoryTable: Difference between revisions

From Apogea Wiki
Dane (talk | contribs)
Show all stats instead of description (via update-page on MediaWiki MCP Server)
Dane (talk | contribs)
No edit summary
 
(16 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
-- Query items by type from Cargo (type is a List field, requires HOLDS)
local function getItemsByType(itemType)
local function getItemsByType(itemType)
     local tables = 'Items'
     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 fields = ItemConfig.cargoFields.itemsTable
     local args = {
     local args = {
         where = 'type LIKE "%' .. itemType .. '%"',
         where = 'type HOLDS "' .. itemType .. '"',
         orderBy = 'name',
         orderBy = 'name',
         limit = 500
         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)
     return mw.ext.cargo.query(tables, fields, args)
end
end


-- Get the singular type name from a plural category name
-- Query all items
local function singularize(plural)
local function getAllItems()
     local mapping = {
     local tables = 'Items'
        ["Rings"] = "Ring",
    local fields = ItemConfig.cargoFields.itemsTable
        ["Necklaces"] = "Necklace",
    local args = {
        ["Staves"] = "Staff",
         orderBy = 'name',
        ["Knives"] = "Knife",
         limit = 500
        ["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$", "")
 
     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
end


Line 78: Line 62:
     return "0"
     return "0"
end
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)
function p.render(frame)
     local args = frame:getParent().args
     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 itemType = singularize(categoryName)
     local sortBy = args.sort or args.sortby
      
    local sortDir = args.dir or args.sortdir or "desc"
     local items = getItemsByType(itemType)
 
      
    -- 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
     if not items or #items == 0 then
         return '<p class="mw-empty">No items found for type: ' .. itemType .. '</p>'
         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
     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 95: 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')
     header:tag('th'):wikitext('Weight')
     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', 'Damage'):wikitext('DMG')
     header:tag('th'):attr('title', 'Armor'):wikitext('ARM')
     header:tag('th'):attr('title', 'Armor'):wikitext('ARM')
Line 110: Line 174:
     header:tag('th'):attr('title', 'Move Speed'):wikitext('MS')
     header:tag('th'):attr('title', 'Move Speed'):wikitext('MS')
     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')
 
     -- 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')
       
 
         -- Item name with sprite
         -- Icon column
         local nameCell = row:tag('td')
         local iconCell = row:tag('td')
         local sprite = item.sprite or item.name
            :css('width', '64px')
         nameCell:wikitext(frame:preprocess('{{Sprite|' .. sprite .. '|x2}}'))
            :css('text-align', 'center')
         nameCell:wikitext(' [[' .. item.name .. ']]')
         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
         -- Stats
         row:tag('td'):css('text-align', 'right'):wikitext(stat(item.weight))
         row:tag('td'):css('text-align', 'right'):wikitext(stat(item.weight))
Line 133: Line 216:
         row:tag('td'):css('text-align', 'right'):wikitext(stat(item.move_speed))
         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(stat(item.attack_speed))
        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