全站通知:

模块:舰娘图鉴导航

来自一血万杰WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

此模块的文档可以在模块:舰娘图鉴导航/doc创建

--------------------------------------------------
--	TODO:
--	
--------------------------------------------------



--------------------------------------------------
--	调用模块:舰娘数据
--------------------------------------------------
local p = require('模块:舰娘数据')
local mSI = require('模块:舰娘图标')

--------------------------------------------------
--	公开函数
--------------------------------------------------

-- 显示一个导航项目,参数#1 - 船名
p.ShowNavItem = function(frame)
	local data = { dye = 3, transform = 1,}
	data.ship = normalizeShipName(frame.args[1])	
	return mSI.ParseShipTextOnly(data)
end
p["显示项目"] = p.ShowNavItem

-- 显示一段导航列表,参数#1 - 舰船类型
p.ShowNavListInType = function(frame)
	local ship_type = parseShipType(frame.args[1]) or 1;
	local list = getShipListInType(ship_type)
	if #list < 1 then return '' end
	local last_rare = p.ship_data[list[1]].rarity
	for i = 1, #list do
		local ship = list[i]
		local rare = p.ship_data[ship].rarity
		list[i] = ('•&nbsp;[[%s|<span style="color:%s;">%s</span>]]'):format(
					ship, rarityToColor(rare), ship
				)
		if rare ~= last_rare then
			list[i] = '<br>'..list[i]
			last_rare = rare
		end
	end
	return table.concat(list)
end
p["依类型显示导航列表"] = p.ShowNavListInType 

--显示所有改造的舰船列表
p.ShowNavListOfKai = function(frame)
	local list = {}
	for ship, data in pairs(p.ship_data) do
		if data.transform then
			table.insert(list, data)
			data.name = ship
		end
	end
	
	table.sort(list, function(a, b)
		if a.rarity ~= b.rarity then
			return a.rarity > b.rarity
		elseif a.nationality ~= b.nationality then 
			return a.nationality < b.nationality 
		elseif a.type ~= b.type then 
			return a.type > b.type
		else
			return a.id < b.id
		end
	end)
	
	if #list < 1 then return '' end
	
	local last_rare = list[1].rarity
	local data = { dye = 2, transform = 3 }
	for i = 1, #list do
		local ship = list[i]
		local rare = ship.rarity
		data.ship = ship.name
		list[i] = '•&nbsp;'.. mSI.ParseShipTextOnly(data)..' '
		
		if rare ~= last_rare then
			list[i] = '<br>'..list[i]
			last_rare = rare
		end
	end
	return table.concat(list)
end
p["依改造显示导航列表"] = p.ShowNavListOfKai 

-- 显示整个导航区域
p.ShowNavTableContent = function(frame)
	local content = [[
{| style="width:100%;" class="table-ShowNavTableContent"
]]
	local table_line = [[
|-
! style="width:8%%;text-align:center" | %s
| %s
|-
| colspan=2|
----
]]	-- {1} = 驱逐、战列等;{2} = 舰船列表
	local postfix = [[
|} ]]

	--当前页面的名称
	local current_title = normalizeShipName(mw.title.getCurrentTitle().text)
	
	local data = {}
	--分类汇总
	for k, v in pairs(p.ship_data) do
		data[v.type] = data[v.type] or {}
		table.insert(data[v.type], k)
	end
	--遍历每个舰船类型
	for ship_type, ship_list in pairs(data) do
		--排序(稀有度高,国家编号小,舰船编号小)
		table.sort(ship_list, function(x,y)
			local tx = p.ship_data[x]
			local ty = p.ship_data[y]
			if tx.rarity ~= ty.rarity then 
				return tx.rarity > ty.rarity 
			end
			if tx.nationality ~= ty.nationality then 
				return tx.nationality < ty.nationality 
			end
			return tx.id < ty.id
		end)
		
		--记录最后一个稀有度,用于按稀有度换行
		local last_rare = #ship_list > 0
				and p.ship_data[ship_list[1]].rarity
				or 0
		
		--遍历每个舰船
		local tmp = { dye = 3, transform = 1,}
		for i = 1, #ship_list do
			local ship = ship_list[i]
			tmp.ship = ship						--舰娘名称
			tmp.rarity = p.ship_data[ship].rarity 		--舰娘稀有度
			
			local html = mSI.ParseShipTextOnly(tmp);
			ship_list[i] = ('•&nbsp;%s '):format(html);
			
			if tmp.rarity ~= last_rare then
				ship_list[i] = '<br>'..ship_list[i]
				last_rare = tmp.rarity
			end
		end
		
		content = content..table_line:format(
						typeIdToName(ship_type),
						table.concat(ship_list)
					);
	end
	
	return content..postfix
end
p["显示导航列表"] =p.ShowNavTableContent 

