bugfix20250107.1
全站通知:

模块:武器

来自卡拉彼丘WIKI_BWIKI_哔哩哔哩
跳到导航 跳到搜索

此模块的文档可以在模块:武器/doc创建

local p = {}

local stringUtil = require("模块:StringUtil")
local get = require("模块:Get")
local acandy = require("模块:ACandy")
local a, some, Raw, Fragment = acandy.a, acandy.some, acandy.Raw, acandy.Fragment
local div, span, li, ul, tr, th, td = a.div, a.span, a.li, a.ul, a.tr, a.th, a.td
local fun = require("模块:Fun")

local valueData = mw.loadData("模块:武器/Data")
local skinData = mw.loadData("模块:武器/SkinData")
local otherSkinData = mw.loadData("模块:武器/OtherSkinData")

local skinList = {}
for k, v in pairs(skinData or {}) do
	skinList[k] = v
end
for k, v in pairs(otherSkinData or {}) do
	skinList[k] = v
end

local function getPageTitle()
	return mw.title.getCurrentTitle().text
end

local function nonEmpty(str)
	return str and str ~= ""
end

local function strFallback(str, fallbackStr)
	return str ~= "" and str or fallbackStr
end

local qualityColor = {
	["私服"] = "#F78653",
	["传说"] = "#F85555",
	["完美"] = "#FFC555",
	["卓越"] = "#F285FF",
	["精致"] = "#60A3F7",
	["初始"] = "#ECECEC",
}


p["武器伤害"] = function (frame)
	local weaponName = getPageTitle()
	local weaponData = valueData[weaponName]
	assert(weaponData, "武器名称错误: "..(weaponName or "未知"))

	local Table = a.table[{ class = "klbqtable", style = "width:100%" }]

	if weaponName == "自由意志" or weaponName == "鸣火" then
		local damages = weaponData['伤害']
		return Fragment {
			'瞄准射击环形靶中心(默认弹丸数)',
			Table {
				tr / some.th('10米', '15米', '20米', '25米', '30米'),
				tr / some.td(damages[1], damages[2], damages[3], damages[4], damages[5]),
			},
		}
	elseif weaponName == "空境" or weaponName == "谢幕曲" then
		local damage = weaponData['伤害']
		return Table {
			tr {
				td { style = "width:15%" },
				some.th('10米', '20米', '30米', '40米', '50米', '60米', '70米'),
			},
			tr {
				th '头部',
				fun.range(7):map(function (i)
					return td {
						'基础:', damage['头部'][i], a.br,
						'蓄满:', damage['头部蓄满'][i],
					}
				end):totable(),
			},
			tr {
				th '上身',
				fun.range(7):map(function (i)
					return td {
						'基础:', damage['上身'][i], a.br,
						'蓄满:', damage['上身蓄满'][i],
					}
				end):totable(),
			},
			tr {
				th '下身',
				fun.range(7):map(function (i)
					return td {
						'基础:', damage['下身'][i], a.br,
						'蓄满:', damage['下身蓄满'][i],
					}
				end):totable(),
			},
		}
	end
	local damage = weaponData['伤害']
	return Table {
		tr {
			td { style = "width:15%" },
			some.th('10米', '20米', '30米', '40米', '50米'),
		},
		tr {
			th '头部',
			fun.range(5):map(function (i)
				return td { damage['头部'][i] }
			end):totable(),
		},
		tr {
			th '上身',
			fun.range(5):map(function (i)
				return td { damage['上身'][i] }
			end):totable(),
		},
		tr {
			th '下身',
			fun.range(5):map(function (i)
				return td { damage['下身'][i] }
			end):totable(),
		},
	}
end


