卡牌:修订间差异
来自卡厄思梦境WIKI
无编辑摘要 标签:已被回退 |
标签:撤销 |
||
| 第1行: | 第1行: | ||
local p = {} | local p = {} | ||
-- | -- 颜色映射表 | ||
local COLOR_MAP = { | local COLOR_MAP = { | ||
["白"] = { bgColor = "rgba(249, 249, 249, 0.5)", textColor = "white" }, | ["白"] = { bgColor = "rgba(249, 249, 249, 0.5)", textColor = "white" }, | ||
| 第8行: | 第8行: | ||
["彩"] = { bgColor = "rgba(201, 88, 241, 0.5)", textColor = "#eba2fc" } | ["彩"] = { bgColor = "rgba(201, 88, 241, 0.5)", textColor = "#eba2fc" } | ||
} | } | ||
-- | -- 安全获取数据字段 | ||
local function safeGet(data, field, default) | local function safeGet(data, field, default) | ||
return data and data[field] or default | |||
end | end | ||
-- | -- 处理描述文本中的模板 | ||
local function processDescription(frame, description) | local function processDescription(frame, description) | ||
if not description or description == "" then | if not description or description == "" then | ||
return | return description | ||
end | end | ||
| 第32行: | 第24行: | ||
end) | end) | ||
return success and result or description | |||
end | end | ||
-- | -- 生成卡牌HTML样式组件 | ||
local function | local function buildStyleComponents(cardData, cardName, baseCardData) | ||
local color = safeGet(cardData, "稀有度", "白") | local color = safeGet(cardData, "稀有度", "白") | ||
local colorStyle = COLOR_MAP[color] or | local colorStyle = COLOR_MAP[color] or COLOR_MAP["白"] | ||
local attribute = safeGet(cardData, "属性", "虚无") | |||
local cardDeck = safeGet(cardData, "卡组", "起始卡牌") | |||
local ap = safeGet(cardData, "AP", "") | local ap = safeGet(cardData, "AP", "") | ||
local originalAP = baseCardData and safeGet(baseCardData, "AP", ap) or ap | local originalAP = baseCardData and safeGet(baseCardData, "AP", ap) or ap | ||
-- | -- 决定AP的发光颜色 | ||
local apGlowColor = "#4a90e2" | local apGlowColor = "#4a90e2" -- 默认蓝色 | ||
if baseCardData and ap ~= originalAP | if baseCardData and ap ~= originalAP then | ||
if ap == "X" then | |||
apGlowColor = "#4a90e2" -- X值保持默认蓝色 | |||
elseif tonumber(ap) and tonumber(originalAP) then | |||
if tonumber(ap) < tonumber(originalAP) then | |||
apGlowColor = "#51f651" -- 绿色(AP降低) | |||
else | |||
apGlowColor = "#f65151" -- 红色(AP增加) | |||
end | |||
end | end | ||
end | end | ||
-- | -- 检查原卡牌与当前卡牌的机制变化 | ||
local mechanism = safeGet(cardData, "机制", "") | local mechanism = safeGet(cardData, "机制", "") | ||
local originalMechanism = baseCardData and safeGet(baseCardData, "机制", "") or mechanism | local originalMechanism = baseCardData and safeGet(baseCardData, "机制", "") or mechanism | ||
originalMechanism = originalMechanism == " | -- 将"无"视为空字符串 | ||
if mechanism == "无" then mechanism = "" end | |||
if originalMechanism == "无" then originalMechanism = "" end | |||
local mechanismChanged = baseCardData and mechanism ~= "" and originalMechanism == "" | |||
return { | return { | ||
color = color, | color = color, | ||
colorStyle = colorStyle, | colorStyle = colorStyle, | ||
attribute = | attribute = attribute, | ||
ap = ap, | |||
apGlowColor = apGlowColor, | |||
cardType = safeGet(cardData, "类型", ""), | cardType = safeGet(cardData, "类型", ""), | ||
art = safeGet(cardData, "art", ""), | art = safeGet(cardData, "art", ""), | ||
mechanism = mechanism, | mechanism = mechanism, | ||
mechanismChanged = | mechanismChanged = mechanismChanged | ||
} | } | ||
end | end | ||
-- | -- 构建卡牌HTML | ||
local function buildCardHTML(frame, cardName, cardData, baseCardData, characterName) | local function buildCardHTML(frame, cardName, cardData, baseCardData, characterName) | ||
if not cardData then | if not cardData then | ||
return format( | return string.format("找不到卡牌数据: %s", cardName or "未指定") | ||
end | end | ||
local style = | local style = buildStyleComponents(cardData, cardName, baseCardData) | ||
local description = processDescription(frame, safeGet(cardData, "描述", "")) | local description = processDescription(frame, safeGet(cardData, "描述", "")) | ||
-- | -- 获取衍生卡牌信息 | ||
local | local derivedCards = safeGet(cardData, "衍生卡牌", "") | ||
local deckType = safeGet(cardData, "卡组", "") | |||
-- | -- 生成数据属性 | ||
local dataAttrs = string.format('data-card-name="%s" data-character="%s" data-deck-type="%s" data-derived-cards="%s"', | |||
cardName or "", characterName or "", deckType or "", derivedCards or "") | |||
-- 处理机制文本(修改:当机制为"无"时不显示) | |||
local mechanismHTML = "" | local mechanismHTML = "" | ||
if style.mechanism ~= "" then | if style.mechanism and style.mechanism ~= "" and style.mechanism ~= "无" then | ||
local mechanismColor = style.mechanismChanged and "#b5f651" or "#f6c478" | local mechanismColor = style.mechanismChanged and "#b5f651" or "#f6c478" | ||
mechanismHTML = format( | mechanismHTML = string.format('<div style="color: %s; margin-bottom: 4px;">[%s]</div>', | ||
mechanismColor, style.mechanism:gsub("、", "/")) | |||
mechanismColor, | |||
end | end | ||
-- | -- 使用字符串拼接优化HTML生成 | ||
local | local htmlParts = { | ||
string.format('<div class="game-card" %s style="display: inline-block; vertical-align: top; position: relative; width: 168px; height: 230px; overflow: hidden; margin: 0px; cursor: pointer;">', dataAttrs), | |||
} | |||
-- | -- 根据类型判断使用哪种布局 | ||
if style.cardType == "状态异常" then | if style.cardType == "状态异常" then | ||
-- | -- 状态异常卡牌的特殊布局 | ||
insert( | table.insert(htmlParts, string.format('<div style="position: absolute; top: 5px; left: 5px;">[[File:%s|150px|link=]]</div>', style.art)) | ||
<div style="position: absolute; top: 5px; left: 5px;">%s</div> | table.insert(htmlParts, string.format('<div style="position: absolute; top: 0px; left: 0px;">[[File:card_状态异常_%s.png|159px|link=]]</div>', style.attribute)) | ||
<div style="position: absolute; top: 0px; left: 0px;">%s</div> | |||
<div style="position: absolute; left: 24px; top: 4px; color: white; font-weight: bold; text-shadow: %s; font-size: 32px;">%s</div> | -- AP值 | ||
<div style="position: absolute; left: 25px; top: 34px; color: white; font-weight: bold; text-shadow: %s;">—</div> | table.insert(htmlParts, string.format('<div style="position: absolute; left: 24px; top: 4px; color: white; font-weight: bold; text-shadow: 0 0 10px %s,0 0 20px %s, 0 0 30px %s, 0 0 40px %s; font-size: 32px;">%s</div>', | ||
<div style="position: absolute; left: 50px; top: 13px; color: %s; font-size:16px">%s</div> | style.apGlowColor, style.apGlowColor, style.apGlowColor, style.apGlowColor, style.ap)) | ||
<div style="position: absolute; left: 48px; top: 30px;">%s</div> | table.insert(htmlParts, string.format('<div style="position: absolute; left: 25px; top: 34px; color: white; font-weight: bold; text-shadow: 0 0 10px %s,0 0 20px %s, 0 0 30px %s, 0 0 40px %s;">—</div>', | ||
<div style="position: absolute; left: 68px; top: 33px; color: white; font-size:14px">%s</div> | style.apGlowColor, style.apGlowColor, style.apGlowColor, style.apGlowColor)) | ||
<div style="position: absolute; left: 0px; bottom: 0px;">[[File:card_顶层蒙版.png|168px|link=]]</div> | |||
-- 卡牌名称和类型 | |||
table.insert(htmlParts, string.format('<div style="position: absolute; left: 50px; top: 13px; color: %s; font-size:16px">%s</div>', | |||
style.colorStyle.textColor, cardName)) | |||
table.insert(htmlParts, string.format('<div style="position: absolute; left: 48px; top: 30px;">[[File:icon_card_%s.png|18px|link=]]</div>', | |||
style.cardType)) | |||
table.insert(htmlParts, string.format('<div style="position: absolute; left: 68px; top: 33px; color: white; font-size:14px">%s</div>', | |||
style.cardType)) | |||
-- 顶层蒙版 | |||
table.insert(htmlParts, '<div style="position: absolute; left: 0px; bottom: 0px;">[[File:card_顶层蒙版.png|168px|link=]]</div>') | |||
else | else | ||
-- | -- 普通卡牌的布局 | ||
insert( | -- 背景图片层 | ||
<div style="position: absolute; top: 1px; left: 12px;">%s</div> | table.insert(htmlParts, string.format('<div style="position: absolute; top: 1px; left: 12px;">[[File:%s|151px|link=]]</div>', style.art)) | ||
<div style="position: absolute; top: 1px; left: 12px;">[[File:card_黑色蒙版.png|151px|link=]]</div> | table.insert(htmlParts, '<div style="position: absolute; top: 1px; left: 12px;">[[File:card_黑色蒙版.png|151px|link=]]</div>') | ||
<div style="position: absolute; top: 21px; left: 10px; width: 148px; height: 8px; background-color: %s;"></div> | |||
<div style="position: absolute; left: 24px; top: 4px; color: white; font-weight: bold; text-shadow: %s; font-size: 32px;">%s</div> | -- 颜色条 | ||
<div style="position: absolute; left: 25px; top: 34px; color: white; font-weight: bold; text-shadow: %s;">—</div> | table.insert(htmlParts, string.format('<div style="position: absolute; top: 21px; left: 10px; width: 148px; height: 8px; background-color: %s;"></div>', | ||
<div style="position: absolute; left: 50px; top: 13px; color: %s; font-size:16px">%s</div> | style.colorStyle.bgColor)) | ||
<div style="position: absolute; left: 48px; top: 30px;">%s</div> | |||
<div style="position: absolute; left: 68px; top: 33px; color: white; font-size:14px">%s</div> | -- AP值 | ||
<div style="position: absolute; top: 0px; left: 1px;">%s</div> | table.insert(htmlParts, string.format('<div style="position: absolute; left: 24px; top: 4px; color: white; font-weight: bold; text-shadow: 0 0 10px %s,0 0 20px %s, 0 0 30px %s, 0 0 40px %s; font-size: 32px;">%s</div>', | ||
<div style="position: absolute; top: 10px; left: 0px;">%s</div> | style.apGlowColor, style.apGlowColor, style.apGlowColor, style.apGlowColor, style.ap)) | ||
<div style="position: absolute; top: 2px; right: 4px;">%s</div> | table.insert(htmlParts, string.format('<div style="position: absolute; left: 25px; top: 34px; color: white; font-weight: bold; text-shadow: 0 0 10px %s,0 0 20px %s, 0 0 30px %s, 0 0 40px %s;">—</div>', | ||
<div style="position: absolute; left: 0px; bottom: 0px;">[[File:card_顶层蒙版.png|168px|link=]]</div> | style.apGlowColor, style.apGlowColor, style.apGlowColor, style.apGlowColor)) | ||
-- 卡牌名称和类型 | |||
table.insert(htmlParts, string.format('<div style="position: absolute; left: 50px; top: 13px; color: %s; font-size:16px">%s</div>', | |||
style.colorStyle.textColor, cardName)) | |||
table.insert(htmlParts, string.format('<div style="position: absolute; left: 48px; top: 30px;">[[File:icon_card_%s.png|18px|link=]]</div>', | |||
style.cardType)) | |||
table.insert(htmlParts, string.format('<div style="position: absolute; left: 68px; top: 33px; color: white; font-size:14px">%s</div>', | |||
style.cardType)) | |||
-- 边框 | |||
table.insert(htmlParts, string.format('<div style="position: absolute; top: 0px; left: 1px;">[[File:card_属性边框_%s.png|160px|link=]]</div>', | |||
style.attribute)) | |||
-- 稀有度 | |||
table.insert(htmlParts, string.format('<div style="position: absolute; top: 10px; left: 0px;">[[File:card_稀有度_%s.png|22px|link=]]</div>', | |||
style.color)) | |||
table.insert(htmlParts, string.format('<div style="position: absolute; top: 2px; right: 4px;">[[File:card_稀有度_边框_%s.png|11px|link=]]</div>', | |||
style.color)) | |||
-- 顶层蒙版 | |||
table.insert(htmlParts, '<div style="position: absolute; left: 0px; bottom: 0px;">[[File:card_顶层蒙版.png|168px|link=]]</div>') | |||
end | end | ||
-- | -- 描述文本 | ||
insert( | table.insert(htmlParts, '<div style="position: absolute; bottom: 7px; left: 15px; width: 144px; height: 100px; font-size: 12px; color: white; line-height: 13px; display: flex; justify-content: center; align-items: center; text-align: center;">') | ||
<div style="position: absolute; bottom: 7px; left: 15px; width: 144px; height: 100px; font-size: 12px; color: white; line-height: 13px; display: flex; justify-content: center; align-items: center; text-align: center;"> | table.insert(htmlParts, '<div style="line-height: 13px;">') | ||
<div style="line-height: 13px;"> | table.insert(htmlParts, mechanismHTML) | ||
</div> | table.insert(htmlParts, description) | ||
</div> | table.insert(htmlParts, '</div>') | ||
table.insert(htmlParts, '</div>') | |||
table.insert(htmlParts, '</div>') | |||
return concat( | return table.concat(htmlParts) | ||
end | |||
-- 合并卡牌数据 | |||
local function mergeCardData(baseData, overrideData) | |||
local result = {} | |||
for k, v in pairs(baseData or {}) do | |||
result[k] = v | |||
end | |||
for k, v in pairs(overrideData or {}) do | |||
result[k] = v | |||
end | |||
return result | |||
end | end | ||
-- | -- 获取并显示所有默认卡牌 | ||
local function displayAllDefaultCards(frame, characterModule, characterName) | local function displayAllDefaultCards(frame, characterModule, characterName) | ||
local cards = characterModule.card or {} | local cards = characterModule.card or {} | ||
local cardOrder = characterModule.cardOrder or {} | local cardOrder = characterModule.cardOrder or {} | ||
local displayedCards = {} | |||
if # | -- 按cardOrder顺序遍历 | ||
for orderIndex, name in ipairs(cardOrder) do | |||
local cardArray = cards[name] | |||
if cardArray and #cardArray > 0 then | |||
-- 只显示第一张卡牌 | |||
table.insert(displayedCards, { | |||
name = name, | |||
data = cardArray[1], | |||
order = orderIndex | |||
}) | |||
end | |||
end | end | ||
-- 生成HTML | |||
local htmlParts = {} | local htmlParts = {} | ||
for | for i, cardInfo in ipairs(displayedCards) do | ||
table.insert(htmlParts, buildCardHTML(frame, cardInfo.name, cardInfo.data, nil, characterName)) | |||
end | end | ||
return concat(htmlParts) | return table.concat(htmlParts) | ||
end | end | ||
-- 处理特定卡牌请求 | |||
local function handleSpecificCard(frame, cardName, cardData, deckFilter, cardIndex, characterName) | local function handleSpecificCard(frame, cardName, cardData, deckFilter, cardIndex, characterName) | ||
local baseCard = cardData[1] | local baseCard = cardData[1] | ||
-- 如果没有指定卡组筛选,返回基础卡牌 | |||
if deckFilter == "" then | if deckFilter == "" then | ||
return buildCardHTML(frame, cardName, baseCard, nil, characterName) | return buildCardHTML(frame, cardName, baseCard, nil, characterName) | ||
end | end | ||
-- | -- 筛选指定卡组的卡牌 | ||
local filteredCards = {} | local filteredCards = {} | ||
for _, card in ipairs(cardData) do | for _, card in ipairs(cardData) do | ||
if card["卡组"] == deckFilter then | if card["卡组"] == deckFilter then | ||
insert(filteredCards, card) | table.insert(filteredCards, card) | ||
end | end | ||
end | end | ||
if #filteredCards == 0 then | if #filteredCards == 0 then | ||
return format( | return string.format("找不到卡组 '%s' 的卡牌: %s", deckFilter, cardName) | ||
end | end | ||
-- | -- 如果指定了索引,返回特定卡牌 | ||
if cardIndex > 0 and cardIndex <= #filteredCards then | if cardIndex > 0 and cardIndex <= #filteredCards then | ||
local mergedCard = mergeCardData(baseCard, filteredCards[cardIndex]) | |||
return buildCardHTML(frame, cardName, mergedCard, baseCard, characterName) | |||
end | end | ||
-- | -- 否则返回该卡组的所有卡牌 | ||
local htmlParts = {} | local htmlParts = {} | ||
for | for i, card in ipairs(filteredCards) do | ||
insert(htmlParts, buildCardHTML(frame, cardName, | local mergedCard = mergeCardData(baseCard, card) | ||
table.insert(htmlParts, buildCardHTML(frame, cardName, mergedCard, baseCard, characterName)) | |||
end | end | ||
return concat(htmlParts) | return table.concat(htmlParts) | ||
end | end | ||
| 第254行: | 第261行: | ||
local cardIndex = tonumber(args[4]) or 0 | local cardIndex = tonumber(args[4]) or 0 | ||
-- | -- 加载战斗员模块 | ||
local success, characterModule = pcall(require, "模块:卡牌/" .. characterName) | local success, characterModule = pcall(require, "模块:卡牌/" .. characterName) | ||
if not success or not characterModule then | if not success or not characterModule then | ||
return format( | return string.format("找不到战斗员卡牌数据模块: 模块:卡牌/%s", characterName) | ||
end | end | ||
-- | -- 如果没有指定卡牌名,显示所有默认卡牌 | ||
if cardName == "" then | if cardName == "" then | ||
return displayAllDefaultCards(frame, characterModule, characterName) | return displayAllDefaultCards(frame, characterModule, characterName) | ||
end | end | ||
-- | -- 获取指定卡牌数据 | ||
local cardData = (characterModule.card or {})[cardName] | local cardData = (characterModule.card or {})[cardName] | ||
if not cardData then | if not cardData then | ||
return format( | return string.format("找不到卡牌: %s", cardName) | ||
end | end | ||
| 第279行: | 第281行: | ||
end | end | ||
-- | -- 元表设置,支持直接调用战斗员名称作为方法 | ||
setmetatable(p, { | setmetatable(p, { | ||
__index = function(t, characterName) | __index = function(t, characterName) | ||
2025年10月1日 (三) 21:19的版本
此模块的文档可以在模块:卡牌/doc创建
local p = {}
-- 颜色映射表
local COLOR_MAP = {
["白"] = { bgColor = "rgba(249, 249, 249, 0.5)", textColor = "white" },
["蓝"] = { bgColor = "rgba(115, 236, 254, 0.5)", textColor = "#7de5ff" },
["橙"] = { bgColor = "rgba(254, 199, 109, 0.5)", textColor = "#ffee75" },
["彩"] = { bgColor = "rgba(201, 88, 241, 0.5)", textColor = "#eba2fc" }
}
-- 安全获取数据字段
local function safeGet(data, field, default)
return data and data[field] or default
end
-- 处理描述文本中的模板
local function processDescription(frame, description)
if not description or description == "" then
return description
end
local success, result = pcall(function()
return frame:preprocess(description)
end)
return success and result or description
end
-- 生成卡牌HTML样式组件
local function buildStyleComponents(cardData, cardName, baseCardData)
local color = safeGet(cardData, "稀有度", "白")
local colorStyle = COLOR_MAP[color] or COLOR_MAP["白"]
local attribute = safeGet(cardData, "属性", "虚无")
local cardDeck = safeGet(cardData, "卡组", "起始卡牌")
local ap = safeGet(cardData, "AP", "")
local originalAP = baseCardData and safeGet(baseCardData, "AP", ap) or ap
-- 决定AP的发光颜色
local apGlowColor = "#4a90e2" -- 默认蓝色
if baseCardData and ap ~= originalAP then
if ap == "X" then
apGlowColor = "#4a90e2" -- X值保持默认蓝色
elseif tonumber(ap) and tonumber(originalAP) then
if tonumber(ap) < tonumber(originalAP) then
apGlowColor = "#51f651" -- 绿色(AP降低)
else
apGlowColor = "#f65151" -- 红色(AP增加)
end
end
end
-- 检查原卡牌与当前卡牌的机制变化
local mechanism = safeGet(cardData, "机制", "")
local originalMechanism = baseCardData and safeGet(baseCardData, "机制", "") or mechanism
-- 将"无"视为空字符串
if mechanism == "无" then mechanism = "" end
if originalMechanism == "无" then originalMechanism = "" end
local mechanismChanged = baseCardData and mechanism ~= "" and originalMechanism == ""
return {
color = color,
colorStyle = colorStyle,
attribute = attribute,
ap = ap,
apGlowColor = apGlowColor,
cardType = safeGet(cardData, "类型", ""),
art = safeGet(cardData, "art", ""),
mechanism = mechanism,
mechanismChanged = mechanismChanged
}
end
-- 构建卡牌HTML
local function buildCardHTML(frame, cardName, cardData, baseCardData, characterName)
if not cardData then
return string.format("找不到卡牌数据: %s", cardName or "未指定")
end
local style = buildStyleComponents(cardData, cardName, baseCardData)
local description = processDescription(frame, safeGet(cardData, "描述", ""))
-- 获取衍生卡牌信息
local derivedCards = safeGet(cardData, "衍生卡牌", "")
local deckType = safeGet(cardData, "卡组", "")
-- 生成数据属性
local dataAttrs = string.format('data-card-name="%s" data-character="%s" data-deck-type="%s" data-derived-cards="%s"',
cardName or "", characterName or "", deckType or "", derivedCards or "")
-- 处理机制文本(修改:当机制为"无"时不显示)
local mechanismHTML = ""
if style.mechanism and style.mechanism ~= "" and style.mechanism ~= "无" then
local mechanismColor = style.mechanismChanged and "#b5f651" or "#f6c478"
mechanismHTML = string.format('<div style="color: %s; margin-bottom: 4px;">[%s]</div>',
mechanismColor, style.mechanism:gsub("、", "/"))
end
-- 使用字符串拼接优化HTML生成
local htmlParts = {
string.format('<div class="game-card" %s style="display: inline-block; vertical-align: top; position: relative; width: 168px; height: 230px; overflow: hidden; margin: 0px; cursor: pointer;">', dataAttrs),
}
-- 根据类型判断使用哪种布局
if style.cardType == "状态异常" then
-- 状态异常卡牌的特殊布局
table.insert(htmlParts, string.format('<div style="position: absolute; top: 5px; left: 5px;">[[File:%s|150px|link=]]</div>', style.art))
table.insert(htmlParts, string.format('<div style="position: absolute; top: 0px; left: 0px;">[[File:card_状态异常_%s.png|159px|link=]]</div>', style.attribute))
-- AP值
table.insert(htmlParts, string.format('<div style="position: absolute; left: 24px; top: 4px; color: white; font-weight: bold; text-shadow: 0 0 10px %s,0 0 20px %s, 0 0 30px %s, 0 0 40px %s; font-size: 32px;">%s</div>',
style.apGlowColor, style.apGlowColor, style.apGlowColor, style.apGlowColor, style.ap))
table.insert(htmlParts, string.format('<div style="position: absolute; left: 25px; top: 34px; color: white; font-weight: bold; text-shadow: 0 0 10px %s,0 0 20px %s, 0 0 30px %s, 0 0 40px %s;">—</div>',
style.apGlowColor, style.apGlowColor, style.apGlowColor, style.apGlowColor))
-- 卡牌名称和类型
table.insert(htmlParts, string.format('<div style="position: absolute; left: 50px; top: 13px; color: %s; font-size:16px">%s</div>',
style.colorStyle.textColor, cardName))
table.insert(htmlParts, string.format('<div style="position: absolute; left: 48px; top: 30px;">[[File:icon_card_%s.png|18px|link=]]</div>',
style.cardType))
table.insert(htmlParts, string.format('<div style="position: absolute; left: 68px; top: 33px; color: white; font-size:14px">%s</div>',
style.cardType))
-- 顶层蒙版
table.insert(htmlParts, '<div style="position: absolute; left: 0px; bottom: 0px;">[[File:card_顶层蒙版.png|168px|link=]]</div>')
else
-- 普通卡牌的布局
-- 背景图片层
table.insert(htmlParts, string.format('<div style="position: absolute; top: 1px; left: 12px;">[[File:%s|151px|link=]]</div>', style.art))
table.insert(htmlParts, '<div style="position: absolute; top: 1px; left: 12px;">[[File:card_黑色蒙版.png|151px|link=]]</div>')
-- 颜色条
table.insert(htmlParts, string.format('<div style="position: absolute; top: 21px; left: 10px; width: 148px; height: 8px; background-color: %s;"></div>',
style.colorStyle.bgColor))
-- AP值
table.insert(htmlParts, string.format('<div style="position: absolute; left: 24px; top: 4px; color: white; font-weight: bold; text-shadow: 0 0 10px %s,0 0 20px %s, 0 0 30px %s, 0 0 40px %s; font-size: 32px;">%s</div>',
style.apGlowColor, style.apGlowColor, style.apGlowColor, style.apGlowColor, style.ap))
table.insert(htmlParts, string.format('<div style="position: absolute; left: 25px; top: 34px; color: white; font-weight: bold; text-shadow: 0 0 10px %s,0 0 20px %s, 0 0 30px %s, 0 0 40px %s;">—</div>',
style.apGlowColor, style.apGlowColor, style.apGlowColor, style.apGlowColor))
-- 卡牌名称和类型
table.insert(htmlParts, string.format('<div style="position: absolute; left: 50px; top: 13px; color: %s; font-size:16px">%s</div>',
style.colorStyle.textColor, cardName))
table.insert(htmlParts, string.format('<div style="position: absolute; left: 48px; top: 30px;">[[File:icon_card_%s.png|18px|link=]]</div>',
style.cardType))
table.insert(htmlParts, string.format('<div style="position: absolute; left: 68px; top: 33px; color: white; font-size:14px">%s</div>',
style.cardType))
-- 边框
table.insert(htmlParts, string.format('<div style="position: absolute; top: 0px; left: 1px;">[[File:card_属性边框_%s.png|160px|link=]]</div>',
style.attribute))
-- 稀有度
table.insert(htmlParts, string.format('<div style="position: absolute; top: 10px; left: 0px;">[[File:card_稀有度_%s.png|22px|link=]]</div>',
style.color))
table.insert(htmlParts, string.format('<div style="position: absolute; top: 2px; right: 4px;">[[File:card_稀有度_边框_%s.png|11px|link=]]</div>',
style.color))
-- 顶层蒙版
table.insert(htmlParts, '<div style="position: absolute; left: 0px; bottom: 0px;">[[File:card_顶层蒙版.png|168px|link=]]</div>')
end
-- 描述文本
table.insert(htmlParts, '<div style="position: absolute; bottom: 7px; left: 15px; width: 144px; height: 100px; font-size: 12px; color: white; line-height: 13px; display: flex; justify-content: center; align-items: center; text-align: center;">')
table.insert(htmlParts, '<div style="line-height: 13px;">')
table.insert(htmlParts, mechanismHTML)
table.insert(htmlParts, description)
table.insert(htmlParts, '</div>')
table.insert(htmlParts, '</div>')
table.insert(htmlParts, '</div>')
return table.concat(htmlParts)
end
-- 合并卡牌数据
local function mergeCardData(baseData, overrideData)
local result = {}
for k, v in pairs(baseData or {}) do
result[k] = v
end
for k, v in pairs(overrideData or {}) do
result[k] = v
end
return result
end
-- 获取并显示所有默认卡牌
local function displayAllDefaultCards(frame, characterModule, characterName)
local cards = characterModule.card or {}
local cardOrder = characterModule.cardOrder or {}
local displayedCards = {}
-- 按cardOrder顺序遍历
for orderIndex, name in ipairs(cardOrder) do
local cardArray = cards[name]
if cardArray and #cardArray > 0 then
-- 只显示第一张卡牌
table.insert(displayedCards, {
name = name,
data = cardArray[1],
order = orderIndex
})
end
end
-- 生成HTML
local htmlParts = {}
for i, cardInfo in ipairs(displayedCards) do
table.insert(htmlParts, buildCardHTML(frame, cardInfo.name, cardInfo.data, nil, characterName))
end
return table.concat(htmlParts)
end
-- 处理特定卡牌请求
local function handleSpecificCard(frame, cardName, cardData, deckFilter, cardIndex, characterName)
local baseCard = cardData[1]
-- 如果没有指定卡组筛选,返回基础卡牌
if deckFilter == "" then
return buildCardHTML(frame, cardName, baseCard, nil, characterName)
end
-- 筛选指定卡组的卡牌
local filteredCards = {}
for _, card in ipairs(cardData) do
if card["卡组"] == deckFilter then
table.insert(filteredCards, card)
end
end
if #filteredCards == 0 then
return string.format("找不到卡组 '%s' 的卡牌: %s", deckFilter, cardName)
end
-- 如果指定了索引,返回特定卡牌
if cardIndex > 0 and cardIndex <= #filteredCards then
local mergedCard = mergeCardData(baseCard, filteredCards[cardIndex])
return buildCardHTML(frame, cardName, mergedCard, baseCard, characterName)
end
-- 否则返回该卡组的所有卡牌
local htmlParts = {}
for i, card in ipairs(filteredCards) do
local mergedCard = mergeCardData(baseCard, card)
table.insert(htmlParts, buildCardHTML(frame, cardName, mergedCard, baseCard, characterName))
end
return table.concat(htmlParts)
end
-- 主函数
function p.main(frame)
local args = frame.args
local characterName = args[1] or ""
local cardName = args[2] or ""
local deckFilter = args[3] or ""
local cardIndex = tonumber(args[4]) or 0
-- 加载战斗员模块
local success, characterModule = pcall(require, "模块:卡牌/" .. characterName)
if not success or not characterModule then
return string.format("找不到战斗员卡牌数据模块: 模块:卡牌/%s", characterName)
end
-- 如果没有指定卡牌名,显示所有默认卡牌
if cardName == "" then
return displayAllDefaultCards(frame, characterModule, characterName)
end
-- 获取指定卡牌数据
local cardData = (characterModule.card or {})[cardName]
if not cardData then
return string.format("找不到卡牌: %s", cardName)
end
return handleSpecificCard(frame, cardName, cardData, deckFilter, cardIndex, characterName)
end
-- 元表设置,支持直接调用战斗员名称作为方法
setmetatable(p, {
__index = function(t, characterName)
return function(frame)
frame.args = {
[1] = characterName,
[2] = frame.args[1] or "",
[3] = frame.args[2] or "",
[4] = frame.args[3] or 0
}
return p.main(frame)
end
end
})
return p