-- Module:PokemonInfobox
-- 合并版:包含基础工具 + 多形态信息框生成器
local p = {}
-- ========== 第一部分:基础工具函数(原 Module:Pokemon Infobox) ========== --
-- 调用现有的 Pokemon Color 模块
local pokemonColor = require('Module:Pokemon Color')
-- 世代到游戏名称的映射
local genToGame = {
["1"] = "红/绿",
["1-2"] = "蓝",
["1-3"] = "皮卡丘",
["2"] = "金/银",
["2-2"] = "水晶版",
["3"] = "红宝石/蓝宝石",
["3-2"] = "火红/叶绿",
["3-3"] = "绿宝石",
["4"] = "钻石/珍珠",
["4-2"] = "白金",
["4-3"] = "心灵之金/灵魂之银",
["5"] = "黑/白",
["5-2"] = "黑2/白2",
["6"] = "X/Y",
["6-2"] = "欧米伽红宝石/阿尔法蓝宝石",
["7"] = "太阳/月亮",
["7-2"] = "究极之日/究极之月",
["7-3"] = "Let's Go! 皮卡丘/Let's Go! 伊布",
["8"] = "剑/盾",
["8-2"] = "晶灿钻石/明亮珍珠",
["8-3"] = "传说 阿尔宙斯",
["9"] = "朱/紫",
["9-2"] = "传说 Z-A"
}
-- 世代到中文数字的映射
local genToChinese = {
["1"] = "一",
["2"] = "二",
["3"] = "三",
["4"] = "四",
["5"] = "五",
["6"] = "六",
["7"] = "七", ["7-2"] = "七", ["7-3"] = "七",
["8"] = "八", ["8-2"] = "八", ["8-3"] = "八",
["9"] = "九", ["9-2"] = "九"
}
-- 获取游戏名称(修复版)
function p.getGameName(frame)
local gen
-- 判断是直接传入字符串,还是通过#invoke传入frame
if type(frame) == "table" and frame.args then
gen = frame.args[1]
else
gen = frame -- 直接传入的值,如 p.getGameName("1")
end
return genToGame[gen] or "未知"
end
-- 获取完整游戏名称(修复版)
function p.getFullGameName(frame)
local gen
if type(frame) == "table" and frame.args then
gen = frame.args[1]
else
gen = frame
end
local gameName = genToGame[gen] or "未知"
if gen == "7" or gen == "7-2" or gen == "7-3" then
return "精灵宝可梦 " .. gameName
elseif gen == "8-3" or gen == "9-2" then
return "宝可梦" .. gameName
else
return "宝可梦 " .. gameName
end
end
-- 获取世代中文数字(修复版)
function p.getGenChinese(frame)
local gen
if type(frame) == "table" and frame.args then
gen = frame.args[1]
else
gen = frame
end
return genToChinese[gen] or "未知"
end
-- 获取类型颜色(修复版)
function p.getTypeColor(frame)
local typeName
if type(frame) == "table" and frame.args then
typeName = frame.args[1]
else
typeName = frame
end
return pokemonColor.getColor({args = {typeName}}) or "2980ef" -- 默认水属性颜色
end
-- 生成属性分类
function p.getTypeCategories(frame)
local types = {}
local args = frame.args
-- 收集所有类型参数
for key, value in pairs(args) do
if string.match(key, "^type%d+") and value and value ~= "" then
table.insert(types, value)
end
end
local result = {}
for _, typeName in ipairs(types) do
table.insert(result, "{{ArticleCategory|" .. typeName .. "属性宝可梦}}")
end
return table.concat(result, "")
end
-- 生成左侧样式
function p.getLeftStyle(frame)
local typeName = frame.args[1] or frame
if type(typeName) == "table" then typeName = typeName.args[1] end
local color = p.getTypeColor(typeName) or "2980ef"
return 'style="background-color: #' .. color .. '; color: #FFF; width: 56px;"'
end
-- 生成行样式
function p.getRowStyle(frame)
local typeName = frame.args[1] or frame
if type(typeName) == "table" then typeName = typeName.args[1] end
local color = p.getTypeColor(typeName) or "2980ef"
return 'style="background-color: #' .. color .. '; color: #FFF;"'
end
-- 生成头部样式
function p.getHeaderStyle(frame)
local typeName = frame.args[1] or frame
if type(typeName) == "table" then typeName = typeName.args[1] end
local color = p.getTypeColor(typeName) or "2980ef"
return 'style="background-color: #' .. color .. '; color: #FFF; padding: 1em;"'
end
-- ========== 第二部分:多形态信息框生成器 ========== --
-- 获取参数的辅助函数,支持回退
local function getArg(args, baseName, formSuffix, fallback)
local key = baseName
if formSuffix and formSuffix ~= "" then
key = baseName .. formSuffix
end
local val = args[key]
if val == nil or val == "" then
return fallback
end
return val
end
-- 生成图片部分
local function buildImage(args, suffix)
local image = getArg(args, "image", suffix, "")
local size = args["size"] or "280px"
local caption = getArg(args, "caption", suffix, "")
local english = args["英文"] or ""
local gen = args["gen"] or ""
if image ~= "" then
return '[[File:' .. image .. '|' .. size .. ']]<br>' .. caption
else
if args["娘"] then
return '{{ArticleCategory|无设定图的娘化条目}}'
else
local englishForm = getArg(args, "英文", suffix, "")
local fileName = 'Pokemon_Gen' .. gen .. '_' .. english
if englishForm ~= "" and englishForm ~= english then
fileName = fileName .. '_' .. englishForm
end
fileName = fileName .. '.png'
return '[[File:' .. fileName .. '|' .. size .. ']]<br>' .. caption
end
end
end
-- 生成单个形态的信息框 HTML
local function buildFormInfobox(args, formIndex)
local suffix = (formIndex == 1) and "" or "-" .. tostring(formIndex)
local formName = getArg(args, "form", suffix, args["中文"] or mw.title.getCurrentTitle().text)
local type1 = getArg(args, "type1", suffix, getArg(args, "type1", "", ""))
local type2 = getArg(args, "type2", suffix, getArg(args, "type2", "", ""))
local english = getArg(args, "英文", "", "")
local englishForm = getArg(args, "英文", suffix, "")
local displayEnglish = english
if englishForm ~= "" and englishForm ~= english then
displayEnglish = english .. " (" .. englishForm .. ")"
end
-- 调用本模块函数获取样式
local headerStyle = p.getHeaderStyle(type1)
local rowStyle = p.getRowStyle(type1)
local leftStyle = p.getLeftStyle(type1)
-- 构建wikitext
local infobox = {}
table.insert(infobox, '{| class="infobox pm-infobox" align="right" style="font-size: 89%; text-align: center; width: 320px; max-width: 100%; float: right; background-color: #FFF;"')
table.insert(infobox, '! colspan="4" ' .. headerStyle .. ' | ' .. (args["中文"] or mw.title.getCurrentTitle().text) .. (args["娘"] or ""))
table.insert(infobox, '|-')
table.insert(infobox, '| colspan="4" | ' .. buildImage(args, suffix))
table.insert(infobox, '|-')
table.insert(infobox, '! colspan="4" ' .. rowStyle .. ' | 基本信息')
table.insert(infobox, '|-')
table.insert(infobox, '| ' .. leftStyle .. ' | 编号 || # ' .. getArg(args, "编号", "", "???"))
table.insert(infobox, '| ' .. leftStyle .. ' | 初次登场 || [[' .. p.getFullGameName(args["gen"]) .. '|' .. p.getGameName(args["gen"]) .. ']]')
table.insert(infobox, '|-')
table.insert(infobox, '| ' .. leftStyle .. ' | 日文 || -{{' .. getArg(args, "日文", "", "日本語") .. '}}-')
table.insert(infobox, '| ' .. leftStyle .. ' | 英文 || ' .. displayEnglish)
table.insert(infobox, '|-')
-- 旧译
local oldTrans = getArg(args, "旧译", suffix, getArg(args, "舊譯", suffix, ""))
if oldTrans ~= "" then
table.insert(infobox, '| ' .. leftStyle .. ' | 旧译 || colspan="3" | ' .. oldTrans)
table.insert(infobox, '|-')
end
-- 常用称呼
local nicknames = getArg(args, "常用称呼", suffix, getArg(args, "常用稱呼", suffix, ""))
if nicknames ~= "" then
table.insert(infobox, '| ' .. leftStyle .. ' | 常用称呼 || colspan="3" | ' .. nicknames)
table.insert(infobox, '|-')
end
-- 属性
local typeLine = '{{Pokemon Type|' .. type1 .. '}}{{ArticleCategory|' .. type1 .. '属性宝可梦}}'
if type2 ~= "" then
typeLine = typeLine .. '<br>{{Pokemon Type|' .. type2 .. '}}{{ArticleCategory|' .. type2 .. '属性宝可梦}}'
end
table.insert(infobox, '| ' .. leftStyle .. ' | 属性 || ' .. typeLine .. ' || ' .. leftStyle .. ' | 分类 || ' .. getArg(args, "分类", suffix, getArg(args, "分類", suffix, "未知")) .. '宝可梦')
table.insert(infobox, '|-')
-- 特性
local ability = getArg(args, "特性", suffix, "无")
local hiddenAbility = getArg(args, "隐藏特性", suffix, getArg(args, "隱藏特性", suffix, ""))
local abilityColspan = (hiddenAbility == "") and "colspan=\"3\"" or ""
table.insert(infobox, '| ' .. leftStyle .. ' | 特性 || ' .. ability .. ' || style="' .. abilityColspan .. '" | ' .. ((hiddenAbility ~= "") and (' ' .. leftStyle .. ' | 隐藏特性 || ' .. hiddenAbility) or ""))
table.insert(infobox, '|-')
-- 身高体重
table.insert(infobox, '| ' .. leftStyle .. ' | 身高 || ' .. getArg(args, "身高", suffix, "未知") .. ' || ' .. leftStyle .. ' | 体重 || ' .. getArg(args, "体重", suffix, getArg(args, "體重", suffix, "未知")))
table.insert(infobox, '|-')
-- 进化链
local evoChain = getArg(args, "进化链", suffix, getArg(args, "進化鏈", suffix, ""))
if evoChain ~= "" then
table.insert(infobox, '| ' .. leftStyle .. ' | 进化链 || colspan="3" | ' .. evoChain)
table.insert(infobox, '|-')
end
-- 地区图鉴
local pokedex = getArg(args, "地区图鉴", suffix, getArg(args, "地區圖鑒", suffix, '<nowiki/>\n{{#invoke:Pokemon Number|main|' .. (args["中文"] or mw.title.getCurrentTitle().text) .. '}}'))
table.insert(infobox, '| ' .. leftStyle .. ' | 地区图鉴 || colspan="3" style="text-align: left;" | ' .. pokedex)
table.insert(infobox, '|-')
-- 娘化/原型 或 性别/蛋群
if args["娘"] then
local prototype = getArg(args, "原型", suffix, '[[' .. (args["中文"] or "") .. ']]')
table.insert(infobox, '| ' .. leftStyle .. ' | 原型 || colspan="3" | ' .. prototype)
else
table.insert(infobox, '| ' .. leftStyle .. ' | 性别比例 || ' .. getArg(args, "性别比例", suffix, getArg(args, "性別比例", suffix, "未知")) .. ' || ' .. leftStyle .. ' | 蛋群 || ' .. getArg(args, "蛋群", suffix, "无"))
end
table.insert(infobox, '|-')
-- 声优
local voiceActor = getArg(args, "声优", suffix, getArg(args, "聲優", suffix, getArg(args, "多位声优", suffix, getArg(args, "多位聲優", suffix, ""))))
if voiceActor ~= "" then
table.insert(infobox, '| ' .. leftStyle .. ' | 声优 || colspan="3" | ' .. voiceActor)
table.insert(infobox, '|-')
end
-- 萌点
local moePoints = getArg(args, "萌点", suffix, getArg(args, "萌點", suffix, ""))
if moePoints ~= "" then
table.insert(infobox, '| ' .. leftStyle .. ' | 萌点 || colspan="3" | ' .. moePoints)
table.insert(infobox, '|-')
end
-- 相关条目
local related = getArg(args, "相关条目", suffix, getArg(args, "相關條目", suffix, ""))
if related ~= "" then
table.insert(infobox, '| ' .. leftStyle .. ' | 相关条目 || colspan="3" | ' .. related)
table.insert(infobox, '|-')
end
-- 注释
local note = getArg(args, "注释", suffix, getArg(args, "注釋", suffix, ""))
if note ~= "" then
table.insert(infobox, '! colspan="4" ' .. rowStyle .. ' | 注释')
table.insert(infobox, '|-')
table.insert(infobox, '| colspan="4" style="text-align: left;" | ' .. note)
table.insert(infobox, '|-')
end
-- 相关链接
table.insert(infobox, '! colspan="4" ' .. rowStyle .. ' | 相关链接')
table.insert(infobox, '|-')
local links = '* [[cm:Category:' .. mw.title.getCurrentTitle().text .. '|萌娘共享上的图片]]\n'
links = links .. '* [https://wiki.52poke.com/wiki/ ' .. (args["中文"] or mw.title.getCurrentTitle().text) .. ' 神奇宝贝百科上的资料]'
local pokeNum = getArg(args, "编号", "", "???")
if pokeNum ~= "???" then
links = links .. '\n* -{zh-cn:[https://cn.portal-pokemon.com/play/pokedex/ ' .. pokeNum .. ' 宝可梦官网上的介绍];zh-tw:[https://tw.portal-pokemon.com/play/pokedex/ ' .. pokeNum .. ' 寶可夢官網上的介紹];}-'
end
local externalLink = getArg(args, "外部链接", suffix, getArg(args, "外部鏈接", suffix, ""))
if externalLink ~= "" then
links = links .. '\n' .. externalLink
end
table.insert(infobox, '| colspan="4" style="text-align: left;" | ' .. links)
table.insert(infobox, '|}')
return table.concat(infobox, '\n')
end
-- 主函数:生成带Tabs的完整HTML(原 Module:PokemonInfoboxMultiForm 的 main 函数)
function p.main(frame)
local args = frame:getParent().args
local forms = {}
-- 计算形态数量
local formCount = 0
for i = 1, 10 do -- 假设最多支持10种形态
if args["form" .. i] or (i == 1 and (args["中文"] or true)) then
formCount = i
else
break
end
end
-- 如果只有一种形态,直接返回信息框,不加Tabs
if formCount <= 1 then
return buildFormInfobox(args, 1)
end
-- 多形态:构建Tabs容器
local type1 = args["type1"] or "水"
local type2 = args["type2"] or type1
local borderColor = p.getTypeColor(type2)
local labelColor = p.getTypeColor(type1)
local tabs = {}
table.insert(tabs, '<div class="Tabs" data-text-padding="0" data-label-border-color="#' .. borderColor .. '" data-label-color="#' .. labelColor .. '" style="width: 320px; float: right;">')
for i = 1, formCount do
local formName = getArg(args, "form", (i == 1) and "" or "-" .. tostring(i), args["中文"] or mw.title.getCurrentTitle().text)
table.insert(tabs, '<div class="Tab">')
table.insert(tabs, '<div class="TabLabelText">' .. formName .. '</div>')
table.insert(tabs, '<div class="TabContentText">')
table.insert(tabs, buildFormInfobox(args, i))
table.insert(tabs, '</div></div>')
end
table.insert(tabs, '</div>')
return table.concat(tabs, '\n')
end
return p