p["武器部位伤害系数"] = function (frame)
	local weaponName = getPageTitle()
	local weaponData = valueData[weaponName]
	assert(weaponData, "武器名称错误: "..(weaponName or "未知"))

	local bodyMagnification = weaponData["部位伤害系数"]
	local magnMap = {
		["头部"] = bodyMagnification[1],
		["脖子"] = bodyMagnification[1],
		["胸部"] = bodyMagnification[2],
		["腹部"] = bodyMagnification[2],
		["骨盆"] = bodyMagnification[2],
		["左肩"] = bodyMagnification[2],
		["左上臂"] = bodyMagnification[2],
		["左前臂"] = bodyMagnification[2],
		["左手"] = bodyMagnification[2],
		["右肩"] = bodyMagnification[2],
		["右上臂"] = bodyMagnification[2],
		["右前臂"] = bodyMagnification[2],
		["右手"] = bodyMagnification[2],
		["左大腿"] = bodyMagnification[3],
		["左小腿"] = bodyMagnification[3],
		["左脚"] = bodyMagnification[3],
		["右大腿"] = bodyMagnification[3],
		["右小腿"] = bodyMagnification[3],
		["右脚"] = bodyMagnification[3],
		["装饰"] = bodyMagnification[3],
	}

	local formatRow = stringUtil.Formatter([[
|-
! {部位1}
| {倍率1}
! {部位2}
| {倍率2}
! {部位3}
| {倍率3}
]], '')
	local rows = get(
			{ "头部", "脖子", "胸部" },
			{ "腹部", "骨盆", "左肩" },
			{ "左上臂", "左前臂", "左手" },
			{ "右肩", "右上臂", "右前臂" },
			{ "右手", "左大腿", "左小腿" },
			{ "左脚", "右大腿", "右小腿" },
			{ "右脚", "装饰", "" }
		)
		:map(function (row)
			return formatRow {
				['部位1'] = row[1],
				['倍率1'] = magnMap[row[1]],
				['部位2'] = row[2],
				['倍率2'] = magnMap[row[2]],
				['部位3'] = row[3],
				['倍率3'] = magnMap[row[3]],
			}
		end)
		:all():concat()

	return stringUtil.fmt([[
{{| class="klbqtable" style="width: 100%"
|-
! colspan="3" | 基础伤害
| colspan="3" | {basicDamage}
{rows}
|}}
]], {
		basicDamage = weaponData["基础伤害"],
		rows = rows,
	})
end


