如果你看到本段文字,说明该页面未正常加载全局JS,部分功能将无法使用,请点击 刷新 重新加载页面。
如果打开页面显示缩略图创建出错,请点击刷新或页面右上WIKI功能中的刷新按钮清除页面缓存并刷新,如果还有问题,请多尝试几次。
全站通知:

模块:舰娘图鉴

来自碧蓝航线WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

这个模块用于辅助模板:舰娘图鉴解析页面参数。
目前只用来处理台词方面的参数、潜艇狩猎范围。

舰娘台词

本模块会根据调用参数生成舰娘台词表格。

模块解析调用模板:舰娘图鉴的参数和模板页面调用本模块的参数,
将这些参数解析整理后传递给模块:舰娘台词
最后由模块:舰娘台词生成舰娘台词表格。

模板中{{#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