Module:Infobox: Difference between revisions
Default item name to current page title (via update-page on MediaWiki MCP Server) |
Add type pluralization for categories (via update-page on MediaWiki MCP Server) |
||
| Line 18: | Line 18: | ||
legendary = "Legendary item." | legendary = "Legendary item." | ||
} | } | ||
-- Type to plural category mapping | |||
local typePlurals = { | |||
["Arrows"] = "Arrows", | |||
["Axe"] = "Axes", | |||
["Book"] = "Books", | |||
["Book Products"] = "Book Products", | |||
["Bow"] = "Bows", | |||
["Cloth Products"] = "Cloth Products", | |||
["Conjured Arrows"] = "Conjured Arrows", | |||
["Container"] = "Containers", | |||
["Cooked Food"] = "Cooked Food", | |||
["Cooking Items"] = "Cooking Items", | |||
["Currency"] = "Currency", | |||
["Dagger"] = "Daggers", | |||
["Desert Products"] = "Desert Products", | |||
["Drinks"] = "Drinks", | |||
["Edible Food"] = "Edible Food", | |||
["Flowers"] = "Flowers", | |||
["Forge Products"] = "Forge Products", | |||
["Gloves"] = "Gloves", | |||
["Grave Products"] = "Grave Products", | |||
["Heavy Boots"] = "Heavy Boots", | |||
["Heavy Chest"] = "Heavy Chest Armor", | |||
["Heavy Helmet"] = "Heavy Helmets", | |||
["Heavy Legs"] = "Heavy Legs", | |||
["Holy Products"] = "Holy Products", | |||
["Knife"] = "Knives", | |||
["Large Axe"] = "Large Axes", | |||
["Large Shield"] = "Large Shields", | |||
["Large Sword"] = "Large Swords", | |||
["Light Armor"] = "Light Armor", | |||
["Light Boots"] = "Light Boots", | |||
["Light Chest"] = "Light Chest Armor", | |||
["Light Helmet"] = "Light Helmets", | |||
["Light Legs"] = "Light Legs", | |||
["Light Mask"] = "Light Masks", | |||
["Light Neck"] = "Light Neck Armor", | |||
["Light Sources"] = "Light Sources", | |||
["Monster Products"] = "Monster Products", | |||
["Necklace"] = "Necklaces", | |||
["North Products"] = "North Products", | |||
["Orb"] = "Orbs", | |||
["Plains Products"] = "Plains Products", | |||
["Potions"] = "Potions", | |||
["Raw Food"] = "Raw Food", | |||
["Regular Sword"] = "Regular Swords", | |||
["Ring"] = "Rings", | |||
["Small Shield"] = "Small Shields", | |||
["Special Food"] = "Special Food", | |||
["Staff"] = "Staves", | |||
["Swamp Products"] = "Swamp Products", | |||
["Sword"] = "Swords", | |||
["Tools"] = "Tools", | |||
} | |||
-- Pluralize a type name for category | |||
local function pluralize(singular) | |||
return typePlurals[singular] or (singular .. "s") | |||
end | |||
-- Stat definitions for monsters (keeping old table-based format) | -- Stat definitions for monsters (keeping old table-based format) | ||
| Line 247: | Line 307: | ||
table.insert(html, '</div>') | table.insert(html, '</div>') | ||
-- Categories (one per type) | -- Categories (one per type, pluralized) | ||
local categories = '' | local categories = '' | ||
for _, t in ipairs(types) do | for _, t in ipairs(types) do | ||
categories = categories .. '[[Category:' .. t .. ']]' | categories = categories .. '[[Category:' .. pluralize(t) .. ']]' | ||
end | end | ||
Revision as of 02:24, 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."
}
-- Type to plural category mapping
local typePlurals = {
["Arrows"] = "Arrows",
["Axe"] = "Axes",
["Book"] = "Books",
["Book Products"] = "Book Products",
["Bow"] = "Bows",
["Cloth Products"] = "Cloth Products",
["Conjured Arrows"] = "Conjured Arrows",
["Container"] = "Containers",
["Cooked Food"] = "Cooked Food",
["Cooking Items"] = "Cooking Items",
["Currency"] = "Currency",
["Dagger"] = "Daggers",
["Desert Products"] = "Desert Products",
["Drinks"] = "Drinks",
["Edible Food"] = "Edible Food",
["Flowers"] = "Flowers",
["Forge Products"] = "Forge Products",
["Gloves"] = "Gloves",
["Grave Products"] = "Grave Products",
["Heavy Boots"] = "Heavy Boots",
["Heavy Chest"] = "Heavy Chest Armor",
["Heavy Helmet"] = "Heavy Helmets",
["Heavy Legs"] = "Heavy Legs",
["Holy Products"] = "Holy Products",
["Knife"] = "Knives",
["Large Axe"] = "Large Axes",
["Large Shield"] = "Large Shields",
["Large Sword"] = "Large Swords",
["Light Armor"] = "Light Armor",
["Light Boots"] = "Light Boots",
["Light Chest"] = "Light Chest Armor",
["Light Helmet"] = "Light Helmets",
["Light Legs"] = "Light Legs",
["Light Mask"] = "Light Masks",
["Light Neck"] = "Light Neck Armor",
["Light Sources"] = "Light Sources",
["Monster Products"] = "Monster Products",
["Necklace"] = "Necklaces",
["North Products"] = "North Products",
["Orb"] = "Orbs",
["Plains Products"] = "Plains Products",
["Potions"] = "Potions",
["Raw Food"] = "Raw Food",
["Regular Sword"] = "Regular Swords",
["Ring"] = "Rings",
["Small Shield"] = "Small Shields",
["Special Food"] = "Special Food",
["Staff"] = "Staves",
["Swamp Products"] = "Swamp Products",
["Sword"] = "Swords",
["Tools"] = "Tools",
}
-- Pluralize a type name for category
local function pluralize(singular)
return typePlurals[singular] or (singular .. "s")
end
-- 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
-- Format description with bracketed text on separate lines and colored
local function formatDescription(desc)
if not desc or desc == "" then
return {}
end
local lines = {}
local remaining = desc
-- Pattern to find [bracketed text]
while remaining and remaining ~= "" do
local beforeBracket, bracketContent, afterBracket = remaining:match("^(.-)%[([^%]]+)%](.*)$")
if bracketContent then
-- Add any text before the bracket as jade-colored description
if beforeBracket and beforeBracket:match("%S") then
local trimmed = beforeBracket:match("^%s*(.-)%s*$")
if trimmed ~= "" then
table.insert(lines, string.format('<p class="color-jade">%s</p>', trimmed))
end
end
-- Add the bracketed text as columbia-colored (item-important)
table.insert(lines, string.format('<p class="color-columbia">[%s]</p>', bracketContent))
remaining = afterBracket
else
-- No more brackets, add remaining text as jade-colored
local trimmed = remaining:match("^%s*(.-)%s*$")
if trimmed ~= "" then
table.insert(lines, string.format('<p class="color-jade">%s</p>', trimmed))
end
remaining = nil
end
end
return lines
end
-- Split a comma-separated string into a table
local function splitTypes(typeStr)
if not typeStr or typeStr == "" then
return {}
end
local types = {}
for t in typeStr:gmatch("[^,]+") do
local trimmed = t:match("^%s*(.-)%s*$")
if trimmed and trimmed ~= "" then
table.insert(types, trimmed)
end
end
return types
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] or mw.title.getCurrentTitle().text
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 (with bracketed text handling)
local descLines = formatDescription(data.description)
for _, line in ipairs(descLines) do
table.insert(html, line)
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/10</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 display (show all types)
local types = splitTypes(data.type)
if #types > 0 then
table.insert(html, formatLine("[" .. table.concat(types, ", ") .. "]", "color-silver"))
end
table.insert(html, '</div>')
-- Categories (one per type, pluralized)
local categories = ''
for _, t in ipairs(types) do
categories = categories .. '[[Category:' .. pluralize(t) .. ']]'
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