p["武器外观"] = function (frame)
	local weaponName = getPageTitle()
	local weaponSkinData = skinList[weaponName]
    if not weaponSkinData then return "未找到武器数据" end
	local skinsByQuality = {
		["传说"] = {}, ["完美"] = {}, ["卓越"] = {}, ["精致"] = {},
	}
	-- 根据品质分类武器皮肤
	for skinName, skin in pairs(weaponSkinData) do
        local rarity = skin['稀有度']
        local skinsOfThisQuality = skinsByQuality[rarity]
        if skinsOfThisQuality then
            skinsOfThisQuality[#skinsOfThisQuality + 1] = skinName
        end
    end

	local tabLabels, tabBodies = {}, {}
	-- 创建每个品质的标签和内容
	for _, quality in ipairs({ "传说", "完美", "卓越", "精致" }) do
		local len = #tabLabels
		for i, skinName in ipairs(skinsByQuality[quality]) do
			local borderColor = qualityColor[quality]  -- 获取品质颜色
			tabLabels[len + i] = li { class = "bili-list-style", style = "border-radius: 6px;background:rgb(82,87,93);",
				span { class = "tab-panel", style = "border-radius: 5px;width:100%;border:4px solid "..borderColor..";",
					skinName,
				},
			}
			tabBodies[len + i] = div { class = "resp-tab-content",
				"[[文件:", weaponName, "外观-", skinName, ".jpg|x500px|center|link=|class=radius5]]",
			}
		end
	end
	if tabLabels[1] then
		tabLabels[1].class = tabLabels[1].class.." active"  -- 设置第一个标签为激活状态
		tabBodies[1].style = "display:block"  -- 显示第一个内容
	end

	-- 返回武器外观的HTML
	return div { class = "resp-tabs", style = "border-spacing:0",
		ul { class = "resp-tabs-list clearfix", style = "margin-left:0;margin-top:0",
			tabLabels,
		},
		div { class = "resp-tabs-container", style = "margin-bottom: 5px;",
			tabBodies,
		},
	}
end


p["武器瞄准镜样式"] = function (frame)
	local weaponName = getPageTitle()
	local weaponSkinData = skinData[weaponName]
    if not weaponSkinData then return "未找到武器数据" end
	local skinsByQuality = {
		["初始"] = {}, ["传说"] = {}, ["完美"] = {}, ["卓越"] = {},
	}

	for skinName, skin in pairs(weaponSkinData) do
        local rarity = skin['稀有度']
        local skinsOfThisQuality = skinsByQuality[rarity]
        if skinsOfThisQuality then
            skinsOfThisQuality[#skinsOfThisQuality + 1] = skinName
        end
    end

	local tabLabels, tabBodies = {}, {}

	tabLabels[1] = li { class = "bili-list-style active", style = "border-radius: 6px;background:rgb(82,87,93);",
		span { class = "tab-panel", style = "border-radius: 5px;width:100%;border:4px solid "..qualityColor["初始"]..";",
			"初始",
		},
	}
	tabBodies[1] = div { class = "resp-tab-content", style = "display:block",
		"[[File:瞄准镜样式 "..weaponName..".png|500px|center|link=|class=radius5]]",
	}

	local tabIndex = 2

	for _k, quality in ipairs({ "传说", "完美", "卓越" }) do
		for i, skinName in ipairs(skinsByQuality[quality]) do
			local borderColor = qualityColor[quality]
			tabLabels[tabIndex] = li { class = "bili-list-style", style = "border-radius: 6px;background:rgb(82,87,93);",
				span { class = "tab-panel", style = "border-radius: 5px;width:100%;border:4px solid "..borderColor..";",
					skinName,
				},
			}
			tabBodies[tabIndex] = div { class = "resp-tab-content",
				"[[File:瞄准镜样式 "..weaponName..skinName..".png|500px|center|link=|class=radius5]]",
			}
			tabIndex = tabIndex + 1
		end
	end

	return div { class = "resp-tabs", style = "border-spacing:0",
		ul { class = "resp-tabs-list clearfix", style = "margin-left:0;margin-top:0",
			tabLabels,
		},
		div { class = "resp-tabs-container", style = "margin-bottom: 5px;",
			tabBodies,
		},
	}
end


local function flattenSkinData(data)
    local flatData = {}
    for WeaponName, skins in pairs(data) do
        for skinName, skin in pairs(skins) do
            table.insert(flatData, {
                id = skin.id,
                ["武器"] = WeaponName,
                ["外观名称"] = skinName,
                ["稀有度"] = skin["稀有度"],
                ['获得方式'] = skin['获得方式'],
                ["巴布洛晶核"] = skin["巴布洛晶核"] or "",
                ["基弦"] = skin["基弦"] or "",
                ["简介"] = skin["简介"],
                ["备注"] = skin["备注"] or "",
            })
        end
    end
    return flatData
end

local function renderSkinImage(skin)
	local rarityPopupSet = { ["卓越"] = true, ["完美"] = true, ["传说"] = true }
    local file = "武器外观图鉴_" .. skin.id .. ".png"
    local weapon = skin['武器']
    local skinName = skin['外观名称']

    if rarityPopupSet[skin['稀有度']] then
        return '<span class="popup"><span style="display: table-cell;"><div style="position:relative;">[[File:'
            .. file .. '|200px|link=]]<br>' .. weapon .. ':' .. skinName
            .. '</div></span><span style="display:none;">[[file:'
            .. weapon .. '外观-' .. skinName .. '.jpg|200px]]</span></span>'
    end

    return '[[文件:' .. file .. '|200px|link=]]<br>' .. weapon .. ':' .. skinName
end

local function renderRarityTag(frame, skin)
	return frame:expandTemplate { title = '稀有度标签', args = { skin['稀有度'] } }
end

local function renderAcquireMethod(ways)
    if type(ways) ~= "table" then return "" end
    local parts = {}
    for _, part in ipairs(ways) do
        if part and part ~= "" then
            parts[#parts + 1] =
                '<span class="badge bg-primary" style="margin: 2px 0; font-size: 13px; white-space: nowrap;">'
                .. part .. '</span>'
        end
    end
    return table.concat(parts, "<br>")
end

----武器外观筛选页
p["武器外观筛选"] = function (frame)
	local flatData = flattenSkinData(skinList)

	local formatter = stringUtil.Formatter [=[
|- class="divsort" data-param1="{武器}" data-param2="{稀有度}" data-param3="{获得方式数据}" data-param4="{巴布洛晶核数据}" data-param5="{基弦数据}"
| style="padding: 2px;font-size: 16px;font-weight: 700;"|{外观}
| style="padding: 2px;"|{稀有度标签}
| style="width: 10%;padding: 2px"|{获得方式}
| style="width: 7%;padding: 2px"|{巴布洛晶核}
| style="width: 7%;padding: 2px"|{基弦}
| style="width: 40%;padding: 2px"|{简介}
| style="width: 15%;padding: 2px"|{备注}
]=]

	local result = {}

    for _, skin in ipairs(flatData) do
            local ways = skin["获得方式"] or {}
			local acquire_str = ""
			for i, v in ipairs(ways) do
    			if v and v ~= "" then
        			acquire_str = acquire_str .. (acquire_str ~= "" and "," or "") .. v
    			end
			end

            table.insert(result, formatter({
            	["武器"] = skin["武器"],
                ["稀有度"] = skin["稀有度"],
                ["外观"] = renderSkinImage(skin),
                ["稀有度标签"] = renderRarityTag(frame, skin),
                ["获得方式数据"] = acquire_str,
                ["巴布洛晶核数据"] = strFallback(skin["巴布洛晶核"], "无"),
                ["基弦数据"] = strFallback(skin["基弦"], "无"),
                ["巴布洛晶核"] = nonEmpty(skin["巴布洛晶核"]) and (skin["巴布洛晶核"] .. "[[文件:图标-小巴布洛晶核.png|15px|link=]]") or "",
                ["基弦"] = nonEmpty(skin["基弦"]) and (skin["基弦"] .. "[[文件:图标-小基弦.png|15px|link=]]") or "",
                ["获得方式"] = renderAcquireMethod(ways),
                ["简介"] = skin["简介"] or "",
                ["备注"] = skin["备注"] or "",
            }))
    end

    return table.concat(result)
end


----意识重构武器外观表
p["意识重构外观筛选"] = function (frame)
	local skinGet = frame.args[1]
	
	local function matchGetWay(ways, needle)
        if not needle or needle == "" then
            return true
        end
        if type(ways) == "table" then
            for _, w in ipairs(ways) do
                if string.find(w, needle, 1, true) then
                    return true
                end
            end
            return false
        end
        return false
	end

	local formatter = stringUtil.Formatter [=[
|-
| style="padding: 2px;font-size: 16px;font-weight: 700;"|{外观}
| style="padding: 2px;"|{稀有度标签}
| style="width: 70%"|{简介}
]=]

	local result = {}

    for weaponName, skins in pairs(skinList) do
        for skinName, skin in pairs(skins) do
            if matchGetWay(skin['获得方式'], skinGet) then
                table.insert(result, formatter({
                    ['外观'] = renderSkinImage({
                        ['id'] = skin.id,
                        ['武器'] = weaponName,
                        ['外观名称'] = skinName,
                        ['稀有度'] = skin['稀有度']
                    }),
                    ['稀有度标签'] = renderRarityTag(frame, skin),
                    ['简介'] = skin['简介'] or "",
                }, ''))
            end
        end
    end

    return table.concat(result)
end

return p