装备:修订间差异
来自卡厄思梦境WIKI
无编辑摘要 |
无编辑摘要 |
||
| (未显示同一用户的5个中间版本) | |||
| 第67行: | 第67行: | ||
-- 将中文逗号(,)替换为英文逗号(,) | -- 将中文逗号(,)替换为英文逗号(,) | ||
return str:gsub(",", ",") | return str:gsub(",", ",") | ||
end | end | ||
| 第479行: | 第305行: | ||
local html = {} | local html = {} | ||
-- | -- 创建排序数组,过滤掉地区为 undefined 的装备 | ||
local equipList = {} | local equipList = {} | ||
for equipName, equipData in pairs(data) do | for equipName, equipData in pairs(data) do | ||
table.insert(equipList, { | local area = equipData.area or "" | ||
-- 跳过地区为 undefined 的装备 | |||
if area ~= "undefined" and area ~= "Undefined" and area ~= "UNDEFINED" then | |||
table.insert(equipList, { | |||
name = equipName, | |||
data = equipData, | |||
rarityOrder = rarityOrder[equipData.rarity] or 999, | |||
typeOrder = typeOrder[equipData.type] or 999 | |||
}) | |||
end | |||
end | end | ||
| 第501行: | 第331行: | ||
end) | end) | ||
-- | -- 稀有度颜色映射 | ||
local rarityColor = { | local rarityColor = { | ||
["蓝"] = "#34638c", | ["蓝"] = "#34638c", | ||
| 第528行: | 第352行: | ||
-- 处理地区数据 | -- 处理地区数据 | ||
local areaData = normalizeCommas(equipData.area or "") | local areaData = normalizeCommas(equipData.area or "") | ||
local areaDisplay = | local areaDisplay = "" | ||
if areaData == "" or areaData == "0" then | if areaData == "" or areaData == "0" then | ||
areaDisplay = "全地区" | areaDisplay = "全地区" | ||
areaData = "" -- | areaData = "" -- 确保筛选数据为空字符串 | ||
else | else | ||
-- 将逗号分隔的地区转换为换行显示 | |||
areaDisplay = areaData:gsub(",", "<br/>") | areaDisplay = areaData:gsub(",", "<br/>") | ||
end | end | ||
| 第547行: | 第372行: | ||
local processedDesc = frame:preprocess(desc) | local processedDesc = frame:preprocess(desc) | ||
-- | -- 获取类型图标(根据类型和稀有度) | ||
local | local typeIcon = string.format('[[File:icon_equip_%s_%s.png|40px|link=]]', | ||
itemType, rarity) | itemType, rarity) | ||
-- | -- 获取稀有度颜色 | ||
local rarityColorValue = rarityColor[rarity] or "#ffffff" | local rarityColorValue = rarityColor[rarity] or "#ffffff" | ||
| 第559行: | 第383行: | ||
local sortType = typeOrder[itemType] or 999 | local sortType = typeOrder[itemType] or 999 | ||
-- | -- 创建表格行,每个 td 都设置与 th 相同的宽度 | ||
local row = string.format( | local row = string.format( | ||
'<tr class="divsort" data-param1="%s" data-param2="%s" data-param3="%s" data-param4="%s" data-sortrarity="%d" data-sorttype="%d">' .. | '<tr class="divsort" data-param1="%s" data-param2="%s" data-param3="%s" data-param4="%s" data-sortrarity="%d" data-sorttype="%d">' .. | ||
'<td style="text-align:center;" | '<td style="width:100px; text-align:center;">[[File:%s|80px|link=%s]]</td>' .. | ||
'<td>[[%s|<span style="color:%s; font-weight:bold;">%s</span>]]</td>' .. | '<td style="width:200px; text-align:center;">[[%s|<span style="color:%s; font-weight:bold;">%s</span>]]</td>' .. | ||
'<td style="text-align:center;">%s</td>' .. | '<td style="width:30px; text-align:center;">%s</td>' .. | ||
'<td>%s</td>' .. | '<td style="width:150px; text-align:center;">%s</td>' .. | ||
'<td style="text-align:left; padding:10px;">%s</td>' .. | '<td style="text-align:left; padding:10px;">%s</td>' .. | ||
'</tr>', | '</tr>', | ||
| 第574行: | 第398行: | ||
sortRarity, | sortRarity, | ||
sortType, | sortType, | ||
artFile, | artFile, | ||
equipName, | equipName, | ||
| 第580行: | 第403行: | ||
rarityColorValue, | rarityColorValue, | ||
equipName, | equipName, | ||
typeIcon, | |||
areaDisplay, | areaDisplay, | ||
processedDesc | processedDesc | ||
| 第589行: | 第412行: | ||
return table.concat(html, '\n') | return table.concat(html, '\n') | ||
end | |||
-- 装备卡片筛选 | |||
function p.generateCards(frame) | |||
local html = mw.html.create() | |||
-- 创建排序数组 | |||
local equipList = {} | |||
for equipName, equipData in pairs(data) do | |||
-- 获取地区数据并规范化 | |||
local area = equipData.area or "" | |||
area = normalizeCommas(area) | |||
-- 只添加地区不是 undefined 的装备 | |||
if area ~= "undefined" and area ~= "Undefined" and area ~= "UNDEFINED" then | |||
table.insert(equipList, { | |||
name = equipName, | |||
data = equipData, | |||
rarityOrder = rarityOrder[equipData.rarity] or 999, | |||
typeOrder = typeOrder[equipData.type] or 999 | |||
}) | |||
end | |||
end | |||
-- 按照稀有度、类型排序 | |||
table.sort(equipList, function(a, b) | |||
-- 先按稀有度排序(升序) | |||
if a.rarityOrder ~= b.rarityOrder then | |||
return a.rarityOrder < b.rarityOrder | |||
end | |||
-- 再按类型排序(升序) | |||
if a.typeOrder ~= b.typeOrder then | |||
return a.typeOrder < b.typeOrder | |||
end | |||
-- 最后按名称排序 | |||
return a.name < b.name | |||
end) | |||
-- 遍历排序后的装备列表 | |||
for _, item in ipairs(equipList) do | |||
local equipName = item.name | |||
local equipData = item.data | |||
-- 直接使用art字段作为图片文件名 | |||
local artFile = equipData.art or "relic_0000.png" | |||
-- 处理地区数据,将中文逗号转换为英文逗号 | |||
local areaData = normalizeCommas(equipData.area or "") | |||
-- 处理TAG数据,将中文逗号转换为英文逗号 | |||
local tagData = normalizeCommas(equipData.tag or "") | |||
-- 创建可筛选的卡片容器 | |||
local cardWrapper = html:tag('div') | |||
:addClass('divsort equipment-wrapper') | |||
:attr('data-param1', equipData.rarity) | |||
:attr('data-param2', areaData) | |||
:attr('data-param3', equipData.type) | |||
:attr('data-param4', tagData) | |||
:attr('data-sortrarity', rarityOrder[equipData.rarity] or 999) | |||
:attr('data-sorttype', typeOrder[equipData.type] or 999) | |||
:cssText('display: inline-block; margin: 5px; position: relative;') | |||
-- 创建卡片和名称的容器 | |||
local cardContainer = cardWrapper:tag('div') | |||
:cssText('display: flex; flex-direction: column; align-items: center;') | |||
-- 生成卡片内容 | |||
local cardDiv = cardContainer:tag('div') | |||
:addClass('equipment-card') | |||
:attr('data-equipment', equipName) | |||
:attr('data-level', '5') | |||
:cssText('position: relative; display: inline-block; width:150px; height: 230px; cursor: pointer;') | |||
-- 背景 | |||
cardDiv:tag('div') | |||
:cssText('position: absolute; top: 0px; left: 0px;') | |||
:wikitext(string.format('[[File:bg_equipment_rarity_%s.png|150px|link=]]', equipData.rarity)) | |||
-- 装备图片 | |||
cardDiv:tag('div') | |||
:cssText('position: absolute; top: 43px; left: 13px;') | |||
:wikitext(string.format('[[File:%s|124px|link=]]', artFile)) | |||
-- 底部背景 | |||
cardDiv:tag('div') | |||
:cssText('position: absolute; bottom: 5px; left: 5px; width: 140px; height: 35px; background-color: rgba(0,0,0,0.5); border-radius: 0px 0px 8px 8px') | |||
-- 星级 | |||
cardDiv:tag('div') | |||
:cssText('position: absolute; bottom: 10px; left: 20px;') | |||
:wikitext('[[File:icon_star_rating_5.png|link=]]') | |||
-- 顶层蒙版 | |||
cardDiv:tag('div') | |||
:cssText('position: absolute; top: 0px; left: 0px;') | |||
:wikitext('[[File:equipment_顶层蒙版.png|150px|link=]]') | |||
-- 装备名称 | |||
local nameDiv = cardContainer:tag('div') | |||
:addClass('equipment-name-link') | |||
:cssText('text-align: center; width: 150px;') | |||
-- 根据稀有度设置名称颜色 | |||
local nameColor = '#34638c' -- 蓝色 | |||
if equipData.rarity == '金' then | |||
nameColor = '#ff9500' -- 金色 | |||
elseif equipData.rarity == '彩' then | |||
nameColor = '#a072d6' -- 紫色 | |||
end | |||
-- 统一使用普通颜色样式 | |||
nameDiv:wikitext(string.format('[[%s|<span style="color:%s; font-size:14px; font-weight:bold;">%s</span>]]', | |||
equipName, nameColor, equipName)) | |||
-- 生成对应的弹窗 | |||
local popupDiv = cardWrapper:tag('div') | |||
:addClass('equipment-popup') | |||
:attr('id', 'equipment-popup-' .. mw.uri.encode(equipName)) | |||
:cssText('position: fixed; display: none; width:368px; height: 335px; background-color: #343434; border-radius: 9px; z-index: 10000;') | |||
-- 弹窗背景 | |||
popupDiv:tag('div') | |||
:cssText('position: absolute; top: 0px; left: 0px;') | |||
:wikitext(string.format('[[File:bg_collection_rarity_%s.png|link=]]', equipData.rarity)) | |||
-- 弹窗装备图片 | |||
popupDiv:tag('div') | |||
:cssText('position: absolute; top: 40px; left: 128px;') | |||
:wikitext(string.format('[[File:%s|124px|link=]]', artFile)) | |||
-- 星级背景 | |||
popupDiv:tag('div') | |||
:cssText('position: absolute; top: 167px; left: 0px; width: 368px; height: 35px; background-color: rgba(0,0,0,0.5); border-radius: 0px 0px 10px 10px ') | |||
-- 星级 | |||
popupDiv:tag('div') | |||
:cssText('position: absolute; top: 173px; left: 128px;') | |||
:wikitext('[[File:icon_star_rating_5.png|link=]]') | |||
-- 类型图标 | |||
popupDiv:tag('div') | |||
:cssText('position: absolute; top: 205px; left: 5px; color: white') | |||
:wikitext(string.format('[[File:icon_equip_%s_%s.png|25px|link=]]', equipData.type, equipData.rarity)) | |||
-- 装备名称 | |||
popupDiv:tag('div') | |||
:cssText('position: absolute; top: 208px; left: 33px; color: white') | |||
:wikitext(equipName) | |||
-- 属性背景 | |||
popupDiv:tag('div') | |||
:cssText('position: absolute; top: 235px; left: 9px; width: 350px; height: 35px; background-color: rgba(255,255,255,0.3); border-radius: 2px') | |||
-- 属性类型 | |||
local valueType = getValueType(equipData.type) | |||
popupDiv:tag('div') | |||
:cssText('position: absolute; top: 242px; left: 14px; color: white') | |||
:wikitext(valueType) | |||
-- 属性值 | |||
local value = calculateValue(equipData.rarity, equipData.type, "5") | |||
popupDiv:tag('div') | |||
:cssText('position: absolute; top: 242px; right: 14px; color: white') | |||
:wikitext(value) | |||
-- 描述(所有星级描述相同) | |||
local desc = equipData.desc or "" | |||
local processedDesc = frame:preprocess(desc) | |||
popupDiv:tag('div') | |||
:cssText('position: absolute; top: 277px; left: 10px; right: 10px; color: white; font-size: 14px;') | |||
:wikitext(processedDesc) | |||
-- 关闭按钮 | |||
popupDiv:tag('div') | |||
:addClass('equipment-popup-close') | |||
:cssText('position: absolute; top: 10px; right: 10px; width: 24px; height: 24px; cursor: pointer; color: white; font-size: 20px;') | |||
:wikitext('×') | |||
end | |||
return tostring(html) | |||
end | |||
-- 内联弹窗(用于模板调用) | |||
function p.inlinePopup(frame) | |||
local args = frame.args | |||
local name = args[1] or args.name | |||
local level = args[2] or args.level or "5" | |||
if not name or not data[name] then | |||
return "" | |||
end | |||
local equipData = data[name] | |||
-- 直接使用art字段作为图片文件名 | |||
local artFile = equipData.art or "relic_0000.png" | |||
-- 创建隐藏的弹窗容器 | |||
local html = mw.html.create('div') | |||
:addClass('equipment-popup') | |||
:cssText('position: fixed; display: none; width:368px; height: 335px; background-color: #343434; border-radius: 9px; z-index: 10001; left: 50%; top: 50%; transform: translate(-50%, -50%);') | |||
-- 弹窗背景 | |||
html:tag('div') | |||
:cssText('position: absolute; top: 0px; left: 0px;') | |||
:wikitext(string.format('[[File:bg_collection_rarity_%s.png|link=]]', equipData.rarity)) | |||
-- 弹窗装备图片 | |||
html:tag('div') | |||
:cssText('position: absolute; top: 40px; left: 128px;') | |||
:wikitext(string.format('[[File:%s|124px|link=]]', artFile)) | |||
-- 星级背景 | |||
html:tag('div') | |||
:cssText('position: absolute; top: 167px; left: 0px; width: 368px; height: 35px; background-color: rgba(0,0,0,0.5); border-radius: 0px 0px 10px 10px ') | |||
-- 星级 | |||
html:tag('div') | |||
:cssText('position: absolute; top: 173px; left: 128px;') | |||
:wikitext(string.format('[[File:icon_star_rating_%s.png|link=]]', level)) | |||
-- 类型图标 | |||
html:tag('div') | |||
:cssText('position: absolute; top: 205px; left: 5px; color: white') | |||
:wikitext(string.format('[[File:icon_equip_%s_%s.png|25px|link=]]', equipData.type, equipData.rarity)) | |||
-- 装备名称 | |||
html:tag('div') | |||
:cssText('position: absolute; top: 208px; left: 33px; color: white') | |||
:wikitext(name) | |||
-- 属性背景 | |||
html:tag('div') | |||
:cssText('position: absolute; top: 235px; left: 9px; width: 350px; height: 35px; background-color: rgba(255,255,255,0.3); border-radius: 2px') | |||
-- 属性类型 | |||
local valueType = getValueType(equipData.type) | |||
html:tag('div') | |||
:cssText('position: absolute; top: 242px; left: 14px; color: white') | |||
:wikitext(valueType) | |||
-- 属性值 | |||
local value = calculateValue(equipData.rarity, equipData.type, level) | |||
html:tag('div') | |||
:cssText('position: absolute; top: 242px; right: 14px; color: white') | |||
:wikitext(value) | |||
-- 描述 | |||
local desc = equipData.desc or "" | |||
local processedDesc = frame:preprocess(desc) | |||
html:tag('div') | |||
:cssText('position: absolute; top: 277px; left: 10px; right: 10px; color: white; font-size: 14px;') | |||
:wikitext(processedDesc) | |||
-- 关闭按钮 | |||
html:tag('div') | |||
:addClass('equipment-popup-close') | |||
:cssText('position: absolute; top: 10px; right: 10px; width: 24px; height: 24px; cursor: pointer; color: white; font-size: 20px; text-align: center; line-height: 24px;') | |||
:wikitext('×') | |||
return tostring(html) | |||
end | end | ||
return p | return p | ||
2025年11月11日 (二) 21:04的最新版本
此模块的文档可以在模块:装备/doc创建
local p = {}
local data = mw.loadData('模块:装备/data/S1')
-- 获取装备稀有度
local rarityMap = {
["蓝"] = "蓝",
["金"] = "金",
["彩"] = "彩"
}
-- 稀有度排序权重
local rarityOrder = {
["彩"] = 1,
["金"] = 2,
["蓝"] = 3
}
-- 类型排序权重
local typeOrder = {
["武器"] = 1,
["装甲"] = 2,
["戒指"] = 3
}
-- 辅助函数:记录数值
local function calculateValue(rarity, itemType, level)
local BASE_VALUES = {
["蓝"] = {
["武器"] = { values = {25, 41, 56, 67, 74} },
["装甲"] = { values = {9, 15, 21, 24, 28} },
["戒指"] = { values = {20, 37, 54, 66, 75} },
},
["金"] = {
["武器"] = { values = {28, 45, 62, 74, 82} },
["装甲"] = { values = {10, 17, 23, 27, 31} },
["戒指"] = { values = {22, 41, 60, 73, 83} },
},
["彩"] = {
["武器"] = { values = {31, 50, 68, 81, 90} },
["装甲"] = { values = {11, 19, 25, 30, 34} },
["戒指"] = { values = {24, 45, 66, 80, 91} },
},
}
local levelNum = tonumber(level) or 1
if BASE_VALUES[rarity] and BASE_VALUES[rarity][itemType] then
return BASE_VALUES[rarity][itemType].values[levelNum]
end
return 0
end
-- 辅助函数:获取属性类型
local function getValueType(itemType)
local typeMap = {
["武器"] = "攻击力",
["装甲"] = "防御力",
["戒指"] = "HP"
}
return typeMap[itemType] or ""
end
-- 辅助函数:将中文逗号转换为英文逗号
local function normalizeCommas(str)
if not str or str == "" then
return ""
end
-- 将中文逗号(,)替换为英文逗号(,)
return str:gsub(",", ",")
end
-- 单个装备卡片
function p.card(frame)
local args = frame.args
local name = args[1] or args.name
local level = args[2] or args.level or "1"
if not name or not data[name] then
return "装备不存在: " .. (name or "未指定")
end
local equip = data[name]
-- 直接使用art字段作为图片文件名
local artFile = equip.art or "relic_0000.png"
-- 生成HTML
local html = mw.html.create('div')
:addClass('equipment-card')
:attr('data-equipment', name)
:attr('data-level', level)
:cssText('position: relative; display: inline-block; width:150px; height: 230px; cursor: pointer;')
-- 背景
html:tag('div')
:cssText('position: absolute; top: 0px; left: 0px;')
:wikitext(string.format('[[File:bg_equipment_rarity_%s.png|150px|link=]]', equip.rarity))
-- 装备图片
html:tag('div')
:cssText('position: absolute; top: 43px; left: 13px;')
:wikitext(string.format('[[File:%s|124px|link=]]', artFile))
-- 底部背景
html:tag('div')
:cssText('position: absolute; bottom: 5px; left: 5px; width: 140px; height: 35px; background-color: rgba(0,0,0,0.5); border-radius: 0px 0px 8px 8px')
-- 星级
html:tag('div')
:cssText('position: absolute; bottom: 10px; left: 20px;')
:wikitext(string.format('[[File:icon_star_rating_%s.png|link=]]', level))
-- 顶层蒙版
html:tag('div')
:cssText('position: absolute; top: 0px; left: 0px;')
:wikitext('[[File:equipment_顶层蒙版.png|150px|link=]]')
return tostring(html)
end
-- 显示弹窗内容
function p.displaypopup(frame)
local args = frame.args
local name = args[1] or args.name
local level = args[2] or args.level or "5"
if not name or not data[name] then
return "装备不存在: " .. (name or "未指定")
end
local equipData = data[name]
-- 直接使用art字段作为图片文件名
local artFile = equipData.art or "relic_0000.png"
-- 创建弹窗容器
local html = mw.html.create('div')
:cssText('position: relative; width:368px; height: 335px; background-color: #343434; border-radius: 9px;')
-- 弹窗背景
html:tag('div')
:cssText('position: absolute; top: 0px; left: 0px;')
:wikitext(string.format('[[File:bg_collection_rarity_%s.png|link=]]', equipData.rarity))
-- 弹窗装备图片
html:tag('div')
:cssText('position: absolute; top: 40px; left: 128px;')
:wikitext(string.format('[[File:%s|124px|link=]]', artFile))
-- 星级背景
html:tag('div')
:cssText('position: absolute; top: 167px; left: 0px; width: 368px; height: 35px; background-color: rgba(0,0,0,0.5); border-radius: 0px 0px 10px 10px ')
-- 星级
html:tag('div')
:cssText('position: absolute; top: 173px; left: 128px;')
:wikitext(string.format('[[File:icon_star_rating_%s.png|link=]]', level))
-- 类型图标
html:tag('div')
:cssText('position: absolute; top: 205px; left: 5px; color: white')
:wikitext(string.format('[[File:icon_equip_%s_%s.png|25px|link=]]', equipData.type, equipData.rarity))
-- 装备名称
html:tag('div')
:cssText('position: absolute; top: 208px; left: 33px; color: white')
:wikitext(name)
-- 属性背景
html:tag('div')
:cssText('position: absolute; top: 235px; left: 9px; width: 350px; height: 35px; background-color: rgba(255,255,255,0.3); border-radius: 2px')
-- 属性类型
local valueType = getValueType(equipData.type)
html:tag('div')
:cssText('position: absolute; top: 242px; left: 14px; color: white')
:wikitext(valueType)
-- 属性值
local value = calculateValue(equipData.rarity, equipData.type, level)
html:tag('div')
:cssText('position: absolute; top: 242px; right: 14px; color: white')
:wikitext(value)
-- 描述(所有星级描述相同)
local desc = equipData.desc or ""
local processedDesc = frame:preprocess(desc)
html:tag('div')
:cssText('position: absolute; top: 277px; left: 10px; right: 10px; color: white; font-size: 14px;')
:wikitext(processedDesc)
return tostring(html)
end
-- 筛选表格
function p.generateTableRows(frame)
local html = {}
-- 创建排序数组
local equipList = {}
for equipName, equipData in pairs(data) do
table.insert(equipList, {
name = equipName,
data = equipData,
rarityOrder = rarityOrder[equipData.rarity] or 999,
typeOrder = typeOrder[equipData.type] or 999
})
end
-- 按照稀有度、类型排序
table.sort(equipList, function(a, b)
if a.rarityOrder ~= b.rarityOrder then
return a.rarityOrder < b.rarityOrder
end
if a.typeOrder ~= b.typeOrder then
return a.typeOrder < b.typeOrder
end
return a.name < b.name
end)
-- 遍历排序后的装备列表生成表格行
for _, item in ipairs(equipList) do
local equipName = item.name
local equipData = item.data
-- 使用art字段作为图片文件名
local artFile = equipData.art or "relic_0000.png"
-- 处理地区数据,将中文逗号转换为英文逗号
local areaData = normalizeCommas(equipData.area or "")
local areaDisplay = areaData
-- 如果地区为空或"0",显示为"全地区"
if areaData == "" or areaData == "0" then
areaDisplay = "全地区"
else
areaDisplay = areaData:gsub(",", "<br/>")
end
-- 处理TAG数据
local tagData = normalizeCommas(equipData.tag or "")
local tagDisplay = tagData
if tagData == "" or tagData == "0" then
tagDisplay = ""
else
tagDisplay = tagData:gsub(",", "<br/>")
end
-- 稀有度文本映射
local rarityText = {
["蓝"] = "普通",
["金"] = "稀有",
["彩"] = "传奇"
}
-- 稀有度颜色
local rarityColor = {
["蓝"] = "#34638c",
["金"] = "#ff9500",
["彩"] = "#a072d6"
}
-- 获取属性类型和数值
local valueType = getValueType(equipData.type)
local value = calculateValue(equipData.rarity, equipData.type, "5")
local valueDisplay = string.format("%s %d", valueType, value)
-- 获取描述
local desc = equipData.desc or ""
local processedDesc = frame:preprocess(desc)
-- 创建表格行
local row = string.format(
'<tr class="divsort" data-param1="%s" data-param2="%s" data-param3="%s" data-param4="%s" data-sortrarity="%s" data-sorttype="%s">' ..
'<td style="text-align:left;">[[File:%s|50px|link=%s]] [[%s|<span style="color:%s;">%s</span>]]</td>' ..
'<td><span style="color:%s;">%s</span></td>' ..
'<td>%s</td>' ..
'<td>%s</td>' ..
'<td>%s</td>' ..
'<td>%s</td>' ..
'<td style="text-align:left;">%s</td>' ..
'</tr>',
equipData.rarity,
areaData,
equipData.type,
tagData,
rarityOrder[equipData.rarity] or 999,
typeOrder[equipData.type] or 999,
artFile, equipName, equipName, rarityColor[equipData.rarity], equipName,
rarityColor[equipData.rarity], rarityText[equipData.rarity] or equipData.rarity,
equipData.type,
valueDisplay,
areaDisplay,
tagDisplay,
processedDesc
)
table.insert(html, row)
end
return table.concat(html, '\n')
end
-- 生成带筛选功能的完整表格
function p.generateFilterTable(frame)
local html = {}
-- 创建排序数组,过滤掉地区为 undefined 的装备
local equipList = {}
for equipName, equipData in pairs(data) do
local area = equipData.area or ""
-- 跳过地区为 undefined 的装备
if area ~= "undefined" and area ~= "Undefined" and area ~= "UNDEFINED" then
table.insert(equipList, {
name = equipName,
data = equipData,
rarityOrder = rarityOrder[equipData.rarity] or 999,
typeOrder = typeOrder[equipData.type] or 999
})
end
end
-- 按照稀有度、类型排序
table.sort(equipList, function(a, b)
if a.rarityOrder ~= b.rarityOrder then
return a.rarityOrder < b.rarityOrder
end
if a.typeOrder ~= b.typeOrder then
return a.typeOrder < b.typeOrder
end
return a.name < b.name
end)
-- 稀有度颜色映射
local rarityColor = {
["蓝"] = "#34638c",
["金"] = "#ff9500",
["彩"] = "#a072d6"
}
-- 遍历排序后的装备列表生成表格行
for _, item in ipairs(equipList) do
local equipName = item.name
local equipData = item.data
-- 确保所有必需字段都有默认值
local rarity = equipData.rarity or "蓝"
local itemType = equipData.type or "武器"
-- 使用art字段作为图片文件名
local artFile = equipData.art or "relic_0000.png"
-- 处理地区数据
local areaData = normalizeCommas(equipData.area or "")
local areaDisplay = ""
if areaData == "" or areaData == "0" then
areaDisplay = "全地区"
areaData = "" -- 确保筛选数据为空字符串
else
-- 将逗号分隔的地区转换为换行显示
areaDisplay = areaData:gsub(",", "<br/>")
end
-- 处理TAG数据
local tagData = normalizeCommas(equipData.tag or "")
if tagData == "0" then
tagData = ""
end
-- 获取描述
local desc = equipData.desc or ""
local processedDesc = frame:preprocess(desc)
-- 获取类型图标(根据类型和稀有度)
local typeIcon = string.format('[[File:icon_equip_%s_%s.png|40px|link=]]',
itemType, rarity)
-- 获取稀有度颜色
local rarityColorValue = rarityColor[rarity] or "#ffffff"
-- 获取排序值
local sortRarity = rarityOrder[rarity] or 999
local sortType = typeOrder[itemType] or 999
-- 创建表格行,每个 td 都设置与 th 相同的宽度
local row = string.format(
'<tr class="divsort" data-param1="%s" data-param2="%s" data-param3="%s" data-param4="%s" data-sortrarity="%d" data-sorttype="%d">' ..
'<td style="width:100px; text-align:center;">[[File:%s|80px|link=%s]]</td>' ..
'<td style="width:200px; text-align:center;">[[%s|<span style="color:%s; font-weight:bold;">%s</span>]]</td>' ..
'<td style="width:30px; text-align:center;">%s</td>' ..
'<td style="width:150px; text-align:center;">%s</td>' ..
'<td style="text-align:left; padding:10px;">%s</td>' ..
'</tr>',
rarity,
areaData,
itemType,
tagData,
sortRarity,
sortType,
artFile,
equipName,
equipName,
rarityColorValue,
equipName,
typeIcon,
areaDisplay,
processedDesc
)
table.insert(html, row)
end
return table.concat(html, '\n')
end
-- 装备卡片筛选
function p.generateCards(frame)
local html = mw.html.create()
-- 创建排序数组
local equipList = {}
for equipName, equipData in pairs(data) do
-- 获取地区数据并规范化
local area = equipData.area or ""
area = normalizeCommas(area)
-- 只添加地区不是 undefined 的装备
if area ~= "undefined" and area ~= "Undefined" and area ~= "UNDEFINED" then
table.insert(equipList, {
name = equipName,
data = equipData,
rarityOrder = rarityOrder[equipData.rarity] or 999,
typeOrder = typeOrder[equipData.type] or 999
})
end
end
-- 按照稀有度、类型排序
table.sort(equipList, function(a, b)
-- 先按稀有度排序(升序)
if a.rarityOrder ~= b.rarityOrder then
return a.rarityOrder < b.rarityOrder
end
-- 再按类型排序(升序)
if a.typeOrder ~= b.typeOrder then
return a.typeOrder < b.typeOrder
end
-- 最后按名称排序
return a.name < b.name
end)
-- 遍历排序后的装备列表
for _, item in ipairs(equipList) do
local equipName = item.name
local equipData = item.data
-- 直接使用art字段作为图片文件名
local artFile = equipData.art or "relic_0000.png"
-- 处理地区数据,将中文逗号转换为英文逗号
local areaData = normalizeCommas(equipData.area or "")
-- 处理TAG数据,将中文逗号转换为英文逗号
local tagData = normalizeCommas(equipData.tag or "")
-- 创建可筛选的卡片容器
local cardWrapper = html:tag('div')
:addClass('divsort equipment-wrapper')
:attr('data-param1', equipData.rarity)
:attr('data-param2', areaData)
:attr('data-param3', equipData.type)
:attr('data-param4', tagData)
:attr('data-sortrarity', rarityOrder[equipData.rarity] or 999)
:attr('data-sorttype', typeOrder[equipData.type] or 999)
:cssText('display: inline-block; margin: 5px; position: relative;')
-- 创建卡片和名称的容器
local cardContainer = cardWrapper:tag('div')
:cssText('display: flex; flex-direction: column; align-items: center;')
-- 生成卡片内容
local cardDiv = cardContainer:tag('div')
:addClass('equipment-card')
:attr('data-equipment', equipName)
:attr('data-level', '5')
:cssText('position: relative; display: inline-block; width:150px; height: 230px; cursor: pointer;')
-- 背景
cardDiv:tag('div')
:cssText('position: absolute; top: 0px; left: 0px;')
:wikitext(string.format('[[File:bg_equipment_rarity_%s.png|150px|link=]]', equipData.rarity))
-- 装备图片
cardDiv:tag('div')
:cssText('position: absolute; top: 43px; left: 13px;')
:wikitext(string.format('[[File:%s|124px|link=]]', artFile))
-- 底部背景
cardDiv:tag('div')
:cssText('position: absolute; bottom: 5px; left: 5px; width: 140px; height: 35px; background-color: rgba(0,0,0,0.5); border-radius: 0px 0px 8px 8px')
-- 星级
cardDiv:tag('div')
:cssText('position: absolute; bottom: 10px; left: 20px;')
:wikitext('[[File:icon_star_rating_5.png|link=]]')
-- 顶层蒙版
cardDiv:tag('div')
:cssText('position: absolute; top: 0px; left: 0px;')
:wikitext('[[File:equipment_顶层蒙版.png|150px|link=]]')
-- 装备名称
local nameDiv = cardContainer:tag('div')
:addClass('equipment-name-link')
:cssText('text-align: center; width: 150px;')
-- 根据稀有度设置名称颜色
local nameColor = '#34638c' -- 蓝色
if equipData.rarity == '金' then
nameColor = '#ff9500' -- 金色
elseif equipData.rarity == '彩' then
nameColor = '#a072d6' -- 紫色
end
-- 统一使用普通颜色样式
nameDiv:wikitext(string.format('[[%s|<span style="color:%s; font-size:14px; font-weight:bold;">%s</span>]]',
equipName, nameColor, equipName))
-- 生成对应的弹窗
local popupDiv = cardWrapper:tag('div')
:addClass('equipment-popup')
:attr('id', 'equipment-popup-' .. mw.uri.encode(equipName))
:cssText('position: fixed; display: none; width:368px; height: 335px; background-color: #343434; border-radius: 9px; z-index: 10000;')
-- 弹窗背景
popupDiv:tag('div')
:cssText('position: absolute; top: 0px; left: 0px;')
:wikitext(string.format('[[File:bg_collection_rarity_%s.png|link=]]', equipData.rarity))
-- 弹窗装备图片
popupDiv:tag('div')
:cssText('position: absolute; top: 40px; left: 128px;')
:wikitext(string.format('[[File:%s|124px|link=]]', artFile))
-- 星级背景
popupDiv:tag('div')
:cssText('position: absolute; top: 167px; left: 0px; width: 368px; height: 35px; background-color: rgba(0,0,0,0.5); border-radius: 0px 0px 10px 10px ')
-- 星级
popupDiv:tag('div')
:cssText('position: absolute; top: 173px; left: 128px;')
:wikitext('[[File:icon_star_rating_5.png|link=]]')
-- 类型图标
popupDiv:tag('div')
:cssText('position: absolute; top: 205px; left: 5px; color: white')
:wikitext(string.format('[[File:icon_equip_%s_%s.png|25px|link=]]', equipData.type, equipData.rarity))
-- 装备名称
popupDiv:tag('div')
:cssText('position: absolute; top: 208px; left: 33px; color: white')
:wikitext(equipName)
-- 属性背景
popupDiv:tag('div')
:cssText('position: absolute; top: 235px; left: 9px; width: 350px; height: 35px; background-color: rgba(255,255,255,0.3); border-radius: 2px')
-- 属性类型
local valueType = getValueType(equipData.type)
popupDiv:tag('div')
:cssText('position: absolute; top: 242px; left: 14px; color: white')
:wikitext(valueType)
-- 属性值
local value = calculateValue(equipData.rarity, equipData.type, "5")
popupDiv:tag('div')
:cssText('position: absolute; top: 242px; right: 14px; color: white')
:wikitext(value)
-- 描述(所有星级描述相同)
local desc = equipData.desc or ""
local processedDesc = frame:preprocess(desc)
popupDiv:tag('div')
:cssText('position: absolute; top: 277px; left: 10px; right: 10px; color: white; font-size: 14px;')
:wikitext(processedDesc)
-- 关闭按钮
popupDiv:tag('div')
:addClass('equipment-popup-close')
:cssText('position: absolute; top: 10px; right: 10px; width: 24px; height: 24px; cursor: pointer; color: white; font-size: 20px;')
:wikitext('×')
end
return tostring(html)
end
-- 内联弹窗(用于模板调用)
function p.inlinePopup(frame)
local args = frame.args
local name = args[1] or args.name
local level = args[2] or args.level or "5"
if not name or not data[name] then
return ""
end
local equipData = data[name]
-- 直接使用art字段作为图片文件名
local artFile = equipData.art or "relic_0000.png"
-- 创建隐藏的弹窗容器
local html = mw.html.create('div')
:addClass('equipment-popup')
:cssText('position: fixed; display: none; width:368px; height: 335px; background-color: #343434; border-radius: 9px; z-index: 10001; left: 50%; top: 50%; transform: translate(-50%, -50%);')
-- 弹窗背景
html:tag('div')
:cssText('position: absolute; top: 0px; left: 0px;')
:wikitext(string.format('[[File:bg_collection_rarity_%s.png|link=]]', equipData.rarity))
-- 弹窗装备图片
html:tag('div')
:cssText('position: absolute; top: 40px; left: 128px;')
:wikitext(string.format('[[File:%s|124px|link=]]', artFile))
-- 星级背景
html:tag('div')
:cssText('position: absolute; top: 167px; left: 0px; width: 368px; height: 35px; background-color: rgba(0,0,0,0.5); border-radius: 0px 0px 10px 10px ')
-- 星级
html:tag('div')
:cssText('position: absolute; top: 173px; left: 128px;')
:wikitext(string.format('[[File:icon_star_rating_%s.png|link=]]', level))
-- 类型图标
html:tag('div')
:cssText('position: absolute; top: 205px; left: 5px; color: white')
:wikitext(string.format('[[File:icon_equip_%s_%s.png|25px|link=]]', equipData.type, equipData.rarity))
-- 装备名称
html:tag('div')
:cssText('position: absolute; top: 208px; left: 33px; color: white')
:wikitext(name)
-- 属性背景
html:tag('div')
:cssText('position: absolute; top: 235px; left: 9px; width: 350px; height: 35px; background-color: rgba(255,255,255,0.3); border-radius: 2px')
-- 属性类型
local valueType = getValueType(equipData.type)
html:tag('div')
:cssText('position: absolute; top: 242px; left: 14px; color: white')
:wikitext(valueType)
-- 属性值
local value = calculateValue(equipData.rarity, equipData.type, level)
html:tag('div')
:cssText('position: absolute; top: 242px; right: 14px; color: white')
:wikitext(value)
-- 描述
local desc = equipData.desc or ""
local processedDesc = frame:preprocess(desc)
html:tag('div')
:cssText('position: absolute; top: 277px; left: 10px; right: 10px; color: white; font-size: 14px;')
:wikitext(processedDesc)
-- 关闭按钮
html:tag('div')
:addClass('equipment-popup-close')
:cssText('position: absolute; top: 10px; right: 10px; width: 24px; height: 24px; cursor: pointer; color: white; font-size: 20px; text-align: center; line-height: 24px;')
:wikitext('×')
return tostring(html)
end
return p