Jump to content

Module:Infobox: Difference between revisions

From Apogea Wiki
Dane (talk | contribs)
Create Infobox module with stat icons support (via create-page on MediaWiki MCP Server)
Tag: Recreated
 
Dane (talk | contribs)
Move icon to right side of label text (via update-page on MediaWiki MCP Server)
Line 103: Line 103:
      
      
     if stat.icon then
     if stat.icon then
         labelContent = string.format('[[File:%s|16px|link=]] %s', stat.icon, stat.text)
         labelContent = string.format('%s [[File:%s|16px|link=]]', stat.text, stat.icon)
     end
     end
      
      

Revision as of 08:06, 22 January 2026

Documentation for this module may be created at Module:Infobox/doc

local p = {}

-- Stat definitions: key -> { text, icon, isBonus }
local stats = {
    -- Base stats
    wgt = { text = 'Weight', icon = 'Weight.png' },
    rng = { text = 'Range', icon = 'Range.png' },
    dmg = { text = 'Damage', icon = 'Damage.png' },
    eq = { text = 'Equip Size', icon = 'Weight.png' },
    
    -- Bonuses
    hp = { text = 'HP', icon = 'Health.png', isBonus = true },
    mp = { text = 'MP', icon = 'Mana.png', isBonus = true },
    ab = { text = 'Ability', icon = 'Ability.png', isBonus = true },
    mag = { text = 'Magic', icon = 'Magic.png', isBonus = true },
    arm = { text = 'Armor', icon = 'Armor.png', isBonus = true },
    def = { text = 'Defense', icon = 'Defense.png', isBonus = true },
    ms = { text = 'Move Speed', icon = 'Move_Speed.png', isBonus = true },
    as = { text = 'Attack Speed', icon = 'Attack_Speed.png', isBonus = true },
    hpregen = { text = 'HP Regen', icon = 'Health_Regen.png', isBonus = true },
    mpregen = { text = 'MP Regen', icon = 'Mana_Regen.png', isBonus = true },
}

local function formatBonus(value)
    if not value or value == '' then
        return nil
    end
    local num = tonumber(value)
    if num and num > 0 then
        return '+' .. value
    end
    return value
end

function p.new(frame)
    local builder = {
        root = mw.html.create('table'),
        frame = frame
    }
    
    builder.root
        :addClass('wikitable')
        :addClass('infobox')
        :css('float', 'right')
        :css('clear', 'right')
        :css('margin', '0 0 1em 1em')
        :css('width', '250px')
    
    setmetatable(builder, { __index = p })
    return builder
end

function p:addClass(class)
    self.root:addClass(class)
    return self
end

function p:addHeader(text)
    self.root:tag('tr')
        :tag('th')
            :attr('colspan', 2)
            :css('text-align', 'center')
            :wikitext(text)
    return self
end

function p:addImage(content)
    self.root:tag('tr')
        :tag('td')
            :attr('colspan', 2)
            :css('text-align', 'center')
            :wikitext(content)
    return self
end

function p:addRow(label, value)
    if not value or value == '' then
        return self
    end
    
    local row = self.root:tag('tr')
    row:tag('th')
        :css('text-align', 'right')
        :wikitext(label)
    row:tag('td')
        :css('text-align', 'left')
        :wikitext(value)
    return self
end

function p:addStat(key, value)
    if not value or value == '' then
        return self
    end
    
    local stat = stats[key]
    if not stat then
        return self
    end
    
    local displayValue = stat.isBonus and formatBonus(value) or value
    local labelContent = stat.text
    
    if stat.icon then
        labelContent = string.format('%s [[File:%s|16px|link=]]', stat.text, stat.icon)
    end
    
    local row = self.root:tag('tr')
    row:tag('th')
        :css('text-align', 'right')
        :wikitext(labelContent)
    row:tag('td')
        :css('text-align', 'left')
        :wikitext(displayValue)
    return self
end

function p:addSection(text)
    self.root:tag('tr')
        :tag('th')
            :attr('colspan', 2)
            :wikitext("'''" .. text .. "'''")
    return self
end

function p:finish()
    return tostring(self.root)
end

function p.item(frame)
    local args = frame:getParent().args
    
    local box = p.new(frame)
        :addClass('item-infobox')
    
    local sprite = args.sprite or args.name
    local spriteContent = frame:expandTemplate{
        title = 'Sprite',
        args = { sprite, '64', class = 'pageimage' }
    }
    
    box:addHeader(args.name or 'Unknown')
       :addImage(spriteContent)
       :addRow('Slot', args.slot)
       :addRow('Type', args.category and string.format('[[:Category:%s|%s]]', args.category, args.category))
       :addStat('wgt', args.wgt)
       :addStat('rng', args.rng)
       :addStat('dmg', args.dmg)
       :addStat('eq', args.eq)
    
    local bonusKeys = {'hp', 'mp', 'ab', 'mag', 'arm', 'def', 'ms', 'as', 'hpregen', 'mpregen'}
    local hasBonus = false
    for _, key in ipairs(bonusKeys) do
        if args[key] and args[key] ~= '' then
            hasBonus = true
            break
        end
    end
    
    if hasBonus then
        box:addSection('Bonuses')
        for _, key in ipairs(bonusKeys) do
            box:addStat(key, args[key])
        end
    end
    
    local categories = ''
    if args.category then
        categories = categories .. '[[Category:' .. args.category .. ']]'
    end
    
    return box:finish() .. categories
end

return p