--显示带标签页的导航面板
p.ShowNavTabTable = function(frame)

	--当前页面的名称
	local curShip = normalizeShipName(mw.title.getCurrentTitle().text)
	local curNation = p.ship_data[curShip] and p.ship_data[curShip].nationality or 1
	
	local ship_data = p.ship_data	
	
	--分类汇总
	local data = {}
	for k, v in pairs(p.ship_data) do
		data[v.nationality] = data[v.nationality] or {}
		data[v.nationality][v.type] = data[v.nationality][v.type] or {}
		table.insert(data[v.nationality][v.type], k)
	end
	
	
	--标签页
	local args = {
		theme = 'primary',
		label_style = nil,
		[1] = { 
			title = '皇家',
			text = '胡德 厌战 反击 etc',
			id = 'en',
			active = 1
		}
	}
	
	--整理表data的索引
	local nation_list = {}
	for nation, _ in pairs(data) do
		table.insert(nation_list, nation)
	end
	table.sort(nation_list)
	
	--遍历所有阵营
	for index, nation in ipairs(nation_list) do
		local ship_list = data[nation]
		
		--表格开始
		local content = [[

{| style="width:100%;" class="table-ShowNavTabTable"
]]
		--遍历每一个类型
		for ship_type = 1, 13 do
			local list = ship_list[ship_type]
			if list and #list > 0 then
				
				--遍历每个舰船
				local tmp = { dye = 3, transform = 1,}
				for i = 1, #list do
					local ship = list[i]
					tmp.ship = ship						--舰娘名称
					
					local html = mSI.ParseShipTextOnly(tmp);
					list[i] = ('•&nbsp;%s '):format(html);
				end
				
				--表头
				content = content..[[
|-
! ]] .. typeIdToName(ship_type) .. [[

| ]] .. table.concat(list) .. '\n'
						
			end
		end
		--表格结束
		content = content.. '|}\n'
		
		args[index] = {
			title = nationIdToName(nation),
			text = content,
			id = 'Nav-'..nationIdToEn(nation):upper(),
			active = curNation == nation
		}
	end
	
	
	local mTBP = require('Module:选项卡面板')
	return mTBP.GenerateWholePanel(args)
end
p["显示标签页导航面板"]=p.ShowNavTabTable

--显示带标签页、按型号划分的导航面板
p.ShowShipClassNavPannel = function(frame, shipHtmlSerializer)

	--将舰娘名字转换为有样式的HTML文本
	shipHtmlSerializer = shipHtmlSerializer or function(ship)
		return ('•&nbsp;%s '):format(
			mSI.ParseShipTextOnly({ 
				dye = 3, 
				transform = 1,
				ship = ship
				})
		)
	end

	--当前页面的名称
	local curShip = normalizeShipName(mw.title.getCurrentTitle().text)
	local curNation = p.ship_data[curShip] and p.ship_data[curShip].nationality or 1
	
	--加载模块
	local mSDC = require('模块:舰娘数据/型号')
	local ship_data_class = mSDC.ship_data_class
	local ship_data = p.ship_data
		
	--分类汇总
	local data = {}
	for ship, v in pairs(ship_data) do
		data[v.nationality] = data[v.nationality] or {}
		data[v.nationality][v.type] = data[v.nationality][v.type] or {}
		
		--当ship_data中有该舰船,而ship_data_class中没有时
		if not ship_data_class[ship] then
			mw.log("ShowShipClassNavPannel> ship_data_class中缺少ship_data中记录的舰船-"..ship)
			ship_data_class[ship] = {id = v.id}
		end
		
		
		local v2 = ship_data_class[ship]
		local class = v2.class_des or '其他'
		data[v.nationality][v.type][class] = 
				data[v.nationality][v.type][class] or {}
		
		table.insert(data[v.nationality][v.type][class], ship)
	end
	
	--标签页面板参数
	local args = {
		theme = 'primary',
		label_style = 'font-weight:bolder;padding:0.5em 0.6em;cursor:pointer;',
		[1] = { 
			title = '皇家',
			text = '胡德 厌战 反击 etc',
			id = 'en',
			active = 1
		}
	}
	
	--整理表data的索引
	local nation_list = {}
	for nation, _ in pairs(data) do
		table.insert(nation_list, nation)
	end
	table.sort(nation_list)
	
	--遍历所有阵营
	for index, nation in ipairs(nation_list) do
		
		--表格开始
		local content = [[

<table class="table-ShowShipClassNavPannel" width="100%">
]]
		
		--遍历所有舰船类型
		for stype = 1, table.maxn(data[nation]) do
			
			if data[nation][stype] then
				--对舰船级别排序
				local class_list = {}
				
				for class, ship_list in pairs(data[nation][stype]) do
					table.insert(class_list, class)
					
					--对舰船进行排序
					table.sort(ship_list, function(a,b)
							return ship_data[a].id < ship_data[b].id
						end
					)
				end
				
				table.sort(class_list, function(a,b)
						if a == '其他' then
							return false
						elseif b == '其他' then
							return true
						end
						local shipA = data[nation][stype][a][1]
						local shipB = data[nation][stype][b][1]
						return ship_data_class[shipA].id 
							< ship_data_class[shipB].id
					end
				)
				
				
				--舰船类型表头
				if stype > 1 then
					content = content .. ([[
<tr class="tr-top">
<th class="th-ship-type" rowspan="%s">%s
</th>
]]):format(#class_list, typeIdToName(stype))
				else
					content = content .. ([[
<tr class="tr-top">
<th class="th-ship-type" rowspan="%s">%s
</th>
]]):format(#class_list, typeIdToName(stype))
				end
				
				
				--遍历所有舰船级别
				for i, class in ipairs(class_list) do
					local ship_list = data[nation][stype][class]
					local ship_v = ship_data_class[ship_list[1]]
					local class_name = class == '其他' and '其他舰船' 
								or ship_v.type_des and ('%s<span class="ship-class-postfix">%s</span>'):format(class, ship_v.type_des)
								or class
					
					
					--遍历每一艘船
					for j = 1, #ship_list do
						--解析为HTML文本
						ship_list[j] = shipHtmlSerializer(ship_list[j]);
					end
						
					
					--舰船级别表头 / 内容
					if i > 1 then
						content = content .. ([[
<tr>
<th class="th-ship-class">%s
</th>
<td>%s
</td>
</tr>
]]):format(class_name, table.concat(ship_list))
					else
						content = content .. ([[
<th class="th-ship-class">%s
</th>
<td>%s
</td>
</tr>
]]):format(class_name, table.concat(ship_list))
					
					end
					
				end
			end
		end
		
		--表格结束
		content = content.. '</table>\n'
		
		args[index] = {
			title = nationIdToName(nation),
			text = content,
			id = 'Nav-'..nationIdToEn(nation):upper(),
			active = curNation == nation
			}
	end
	
	
	local mTBP = require('Module:选项卡面板')
	return mTBP.GenerateWholePanel(args)
end
p['显示舰船型号导航面板'] = function(frame)

	local handler = frame.args[1] and mw.text.trim(frame.args[1])
	handler = handler and mSI[handler];
	local serializer;
	if (handler) then
		local ff = mw.getCurrentFrame();
		ff.args = parseArgument(frame);
	
		serializer = function(ship)
			frame.args[1] = ship;
			return (' %s '):format(
					handler(ff)
				)
		end
	end
	
	return p.ShowShipClassNavPannel(frame, serializer);
end

--------------------------------------------------
--	测试函数
--------------------------------------------------

p['测试'] = function(frame)
	mw.log('测试', frame[1])
	
	local foo = p[frame[1]]
	if not foo then
		local msg = ('函数%s不存在!'):format(frame[1] or 'nil')
		mw.log(msg)
		return msg
	end
	
	return mw.text.nowiki(foo(frame))
end


--------------------------------------------------
--	私有函数
--------------------------------------------------
--解析传入参数——去空白符+转换数字
function parseArgument(frame)
	local arg = {}
	for k, v in pairs(frame.args) do
		arg[k] = tonumber(v) or Text.trim(v)
	end
	return arg
end

function getShipListInType(shipType)
	local ret = {}
	for k, v in pairs(p.ship_data) do
		if v.type == shipType then
			table.insert(ret,k)
		end
	end
	--排序
	table.sort(ret, function(x,y)
		local tx = p.ship_data[x]
		local ty = p.ship_data[y]
		if tx.rarity ~= ty.rarity then 
			return tx.rarity > ty.rarity 
		end
		if tx.nationality ~= ty.nationality then 
			return tx.nationality < ty.nationality 
		end
		return tx.id < ty.id
	end)
	return ret
end

function parseShipType(text)
	if type(text) == 'number' then return number end
	text = trim(text)
	
	for id, stype in pairs(p.type_data) do
		if text == stype then
			return id
		end
	end
	
	return text == '轻航' and 6		--轻航
		or text == '轻母' and 6
		or text == '正航' and 7		--正航
		or text == '航母' and 7
		or text == '空母' and 7
		or nil
end

function typeIdToName(id)
	return p.TypeIdToName(id,  '未知')
end

function nationIdToName(id)
	return p.NationIdToName(id, '未知')
end

function nationIdToEn(id)
	return p.nation_data.prints[id] or 'nil'
end

function rarityToColor(n)
	return mSI.RarityToColor(n)
end

function trim(str)
	if not str then return '' end
	return mw.text.trim(str)
end

function normalizeShipName(str)
	return p.NormalizeShipName(trim(str or '') or '')
end


return p