Module:Infobox: Difference between revisions
Update item() to query Cargo Items table (via update-page on MediaWiki MCP Server) |
Switch item infobox to tooltip-panel styling (via update-page on MediaWiki MCP Server) |
||
| Line 1: | Line 1: | ||
local p = {} | local p = {} | ||
-- | -- Rarity color mapping | ||
local | local rarityColors = { | ||
common = "silver", | |||
uncommon = "mint", | |||
rare = "sky", | |||
epic = "pink", | |||
legendary = "gold" | |||
} | } | ||
-- | -- Rarity display names | ||
local | local rarityNames = { | ||
common = "Common item.", | |||
uncommon = "Uncommon item.", | |||
rare = "Rare item.", | |||
epic = "Epic item.", | |||
legendary = "Legendary item." | |||
} | } | ||
-- Stat definitions for monsters (keeping old table-based format) | |||
local monsterStats = { | |||
hp = { text = 'HP', icon = 'Health.png' }, | |||
mp = { text = 'MP', icon = 'Mana.png' }, | |||
arm = { text = 'Armor', icon = 'Armor.png' }, | |||
def = { text = 'Defense', icon = 'Defense.png' }, | |||
ms = { text = 'Move Speed', icon = 'Move_Speed.png' }, | |||
as = { text = 'Attack Speed', icon = 'Attack_Speed.png' }, | |||
xp = { text = 'Experience', icon = 'Experience.png' }, | |||
respawn = { text = 'Respawn Time', icon = 'Respawn_Time.png' }, | |||
} | |||
local function makeIcon(frame, icon, tooltip) | local function makeIcon(frame, icon, tooltip) | ||
| Line 55: | Line 36: | ||
end | end | ||
-- Format a stat line with positive/negative coloring | |||
local function formatStat(label, value) | |||
if not value or value == "" then | |||
return nil | |||
function | |||
if not value or value == | |||
return | |||
end | end | ||
local | local numValue = tonumber(value) | ||
local | if numValue then | ||
local colorClass, prefix | |||
if numValue >= 0 then | |||
colorClass = "color-conifer" | |||
prefix = "+" | |||
else | |||
colorClass = "color-coral" | |||
prefix = "" | |||
end | |||
return string.format('<p>%s: <span class="%s">%s%s</span></p>', label, colorClass, prefix, value) | |||
else | else | ||
return string.format('<p>%s: %s</p>', label, value) | |||
end | end | ||
end | end | ||
function | -- Format a plain text line | ||
if not | local function formatLine(text, colorClass) | ||
return | if not text or text == "" then | ||
return nil | |||
end | end | ||
if colorClass then | |||
return string.format('<p class="%s">%s</p>', colorClass, text) | |||
if | |||
return | |||
else | else | ||
return string.format('<p>%s</p>', text) | |||
end | end | ||
end | end | ||
| Line 181: | Line 95: | ||
local itemName = args.name or args[1] | local itemName = args.name or args[1] | ||
local rarity = args.rarity | local rarity = args.rarity | ||
local float = args.float or "right" | |||
local spriteSize = args.spriteSize or "64" | |||
-- Query Cargo for item data | -- Query Cargo for item data | ||
| Line 189: | Line 105: | ||
end | end | ||
local | local itemRarity = string.lower(data.rarity or "common") | ||
local rarityColor = rarityColors[itemRarity] or "silver" | |||
local rarityText = rarityNames[itemRarity] or "" | |||
local html = {} | |||
-- Container with tooltip-panel styling | |||
table.insert(html, string.format('<div class="tooltip-panel font-apogea-long infobox" style="float:%s; margin-%s:15px; margin-bottom:10px;">', | |||
float, | |||
float == "right" and "left" or "right")) | |||
-- Sprite | |||
local sprite = data.sprite or data.name | local sprite = data.sprite or data.name | ||
table.insert(html, string.format('{{Sprite|%s|%s|class=pageimage}}', sprite, spriteSize)) | |||
-- Item name with rarity color | |||
table.insert(html, string.format('<p class="font-bitcell color-%s">%s</p>', rarityColor, data.name)) | |||
-- Description | |||
if data.description and data.description ~= "" then | |||
table.insert(html, formatLine(data.description, "color-jade")) | |||
end | |||
-- Slot/Type line | |||
if data.slot and data.slot ~= "" then | |||
table.insert(html, formatLine("[" .. data.slot .. "]", "color-silver")) | |||
end | |||
-- Stats | |||
if data.rng and data.rng ~= "" then | |||
table.insert(html, formatStat("Range", data.rng)) | |||
end | |||
if data.armor and data.armor ~= "" then | |||
table.insert(html, formatStat("Armor", data.armor)) | |||
end | |||
if data.damage and data.damage ~= "" then | |||
table.insert(html, formatStat("Damage", data.damage)) | |||
end | |||
if data.attack_speed and data.attack_speed ~= "" then | |||
table.insert(html, formatStat("Attackspeed", data.attack_speed)) | |||
end | |||
if data.defense and data.defense ~= "" then | |||
table.insert(html, formatStat("Defense", data.defense)) | |||
end | |||
if data.move_speed and data.move_speed ~= "" then | |||
table.insert(html, formatStat("Movespeed", data.move_speed)) | |||
end | |||
if data.health and data.health ~= "" then | |||
table.insert(html, formatStat("HP", data.health)) | |||
end | |||
if data.mana and data.mana ~= "" then | |||
table.insert(html, formatStat("MP", data.mana)) | |||
end | |||
if data.ability and data.ability ~= "" then | |||
table.insert(html, formatStat("Ability", data.ability)) | |||
end | |||
if data.magic and data.magic ~= "" then | |||
table.insert(html, formatStat("Magic", data.magic)) | |||
end | |||
if data.health_regen and data.health_regen ~= "" then | |||
table.insert(html, formatStat("HP Regen", data.health_regen)) | |||
end | |||
if data.mana_regen and data.mana_regen ~= "" then | |||
table.insert(html, formatStat("MP Regen", data.mana_regen)) | |||
end | |||
if data.container and data.container ~= "" then | |||
table.insert(html, formatStat("Slots", data.container)) | |||
end | |||
-- Size | |||
if data.size and data.size ~= "" then | |||
table.insert(html, string.format('<p>Size: %s</p>', data.size)) | |||
end | |||
-- Weight | |||
if data.weight and data.weight ~= "" then | |||
table.insert(html, string.format('<p>It weighs %s oz.</p>', data.weight)) | |||
end | |||
-- Rarity text (skip for common) | |||
if itemRarity ~= "common" and rarityText ~= "" then | |||
table.insert(html, formatLine(rarityText, "color-" .. rarityColor)) | |||
end | |||
-- Type category | |||
if data.type and data.type ~= "" then | |||
table.insert(html, formatLine("[" .. data.type .. "]", "color-silver")) | |||
end | |||
table.insert(html, '</div>') | |||
-- Categories | |||
local categories = '' | local categories = '' | ||
if data.type then | if data.type then | ||
| Line 223: | Line 202: | ||
end | end | ||
return | return frame:preprocess(table.concat(html, '\n')) .. categories | ||
end | end | ||
-- Monster infobox (keeping table-based format for now) | |||
function p.monster(frame) | function p.monster(frame) | ||
local args = frame:getParent().args | local args = frame:getParent().args | ||
local | local root = mw.html.create('table') | ||
root:addClass('wikitable') | |||
:addClass('infobox') | |||
:addClass('monster-infobox') | :addClass('monster-infobox') | ||
:css('float', 'right') | |||
:css('clear', 'right') | |||
:css('margin', '0 0 1em 1em') | |||
:css('width', '250px') | |||
-- Header | |||
root:tag('tr') | |||
:tag('th') | |||
:attr('colspan', 2) | |||
:css('text-align', 'center') | |||
:wikitext(args.name or 'Unknown') | |||
-- Image | |||
local sprite = args.sprite or args.name | local sprite = args.sprite or args.name | ||
local previewContent = frame:expandTemplate{ | local previewContent = frame:expandTemplate{ | ||
| Line 237: | Line 231: | ||
args = { sprite, '128', mode = args.mode or 'auto', file = args.file or '' } | args = { sprite, '128', mode = args.mode or 'auto', file = args.file or '' } | ||
} | } | ||
root:tag('tr') | |||
:tag('td') | |||
:attr('colspan', 2) | |||
:css('text-align', 'center') | |||
:wikitext(previewContent) | |||
-- Stats | |||
local function addStat(key, value) | |||
if not value or value == '' then return end | |||
local stat = monsterStats[key] | |||
if not stat then return end | |||
local row = root:tag('tr') | |||
row:tag('th') | |||
:css('text-align', 'right') | |||
:css('width', '32px') | |||
:wikitext(makeIcon(frame, stat.icon, stat.text)) | |||
row:tag('td') | |||
:css('text-align', 'left') | |||
:wikitext(value) | |||
end | |||
addStat('hp', args.hp) | |||
addStat('xp', args.xp) | |||
addStat('arm', args.arm) | |||
addStat('def', args.def) | |||
addStat('as', args.as) | |||
addStat('ms', args.ms) | |||
addStat('respawn', args.respawn) | |||
return | return tostring(root) .. '[[Category:Monsters]]' | ||
end | end | ||
return p | return p | ||
Revision as of 00:41, 28 January 2026
Documentation for this module may be created at Module:Infobox/doc
local p = {}
-- Rarity color mapping
local rarityColors = {
common = "silver",
uncommon = "mint",
rare = "sky",
epic = "pink",
legendary = "gold"
}
-- Rarity display names
local rarityNames = {
common = "Common item.",
uncommon = "Uncommon item.",
rare = "Rare item.",
epic = "Epic item.",
legendary = "Legendary item."
}
-- Stat definitions for monsters (keeping old table-based format)
local monsterStats = {
hp = { text = 'HP', icon = 'Health.png' },
mp = { text = 'MP', icon = 'Mana.png' },
arm = { text = 'Armor', icon = 'Armor.png' },
def = { text = 'Defense', icon = 'Defense.png' },
ms = { text = 'Move Speed', icon = 'Move_Speed.png' },
as = { text = 'Attack Speed', icon = 'Attack_Speed.png' },
xp = { text = 'Experience', icon = 'Experience.png' },
respawn = { text = 'Respawn Time', icon = 'Respawn_Time.png' },
}
local function makeIcon(frame, icon, tooltip)
local img = frame:preprocess('{{#spritescale:' .. icon .. '|stat}}')
return '<span title="' .. mw.text.encode(tooltip) .. '">' .. img .. '</span>'
end
-- Format a stat line with positive/negative coloring
local function formatStat(label, value)
if not value or value == "" then
return nil
end
local numValue = tonumber(value)
if numValue then
local colorClass, prefix
if numValue >= 0 then
colorClass = "color-conifer"
prefix = "+"
else
colorClass = "color-coral"
prefix = ""
end
return string.format('<p>%s: <span class="%s">%s%s</span></p>', label, colorClass, prefix, value)
else
return string.format('<p>%s: %s</p>', label, value)
end
end
-- Format a plain text line
local function formatLine(text, colorClass)
if not text or text == "" then
return nil
end
if colorClass then
return string.format('<p class="%s">%s</p>', colorClass, text)
else
return string.format('<p>%s</p>', text)
end
end
-- Query item data from Cargo
local function getItemData(name, rarity)
local tables = 'Items'
local fields = 'name,sprite,slot,type,weight,rng,damage,health,mana,ability,magic,armor,defense,move_speed,attack_speed,size,container,health_regen,mana_regen,description,rarity'
local args = {
where = 'name="' .. name .. '"',
limit = 1
}
if rarity and rarity ~= '' then
args.where = args.where .. ' AND rarity="' .. rarity .. '"'
end
local result = mw.ext.cargo.query(tables, fields, args)
if result and result[1] then
return result[1]
end
return nil
end
function p.item(frame)
local args = frame:getParent().args
local itemName = args.name or args[1]
local rarity = args.rarity
local float = args.float or "right"
local spriteSize = args.spriteSize or "64"
-- Query Cargo for item data
local data = getItemData(itemName, rarity)
if not data then
return '<span class="error">Item not found: ' .. (itemName or 'nil') .. '</span>'
end
local itemRarity = string.lower(data.rarity or "common")
local rarityColor = rarityColors[itemRarity] or "silver"
local rarityText = rarityNames[itemRarity] or ""
local html = {}
-- Container with tooltip-panel styling
table.insert(html, string.format('<div class="tooltip-panel font-apogea-long infobox" style="float:%s; margin-%s:15px; margin-bottom:10px;">',
float,
float == "right" and "left" or "right"))
-- Sprite
local sprite = data.sprite or data.name
table.insert(html, string.format('{{Sprite|%s|%s|class=pageimage}}', sprite, spriteSize))
-- Item name with rarity color
table.insert(html, string.format('<p class="font-bitcell color-%s">%s</p>', rarityColor, data.name))
-- Description
if data.description and data.description ~= "" then
table.insert(html, formatLine(data.description, "color-jade"))
end
-- Slot/Type line
if data.slot and data.slot ~= "" then
table.insert(html, formatLine("[" .. data.slot .. "]", "color-silver"))
end
-- Stats
if data.rng and data.rng ~= "" then
table.insert(html, formatStat("Range", data.rng))
end
if data.armor and data.armor ~= "" then
table.insert(html, formatStat("Armor", data.armor))
end
if data.damage and data.damage ~= "" then
table.insert(html, formatStat("Damage", data.damage))
end
if data.attack_speed and data.attack_speed ~= "" then
table.insert(html, formatStat("Attackspeed", data.attack_speed))
end
if data.defense and data.defense ~= "" then
table.insert(html, formatStat("Defense", data.defense))
end
if data.move_speed and data.move_speed ~= "" then
table.insert(html, formatStat("Movespeed", data.move_speed))
end
if data.health and data.health ~= "" then
table.insert(html, formatStat("HP", data.health))
end
if data.mana and data.mana ~= "" then
table.insert(html, formatStat("MP", data.mana))
end
if data.ability and data.ability ~= "" then
table.insert(html, formatStat("Ability", data.ability))
end
if data.magic and data.magic ~= "" then
table.insert(html, formatStat("Magic", data.magic))
end
if data.health_regen and data.health_regen ~= "" then
table.insert(html, formatStat("HP Regen", data.health_regen))
end
if data.mana_regen and data.mana_regen ~= "" then
table.insert(html, formatStat("MP Regen", data.mana_regen))
end
if data.container and data.container ~= "" then
table.insert(html, formatStat("Slots", data.container))
end
-- Size
if data.size and data.size ~= "" then
table.insert(html, string.format('<p>Size: %s</p>', data.size))
end
-- Weight
if data.weight and data.weight ~= "" then
table.insert(html, string.format('<p>It weighs %s oz.</p>', data.weight))
end
-- Rarity text (skip for common)
if itemRarity ~= "common" and rarityText ~= "" then
table.insert(html, formatLine(rarityText, "color-" .. rarityColor))
end
-- Type category
if data.type and data.type ~= "" then
table.insert(html, formatLine("[" .. data.type .. "]", "color-silver"))
end
table.insert(html, '</div>')
-- Categories
local categories = ''
if data.type then
categories = categories .. '[[Category:' .. data.type .. ']]'
end
return frame:preprocess(table.concat(html, '\n')) .. categories
end
-- Monster infobox (keeping table-based format for now)
function p.monster(frame)
local args = frame:getParent().args
local root = mw.html.create('table')
root:addClass('wikitable')
:addClass('infobox')
:addClass('monster-infobox')
:css('float', 'right')
:css('clear', 'right')
:css('margin', '0 0 1em 1em')
:css('width', '250px')
-- Header
root:tag('tr')
:tag('th')
:attr('colspan', 2)
:css('text-align', 'center')
:wikitext(args.name or 'Unknown')
-- Image
local sprite = args.sprite or args.name
local previewContent = frame:expandTemplate{
title = 'MonsterPreview',
args = { sprite, '128', mode = args.mode or 'auto', file = args.file or '' }
}
root:tag('tr')
:tag('td')
:attr('colspan', 2)
:css('text-align', 'center')
:wikitext(previewContent)
-- Stats
local function addStat(key, value)
if not value or value == '' then return end
local stat = monsterStats[key]
if not stat then return end
local row = root:tag('tr')
row:tag('th')
:css('text-align', 'right')
:css('width', '32px')
:wikitext(makeIcon(frame, stat.icon, stat.text))
row:tag('td')
:css('text-align', 'left')
:wikitext(value)
end
addStat('hp', args.hp)
addStat('xp', args.xp)
addStat('arm', args.arm)
addStat('def', args.def)
addStat('as', args.as)
addStat('ms', args.ms)
addStat('respawn', args.respawn)
return tostring(root) .. '[[Category:Monsters]]'
end
return p