模块:舰娘图鉴
这个模块用于辅助模板:舰娘图鉴解析页面参数。
目前只用来处理台词方面的参数、潜艇狩猎范围。
舰娘台词
本模块会根据调用参数生成舰娘台词表格。
模块解析调用模板:舰娘图鉴的参数和模板页面调用本模块的参数,
将这些参数解析整理后传递给模块:舰娘台词,
最后由模块:舰娘台词生成舰娘台词表格。
模板中{{#invoke:舰娘图鉴}}
的参数会覆盖
{{舰娘图鉴}}
的参数。
之所以解析两层参数,是为了模板中对参数进行加工处理。
例如模板对特殊触摸台词参数使用模板:黑幕遮罩。
参数解析机制
表ShipWordsParameters
中定义了模块要检查的参数的名字。
例如
ShipWordsParameters = { login = {'登录台词', '登陆台词'}; }
则模块会依次查找以下参数是否被赋值:
{{ 舰娘图鉴 | login = | 登录台词 = | 登陆台词 = }}
若参数登录台词被赋值,则会继续查找以下参数:
{{ 舰娘图鉴 | 登录台词_jp = | 登录台词_mediaFile = | 登录台词_jp_mediaFile = | 登录台词_2 = | 登录台词_2_jp = | 登录台词_2_mediaFile = | 登录台词_2_jp_mediaFile = | 登录台词_3 = | .... }}
- XX_jp是台词的日文。
- XX_mediaFile是台词的语音文件。
- 若同一句台词对应日文中文两个语音,则用XX_jp_mediaFile设置日文语音。
- 若有多句台词,则用XX_2顺延。
- 目前最大到XX_15。
媒体文件默认值
若参数登陆台词非空,则会默认
{{ 舰娘图鉴 | 登录台词_mediaFile = {{{名称}}}login.mp3 }}
其中{{{名称}}}
是舰娘名字,由参数名称确定。
表ShipWordsParameters
中可以定义默认媒体文件默认值。
例如:
ShipWordsParameters = { unlock = {'获取台词', '获得台词', mediaFile = '%sget.mp3'}; }
则当页面独角兽有unlock台词时,默认媒体文件名为独角兽get.mp3。
空值
这里的空值是指调用模板或模块时为参数提供了空白字符串。
例如:
{{ 舰娘图鉴 | 登录台词 = | 登陆台词 = }}
这里登录台词和登陆台词传入的都是空白值。
ShipWordsParameters = { login = {'登录台词', '登陆台词'}; }
目前的函数实现是:
当遇到登录台词参数时,
函数会停止检查后面的参数登陆台词。
又因为登录台词为空值,
函数不会继续检查XX_jpXX_mediaFileXX_2,
也不会为XX_mediaFile设置默认值。
因此生成的表格中,会出现一行登录台词的空白行。
主界面台词与彩蛋台词
主界面台词(main
)除了会按照以上规则处理外:
- 还会检查主界面N台词。
- N为1~15。可以间断。
- 主界面N台词非空时,会覆盖主界面台词_N设定的值。
- 主界面N台词非空时,会检查主界面N台词_jp主界面N台词_mediaFile等。
- 默认媒体文件名为
{{{名称}}}main_N.mp3
彩蛋台词(couple_encourage
)除了会按照以上规则处理外:
- 还会检查彩蛋N台词。
- N为1~15。不可间断。
- 彩蛋N台词非空时,会覆盖彩蛋台词_N设定的值。
- 彩蛋N台词非空时,会检查彩蛋N台词_jp彩蛋N台词_mediaFile等。
- 默认媒体文件名为
{{{名称}}}linkN.mp3
潜艇范围
用于显示潜艇狩猎范围,沿用了模板:狩猎范围的参数格式。
- 参数列表
#1 表格的类名(submarineRangeXXX)可省略。 T 表格标题。可省略。 A 第1行。可省略。 B...G 第2~7行。可省略。
- 示例
{{#invoke:舰娘图鉴|生成潜艇范围表格 |U-81Lv1 |A= |B=3、4、5 |C=2-3-4-5-6 |D=2 3 4 5 6 |E=3,4,5 |F=3、4、5 |G=}}
- 预览
--这个脚本用于帮助[[模板:舰娘图鉴]]解析页面参数
--目前只用来处理台词方面的参数
local p = {}
local mSW = require('模块:舰娘台词')
--------------------------------------------------
-- 主要过程
--------------------------------------------------
local ShipWordsParameters = mSW.ShipWordsParameters
--从当前页面的参数列表解析生成舰娘台词的参数列表
function ParseShipWordsParameters(args, shipName)
local data = {};
--------------------------------------------------
-- 遍历所有页面参数
--------------------------------------------------
for k, paramData in pairs(ShipWordsParameters) do
local text;
local param;
local mediaFile;
--找到一个被赋值了的页面参数
if args[k] then
param = k
elseif type(paramData) == 'string' then
param = paramData
text = args[param]
elseif type(paramData) == 'table' then
mediaFile = paramData.mediaFile
for _, p in ipairs(paramData) do
param = p
text = args[p]
if text then break end
end
end
if text then
--若为参数提供了空白值
--则显示空白行
data[k] = data[k] or {}
text = trimNullOrEmpty(text)
end
if text then
--[[
data[k] = {
[1] = {
text = '中文文本'
jp = '日文文本'
mf = 'xxx.mp3'
jp_mf = 'xxx2.mp3'
}
} ]]
for i = 1, 15 do
local keyI = i == 1 and param or param..'_'..i
text = trimNullOrEmpty(args[keyI])
if not text then break end
data[k][i] = data[k][i] or {}
data[k][i].text = text
data[k][i].jp = trimNullOrEmpty(args[keyI..'_jp'])
data[k][i].mf = trimNullOrEmpty(args[keyI..'_mediaFile'])
data[k][i].jp_mf = trimNullOrEmpty(args[keyI..'_jp_mediaFile'])
--设置默认媒体文件名
if i == 1 and not data[k][i].mf and shipName then
data[k][i].mf = mediaFile
and mediaFile:format(shipName)
or shipName .. k ..'.mp3';
end
end
end
end
--------------------------------------------------
-- 处理main参数序列
--------------------------------------------------
local k = 'main'
local text;
local mediaFile = type(ShipWordsParameters[k]) == 'table' and ShipWordsParameters[k].mediaFile
for i = 1, 15 do
local keyI = '主界面'..i..'台词'
text = trimNullOrEmpty(args[keyI])
if text then
data[k] = data[k] or {}
data[k][i] = data[k][i] or {}
data[k][i].text = text
data[k][i].jp = trimNullOrEmpty(args[keyI..'_jp'])
data[k][i].mf = trimNullOrEmpty(args[keyI..'_mediaFile'])
data[k][i].jp_mf = trimNullOrEmpty(args[keyI..'_jp_mediaFile'])
--设置默认媒体文件名
if not data[k][i].mf and shipName then
data[k][i].mf = mediaFile
and mediaFile:format(shipName)
or shipName .. 'main_'.. i ..'.mp3';
end
end
end
--兼容旧的<br>写法
if data['main'] and table.maxn(data['main']) == 1 then
local spl = mw.text.split(data['main'][1].text, '<br ?/?>')
if #spl > 1 then
for i = 1, #spl do
data['main'][i] = data['main'][i] or {}
data['main'][i].text = trimNullOrEmpty(spl[i])
end
end
end
--------------------------------------------------
-- 处理couple_encourage参数序列
--------------------------------------------------
k = 'couple_encourage'
mediaFile = type(ShipWordsParameters[k]) == 'table' and ShipWordsParameters[k].mediaFile
for i = 1, 15 do
local keyI = '彩蛋'..i..'台词'
text = trimNullOrEmpty(args[keyI])
if not text then break end
data[k] = data[k] or {}
data[k][i] = data[k][i] or {}
data[k][i].text = text
data[k][i].jp = trimNullOrEmpty(args[keyI..'_jp'])
data[k][i].mf = trimNullOrEmpty(args[keyI..'_mediaFile'])
data[k][i].jp_mf = trimNullOrEmpty(args[keyI..'_jp_mediaFile'])
--设置默认媒体文件名
if not data[k][i].mf and shipName then
data[k][i].mf = mediaFile
and mediaFile:format(shipName)
or shipName .. 'link'.. i ..'.mp3';
end
end
--兼容旧的<br>写法
if data['couple_encourage'] and #data['couple_encourage'] == 1 then
local spl = mw.text.split(data['couple_encourage'][1].text, '<br ?/?>')
if #spl > 1 then
for i = 1, #spl do
data['couple_encourage'][i] = data['couple_encourage'][i] or {}
data['couple_encourage'][i].text = trimNullOrEmpty(spl[i])
end
end
end
--------------------------------------------------
-- 处理莱莎相关参数序列
--------------------------------------------------
for _, k in ipairs({"ryza_item", "ryza_shop", "ryza_atellier"}) do
mediaFile = type(ShipWordsParameters[k]) == 'table' and ShipWordsParameters[k].mediaFile
for i = 1, 15 do
local keyI = ShipWordsParameters[k][1]..i..'台词'
text = trimNullOrEmpty(args[keyI])
if not text then break end
data[k] = data[k] or {}
data[k][i] = data[k][i] or {}
data[k][i].text = text
data[k][i].jp = trimNullOrEmpty(args[keyI..'_jp'])
data[k][i].mf = trimNullOrEmpty(args[keyI..'_mediaFile'])
data[k][i].jp_mf = trimNullOrEmpty(args[keyI..'_jp_mediaFile'])
--设置默认媒体文件名
if not data[k][i].mf and shipName then
data[k][i].mf = mediaFile
and mediaFile:format(shipName)
or shipName ..k.. i ..'.mp3';
end
end
end
--------------------------------------------------
-- 处理闪乱神乐NL相关参数序列
--------------------------------------------------
for _, k in ipairs({"sknl_pt"}) do
mediaFile = type(ShipWordsParameters[k]) == 'table' and ShipWordsParameters[k].mediaFile
for i = 1, 15 do
local keyI = ShipWordsParameters[k][1]..i..'台词'
text = trimNullOrEmpty(args[keyI])
if not text then break end
data[k] = data[k] or {}
data[k][i] = data[k][i] or {}
data[k][i].text = text
data[k][i].jp = trimNullOrEmpty(args[keyI..'_jp'])
data[k][i].mf = trimNullOrEmpty(args[keyI..'_mediaFile'])
data[k][i].jp_mf = trimNullOrEmpty(args[keyI..'_jp_mediaFile'])
--设置默认媒体文件名
if not data[k][i].mf and shipName then
data[k][i].mf = mediaFile
and mediaFile:format(shipName)
or shipName ..k.. i ..'.mp3';
end
end
end
--------------------------------------------------
-- 设置周年语音
--------------------------------------------------
data.extra5th = {
{ text = '碧蓝航线,五周年快乐!', mf = shipName..'extra5th.mp3' }
}
data.extra6th = {
{ text = '碧蓝航线,六周年快乐!', mf = shipName..'extra6th.mp3' }
}
data.extra = {
{ text = '碧蓝航线!', mf = shipName..'extra.mp3' }
}
return data
end
--解析潜艇狩猎范围参数
function parseSubmarineRangeArguments(frame)
local args = {}
--狩猎范围
for i, x in ipairs {'A','B','C','D','E','F','G'} do
for s in (frame.args[x] or ''):gmatch('%d+') do
args[i*100 + tonumber(s)] = true
end
end
--表格ID
args.id = trimNullOrEmpty(frame.args[1])
args.id = args.id and 'submarineRange' .. args.id
--表格标题
args.title = trimNullOrEmpty(frame.args['T'])
return args
end
--------------------------------------------------
-- 公开函数
--------------------------------------------------
p['生成台词表格'] = function()
local frame = mw.getCurrentFrame()
local parent = frame:getParent()
--合并页面参数
local args = {}
if parent then
for k, v in parent:argumentPairs() do
args[k] = v
end
end
for k, v in frame:argumentPairs() do
args[k] = v
end
local shipName = args['名称'] or '未命名'
local data = ParseShipWordsParameters(args, shipName)
return mSW.ShowShipWordsTable(data)
end
p['生成潜艇范围表格'] = function(frame)
local args = parseSubmarineRangeArguments(frame)
local result = ([[
<table class="wikitable noselect submarineRange %s">
]]):format(args.id or '')
--表格标题
if args.title then
result = result .. '<caption>'
.. args.title
.. '</caption>'
end
--潜艇区域
for i = 1, 7 do
result = result .. '<tr>'
for j = 1, 7 do
local inrange = args[i*100+j]
result = result ..
( inrange
and '<td class="select"></td>'
or '<td></td>'
)
end
result = result .. '</tr>'
end
result = result..'</table>'
return result
end
--------------------------------------------------
-- 工具函数
--------------------------------------------------
function trimNullOrEmpty(s)
if not s then return false end
s = mw.text.trim(s)
return s ~= '' and s
end
return p