| 此模块使用Lua语言: |
{{P5X Character}}用于《女神异闻录:夜幕魅影》登场角色。
除基础信息(分组、名字、声优)外,每个部分的填写项均为可选,不填的部分不会显示。示例:
{{P5X Character
|group = P5X/P5/P3
|name = 完整角色名,包含形态
|cv = 日文声优
|cv-zh = 中文声优
|<!-- 图片 -->
|image = 立绘,只有协同者数据而没有怪盗数据的用这个参数并删除以下参数,有怪盗数据的不用这个参数
|image-card = 卡面图片,所有图片均为解包图
|image-normal = 常服图片
|image-phantom = 怪盗服图片
|image-persona = 人格面具图片
|image-all-out = 总攻击图片
|image-final = 总攻击最后一击图片
|<!-- 档案 -->
|birthday = 生日
|blood-type = 血型
|age = 年龄
|occupation = 职业
|height = 身高
|weight = 体重
|favorite-food = 喜欢的食物
|hobbies = 兴趣
|talents = 特长
|synergy-description = 协同效果
|profile-description = 档案→故事→角色详情
|<!-- 协同者 -->
|rank-1 = 等级1解锁内容标题
|rank-1-description = 等级1解锁内容详情
|rank-? =
|rank-?-description =
|<!-- 怪盗 -->
|star = 4/5
|codename = 代号
|persona = 人格面具名称
|attribute = 属性/风冰/辅助
|role = 职业
|<!-- 属性克制,格式为“属性 = 耐/弱/无/反” -->
|念动 = 耐
|核热 = 弱
|phantom-description = 角色介绍
|persona-description = 人格面具介绍
|<!-- 技能 -->
|skill-1 = 技能1名字
|skill-1-sp = 技能1SP
|skill-1-type = 技能1属性,2个字
|skill-1-description = 技能1介绍,数值用{{荧光笔|xxx}}
|skill-2 =
|skill-2-sp =
|skill-2-type =
|skill-2-description =
|skill-3 =
|skill-3-sp =
|skill-3-type =
|skill-3-description =
|skill-4 = 战斗技巧
|skill-4-description = 『HIGHLIGHT』:<br />『ONE MORE』:对1名敌人造成XX属性伤害。<br />近战攻击:使用近战武器,对1名敌人造成物理属性的少量伤害。
|skill-5 =
|skill-5-description =
|skill-6 =
|skill-6-description =
|<!-- 意识 -->
|awareness-0 = 意识1名字
|awareness-0-description = 意识1说明
|awareness-1 =
|awareness-1-description =
|awareness-2 =
|awareness-2-description =
|awareness-3 =
|awareness-3-description =
|awareness-4 =
|awareness-4-description =
|awareness-5 =
|awareness-5-description =
|awareness-6 =
|awareness-6-description =
|<!-- 武器 -->
|weapon-4 = 4星武器名字
|weapon-4-description = 4星武器说明
|weapon-5 =
|weapon-5-description =
}}
local p = {}
local getArgs = require('Module:Arguments').getArgs
local row = function(label, value)
return [[<div class="p5x-chara-row">
<div class="p5x-chara-label">]] .. label .. [[</div>
<div class="p5x-chara-value">]] .. value .. [[</div>
</div>]]
end
local description = function(label, value, start)
return [[<div class="p5x-chara-row-vertical]] .. (start and ' p5x-chara-row-start' or '') .. [[">
<div class="p5x-chara-label">]] .. label .. [[</div>
<div class="p5x-chara-value p5x-chara-description"><p>]] .. value .. [[</p></div>
</div>]]
end
local image_configuration = {
{ '', '图片' },
{ 'card', '卡面' },
{ 'normal', '常服' },
{ 'phantom', '怪盗服' },
{ 'persona', '人格面具' },
{ 'all-out', '总攻击' },
{ 'final', '总攻击最后一击' },
}
function p.image(frame, args)
local tabs = args['tabs'] or ''
local output = '<div class="p5x-chara-image-cell">'
if tabs ~= '' then
return output .. tabs .. '</div>'
end
local tabs_output = {}
local tab_index = 1
local insert_tab = function(label, content)
if content and content ~= '' then
tabs_output['bt' .. tab_index] = label
tabs_output['tab' .. tab_index] = frame:preprocess(content)
tab_index = tab_index + 1
end
end
for _, config in ipairs(image_configuration) do
local key, label = config[1], config[2]
local image = nil
if key ~= '' then
image = args['image-' .. key] or ''
else
image = args['image'] or ''
end
if image ~= '' then
insert_tab(label, '[[File:' .. image .. '|760x400px]]')
end
end
local i = 1
while true do
local label = args['image-label-' .. i]
if label ~= nil then
insert_tab(label, '[[File:' .. args['image-' .. i] .. '|760x400px]]')
i = i + 1
else
break
end
end
if tab_index < 3 then
return output .. (tabs_output['tab1'] or '') .. '</div>'
else
return output .. frame:expandTemplate {
title = 'Tabs',
args = tabs_output,
} .. '</div>'
end
end
function p.basic_information(frame, args)
local template = [[<div class="p5x-chara-name-cell">
<div class="p5x-chara-name">{{{name<includeonly>|{{PAGENAME}}</includeonly>}}}</div><!--
-->{{#if:{{{star|}}}|<div>{{repeat|{{{star|5}}}|★}}</div>}}<!--
--><div>CV:{{声优|{{{cv}}}}}{{#if:{{{cv-zh|}}}|(日文)/{{声优|{{{cv-zh}}}}}(中文)}}</div>
</div>]]
local frame_child = frame:newChild({ args = args })
return frame_child:preprocess(template)
end
function p.phantom(frame, args)
local codename = args['codename'] or ''
if codename == '' then
return ''
end
local output = {
'<div class="p5x-chara-header">怪盗信息</div>',
}
for _, config in ipairs({
{ 'codename', '代号', 'WONDER' },
{ 'persona', '人格面具', '???' },
{ 'role', '职业', '??', function(value)
if value ~= '??' then
return '[[File:P5X Icon Role ' .. value .. '.png|24px|link=]]' .. value
end
return value
end },
{ 'attribute', '属性', '?', function(value)
if value ~= '?' then
return '[[File:P5X Icon Attribute ' .. value .. '.png|36px|link=]]' .. value
end
return value
end },
}) do
local key, label, default, transform = config[1], config[2], config[3], config[4]
local value = args[key] or default
if transform then
value = transform(value)
end
table.insert(output, row(label, value))
end
table.insert(output, '<div class="p5x-chara-row p5x-chara-row-types">')
for i, element in ipairs({
'物理',
'射击',
'火焰',
'冰冻',
'疾风',
'电击',
'核热',
'念动',
'祝福',
'诅咒',
}) do
local value = args[element] or '—'
table.insert(output, [[<div class="p5x-chara-row-vertical">
<div class="p5x-chara-label">]] ..
('' or '[[File:P5X Icon Attribute ') .. element .. ('' or ' 2.png|24px|link=]]') .. [[</div>
<div class="p5x-chara-value">]] .. value .. [[</div>
</div>]])
if i % 5 == 0 then
table.insert(output, '</div><div class="p5x-chara-row p5x-chara-row-types">')
end
end
output[#output] = '</div>'
table.insert(output, description('角色介绍', args['phantom-description'] or '—', true))
table.insert(output, description('人格面具介绍', args['persona-description'] or '—'))
return table.concat(output, '\n')
end
function p.skills(frame, args)
local output = {}
for i = 1, 6 do
local skill = args['skill-' .. i] or ''
if skill ~= '' then
if #output == 0 then
table.insert(output, [[<div class="p5x-chara-header">技能</div>
<table class="p5x-chara-table">
<tr>
<th colspan="2" class="p5x-chara-label">名称</th>
<th class="p5x-chara-label">属性</th>
<th colspan="7" class="p5x-chara-label">说明</th>
</tr>]])
end
local skill_type = args['skill-' .. i .. '-type'] or '??'
local skill_sp = args['skill-' .. i .. '-sp'] or '??'
local skill_description = args['skill-' .. i .. '-description'] or '———'
table.insert(output, '<tr>\n<td colspan="2" class="p5x-chara-value">' .. skill .. '</td>')
if i <= 3 then
table.insert(output, '<td class="p5x-chara-value">' .. skill_type .. '<br />' .. skill_sp .. 'SP</td>')
elseif i == 4 then
table.insert(output, '<td class="p5x-chara-value">—</td>')
else
table.insert(output, '<td class="p5x-chara-value">潜能</td>')
end
table.insert(output,
'<td colspan="7" class="p5x-chara-value p5x-chara-description"><p>' .. skill_description .. '</p></td>\n</tr>')
end
end
if #output == 0 then
return ''
end
table.insert(output, '</table>')
return table.concat(output, '\n')
end
function p.awarenesses(frame, args)
local output = {}
for i = 0, 6 do
local awareness = args['awareness-' .. i] or ''
if awareness ~= '' then
if #output == 0 then
table.insert(output, [[<div class="p5x-chara-header">意识</div>
<table class="p5x-chara-table">
<tr>
<th class="p5x-chara-label">等级</th>
<th colspan="2" class="p5x-chara-label">名称</th>
<th colspan="7" class="p5x-chara-label">说明</th>
</tr>]])
end
local awareness_description = args['awareness-' .. i .. '-description'] or '———'
table.insert(output,
'<tr>\n<td class="p5x-chara-value">' ..
i .. '</td>')
table.insert(output, '<td colspan="2" class="p5x-chara-value">' .. awareness .. '</td>')
table.insert(output,
'<td colspan="7" class="p5x-chara-value p5x-chara-description"><p>' ..
awareness_description .. '</p></td>\n</tr>')
end
end
if #output == 0 then
return ''
end
table.insert(output, '</table>')
return table.concat(output, '\n')
end
function p.weapons(frame, args)
local output = {}
for i = 2, 5 do
local weapon = args['weapon-' .. i] or ''
if weapon ~= '' then
if #output == 0 then
table.insert(output, [[<div class="p5x-chara-header">武器</div>
<table class="p5x-chara-table">
<tr>
<th class="p5x-chara-label">星级</th>
<th colspan="2" class="p5x-chara-label">名称</th>
<th colspan="7" class="p5x-chara-label">说明</th>
</tr>]])
end
local weapon_description = args['weapon-' .. i .. '-description'] or '———'
table.insert(output,
'<tr>\n<td class="p5x-chara-value">' ..
i .. '</td>')
table.insert(output, '<td colspan="2" class="p5x-chara-value">' .. weapon .. '</td>')
table.insert(output,
'<td colspan="7" class="p5x-chara-value p5x-chara-description"><p>' .. weapon_description .. '</p></td>\n</tr>')
end
end
if #output == 0 then
return ''
end
table.insert(output, '</table>')
return table.concat(output, '\n')
end
function p.profile(frame, args)
local birthday = args['birthday'] or ''
if birthday == '' then
return ''
end
local output = {
'<div class="p5x-chara-header">协同者档案</div>',
}
for _, config in ipairs({
{ 'birthday', '生日', '???', function(value)
return frame:expandTemplate {
title = 'Birthday',
args = { value, ft = 1 },
}
end },
{ 'blood-type', '血型', '???', function(value)
if value == 'A型' or value == 'B型' or value == 'AB型' or value == 'O型' then
-- 为什么 Lua 正则表达式不支持“或”运算符
return '[[:Category:' .. value .. '|' .. value .. ']]{{ArticleCategory|' .. value .. '}}'
end
return value
end },
{ 'age', '年龄', '??' },
{ 'occupation', '职业', '??' },
{ 'height', '身高', '???cm' },
{ 'weight', '体重', '???kg' },
{ 'favorite-food', '喜欢的食物', '???' },
{ 'hobbies', '兴趣', '???' },
{ 'talents', '特长', '???' },
}) do
local key, label, default, transform = config[1], config[2], config[3], config[4]
local value = args[key] or default
if transform then
value = transform(value)
end
table.insert(output, row(label, value))
end
table.insert(output, description('协同效果', args['synergy-description'] or '—', true))
table.insert(output, description('角色详情', args['profile-description'] or '—'))
return table.concat(output, '\n')
end
function p.synergy_rewards(frame, args)
local output = {}
for i = 1, 20 do
local rank = args['rank-' .. i] or ''
if rank ~= '' then
if #output == 0 then
table.insert(output, [[<div class="p5x-chara-header">协同者等级奖励</div>
<table class="p5x-chara-table">
<tr>
<th class="p5x-chara-label">等级</th>
<th colspan="2" class="p5x-chara-label">名称</th>
<th colspan="7" class="p5x-chara-label">说明</th>
</tr>]])
end
local rank_description = args['rank-' .. i .. '-description'] or '———'
table.insert(output,
'<tr>\n<td class="p5x-chara-value">' ..
i .. '</td>')
table.insert(output, '<td colspan="2" class="p5x-chara-value">' .. rank .. '</td>')
table.insert(output,
'<td colspan="7" class="p5x-chara-value p5x-chara-description"><p>' .. rank_description .. '</p></td>\n</tr>')
end
end
if #output == 0 then
return ''
end
table.insert(output, '</table>')
return table.concat(output, '\n')
end
function p._main(frame, args)
local group = args['group'] or 'P5X'
local output = {
'<div class="p5x-chara-helper"></div>',
'<div class="p5x-chara p5x-chara-group-' .. mw.ustring.lower(group) .. '">',
}
local insert = function(value)
if value and value ~= '' then
table.insert(output, value)
end
end
-- 避免图片无链入
local image = 'P5X Background Pattern.webp'
if group == 'P3' then
image = 'P5X Background for P3R characters.png'
end
insert('<div style="display: none !important;">[[File:' .. image .. ']]</div>')
insert(p.image(frame, args))
insert(p.basic_information(frame, args))
insert(p.profile(frame, args))
insert(p.synergy_rewards(frame, args))
insert(p.phantom(frame, args))
insert(p.skills(frame, args))
insert(p.awarenesses(frame, args))
insert(p.weapons(frame, args))
table.insert(output, '</div>')
return frame:preprocess(table.concat(output, '\n'))
end
function p.main(frame)
return p._main(frame, getArgs(frame))
end
return p