模块

配队/卡牌:修订间差异

来自卡厄思梦境WIKI

律Rhyme留言 | 贡献
无编辑摘要
律Rhyme留言 | 贡献
无编辑摘要
 
(未显示同一用户的8个中间版本)
第1行: 第1行:
local p = {}
local p = {}


-- 使用官方参数解析器
-- 引入依赖模块
local getArgs = require('Module:Arguments').getArgs
local getArgs = require('Module:Arguments').getArgs
-- 引入卡牌模块
local cardModule = require('Module:卡牌')
local cardModule = require('Module:卡牌')


第12行: 第10行:
end
end


-- 安全地从页面获取属性值
-- 安全的字符串处理函数
local function getProperty(pageName, propertyName)
local function safeString(str)
     if not pageName or pageName == '' then
    if not str then return "" end
         return nil
    str = tostring(str)
    -- 确保字符串是有效的UTF-8
     if not mw.ustring then
        return str
    end
    -- 移除可能的BOM和其他非打印字符
    str = mw.text.trim(str)
    return str
end
 
-- 解析 card.order 字符串,返回卡牌名称数组
local function parseCardOrder(orderStr)
    orderStr = safeString(orderStr)
    if orderStr == "" then
        return {}
    end
   
    local cards = {}
    -- 保留卡牌名称中的中文标点符号
    for cardName in mw.ustring.gmatch(orderStr, '([^,]+)') do
        cardName = mw.text.trim(cardName)
        if cardName ~= "" then
            table.insert(cards, cardName)
         end
    end
   
    return cards
end
 
-- 主函数:批量显示指定战斗员的卡牌
-- 参数:
--  moduleName: 战斗员模块名(如 "凯隆")
function p.main(frame)
    local args = getArgs(frame, { removeBlank = true })
   
    local moduleName = args[1] or args.module
   
    moduleName = safeString(moduleName)
    if moduleName == "" then
        return err("错误: 未指定战斗员模块名")
     end
     end
      
      
     -- 构造完整页面名(如果需要命名空间)
     -- 加载战斗员卡牌数据模块
     local fullPageName = pageName
     local success, cardData = pcall(require, 'Module:卡牌/' .. moduleName)
    if not pageName:match(':') then
    if not success or not cardData then
         fullPageName = '战斗员:' .. pageName
         return err('错误: 找不到模块 "Module:卡牌/' .. moduleName .. '"')
     end
     end
      
      
     -- 检查页面是否存在
     -- 获取 card.order
     local title = mw.title.new(fullPageName)
     local orderData = cardData.order
     if not title or not title.exists then
     if not orderData then
         return nil
         return err('错误: 模块 "' .. moduleName .. '" 没有定义 card.order')
     end
     end
      
      
     -- 尝试从页面源码解析
     -- 如果 order 是表格,取第一个元素
     local content = title:getContent()
     local orderStr = orderData
     if content then
     if type(orderData) == "table" then
        local pattern = '|' .. propertyName .. '%s*=%s*([^\n|]*)'
         if #orderData == 0 then
        local value = content:match(pattern)
             return err('错误: card.order 为空')
         if value then
             value = mw.text.trim(value)
            if value ~= '' then
                return value
            end
         end
         end
        orderStr = orderData[1]
    end
   
    orderStr = safeString(orderStr)
    if orderStr == "" then
        return err('错误: card.order 为空或格式错误')
    end
   
    -- 解析卡牌顺序
    local cardNames = parseCardOrder(orderStr)
    if #cardNames == 0 then
        return err('错误: card.order 解析后为空,原始值: ' .. mw.text.encode(orderStr))
    end
   
    -- 直接构建 HTML 而不是调用 batch
    local html = {}
    table.insert(html, '<div style="display:flex;gap:0px;flex-wrap:wrap;">')
   
    for i, cardName in ipairs(cardNames) do
        -- 为每张卡牌创建独立的 frame
        local subFrame = {
            args = {moduleName, cardName},
            getParent = function() return frame end
        }
        table.insert(html, cardModule.main(subFrame))
     end
     end
      
      
     return nil
    table.insert(html, '</div>')
   
     return table.concat(html, '')
end
end


-- 已知的卡牌模块列表(按优先级排序)
-- 自定义函数:允许指定特定卡牌列表
local knownModules = {
-- 用法:{{#invoke:配队/卡牌|custom|模块名|卡牌1|卡牌2|卡牌3|...}}
    '齐尔克尼茨',
function p.custom(frame)
     '德洛斯',
     local args = getArgs(frame, { removeBlank = true })
     '尼希卢姆',
      
     '塞克瑞德',
     local moduleName = safeString(args[1])
    '维托尔',
     if moduleName == "" then
    '通用',
         return err("错误: 未指定战斗员模块名")
    '状态异常',
    -- 可以继续添加更多模块
}
 
-- 查找卡牌所在的模块
local function findCardModule(cardName)
     if not cardName or cardName == '' then
         return nil
     end
     end
      
      
     -- 遍历已知模块,查找卡牌
     -- 收集所有卡牌名称(从第2个参数开始)
     for _, moduleName in ipairs(knownModules) do
     local cardNames = {}
         local ok, dataModule = pcall(require, 'Module:卡牌/' .. moduleName)
    local i = 2
         if ok and dataModule then
    while args[i] do
             -- 检查卡牌是否存在于该模块
         local cardName = safeString(args[i])
            if dataModule[cardName] then
         if cardName ~= "" then
                return moduleName
             table.insert(cardNames, cardName)
            end
         end
         end
        i = i + 1
    end
   
    if #cardNames == 0 then
        return err("错误: 未指定任何卡牌")
     end
     end
      
      
     return nil
     -- 直接构建 HTML
    local html = {}
    table.insert(html, '<div style="display:flex;gap:0px;flex-wrap:wrap;">')
   
    for _, cardName in ipairs(cardNames) do
        local subFrame = {
            args = {moduleName, cardName},
            getParent = function() return frame end
        }
        table.insert(html, cardModule.main(subFrame))
    end
   
    table.insert(html, '</div>')
   
    return table.concat(html, '')
end
end


-- 解析卡牌字符串
-- 显示指定战斗员的所有卡牌(按字母顺序)
-- 支持格式:
-- 用法:{{#invoke:配队/卡牌|all|模块名}}
-- 1. 卡牌名
function p.all(frame)
-- 2. 模块名|卡牌名
    local args = getArgs(frame, { removeBlank = true })
-- 3. 模块名|卡牌名|变体类型|变体参数|变体索引
   
local function parseCardString(cardStr)
    local moduleName = safeString(args[1])
     if not cardStr or cardStr == '' then
     if moduleName == "" then
         return nil
         return err("错误: 未指定战斗员模块名")
     end
     end
      
      
     cardStr = mw.text.trim(cardStr)
     -- 加载战斗员卡牌数据模块
    local success, cardData = pcall(require, 'Module:卡牌/' .. moduleName)
    if not success or not cardData then
        return err('错误: 找不到模块 "Module:卡牌/' .. moduleName .. '"')
    end
      
      
     -- 检查是否包含 | 分隔符
     -- 收集所有卡牌名称(除了 info 和 order)
     if not cardStr:match('|') then
     local cardNames = {}
         -- 格式1:只有卡牌名,需要自动查找模块
    for cardName, _ in pairs(cardData) do
        local moduleName = findCardModule(cardStr)
         if cardName ~= "info" and cardName ~= "order" and type(cardData[cardName]) == "table" then
        if not moduleName then
             table.insert(cardNames, cardName)
             return nil, '找不到卡牌 "' .. cardStr .. '" 所在的模块'
         end
         end
        return {
            moduleName = moduleName,
            cardName = cardStr,
            variantType = nil,
            variantParam = nil,
            variantIndex = nil
        }
     end
     end
      
      
     -- 格式2或3:包含模块名
     table.sort(cardNames)  -- 按字母顺序排序
     local parts = {}
      
     for part in cardStr:gmatch('([^|]+)') do
     if #cardNames == 0 then
         table.insert(parts, mw.text.trim(part))
         return err("错误: 模块中没有找到任何卡牌")
     end
     end
      
      
     if #parts < 2 then
     -- 直接构建 HTML
        return nil, '卡牌字符串格式错误: ' .. cardStr
    local html = {}
    table.insert(html, '<div style="display:flex;gap:0px;flex-wrap:wrap;">')
   
    for _, cardName in ipairs(cardNames) do
        local subFrame = {
            args = {moduleName, cardName},
            getParent = function() return frame end
        }
        table.insert(html, cardModule.main(subFrame))
     end
     end
      
      
     return {
     table.insert(html, '</div>')
        moduleName = parts[1],
   
        cardName = parts[2],
    return table.concat(html, '')
        variantType = parts[3],
        variantParam = parts[4],
        variantIndex = parts[5]
    }
end
end


-- 主函数
-- 调试函数:显示 card.order 的原始内容
function p.main(frame)
function p.debug(frame)
     local args = getArgs(frame, { removeBlank = true })
     local args = getArgs(frame, { removeBlank = true })
    local moduleName = safeString(args[1])
      
      
     -- 第一个参数是战斗员名称
     if moduleName == "" then
     local characterName = args[1]
        return err("错误: 未指定战斗员模块名")
     end
      
      
     if not characterName or characterName == '' then
    local success, cardData = pcall(require, 'Module:卡牌/' .. moduleName)
         return err('错误: 未指定战斗员名称')
     if not success or not cardData then
         return err('错误: 找不到模块 "Module:卡牌/' .. moduleName .. '"')
     end
     end
      
      
    -- 定义要读取的卡牌字段列表(按顺序)
     local orderData = cardData.order
    local cardFields = {
     local html = {}
        '自我意识技能',
        '起始卡牌_1',
        '起始卡牌_2',
        '起始卡牌_3',
        '起始卡牌_4',
        '独特卡牌_1',
        '独特卡牌_2',
        '独特卡牌_3',
        '独特卡牌_4'
    }
   
    -- 收集所有卡牌数据
     local cardDataList = {}
     local errors = {}
      
      
     for _, fieldName in ipairs(cardFields) do
     table.insert(html, '<div style="background:#f9f9f9;border:1px solid #ccc;padding:0px;margin:10px 0;">')
        local cardStr = getProperty(characterName, fieldName)
    table.insert(html, '<b>调试信息:</b><br>')
        if cardStr and cardStr ~= '' then
    table.insert(html, '<b>order 类型:</b>' .. type(orderData) .. '<br>')
            local cardData, errMsg = parseCardString(cardStr)
            if cardData then
                table.insert(cardDataList, cardData)
            elseif errMsg then
                table.insert(errors, fieldName .. ': ' .. errMsg)
            end
        end
    end
      
      
    -- 如果有错误,显示错误信息
     if type(orderData) == "table" then
     if #errors > 0 then
         table.insert(html, '<b>order 长度:</b>' .. #orderData .. '<br>')
        local errorHtml = {}
         for i, v in ipairs(orderData) do
         table.insert(errorHtml, '<div style="color: red;">')
             table.insert(html, '<b>order[' .. i .. ']:</b>' .. mw.text.encode(tostring(v)) .. '<br>')
        table.insert(errorHtml, '解析卡牌信息时出错:<br>')
         for _, errMsg in ipairs(errors) do
             table.insert(errorHtml, '- ' .. mw.text.encode(errMsg) .. '<br>')
         end
         end
         table.insert(errorHtml, '</div>')
    else
        return table.concat(errorHtml, '')
         table.insert(html, '<b>order 值:</b>' .. mw.text.encode(tostring(orderData)) .. '<br>')
     end
     end
      
      
     -- 如果没有找到任何卡牌
     local orderStr = type(orderData) == "table" and orderData[1] or orderData
    if #cardDataList == 0 then
     local cardNames = parseCardOrder(orderStr)
        return err('错误: 战斗员 "' .. characterName .. '" 没有配置任何卡牌')
     end
      
      
     -- 使用 batch 渲染所有卡牌
     table.insert(html, '<b>解析后的卡牌数量:</b>' .. #cardNames .. '<br>')
    local batchArgs = {}
     for i, name in ipairs(cardNames) do
     for _, cardData in ipairs(cardDataList) do
         table.insert(html, '<b>' .. i .. '.</b> ' .. mw.text.encode(name) .. '<br>')
         table.insert(batchArgs, cardData.moduleName)
        table.insert(batchArgs, cardData.cardName)
        table.insert(batchArgs, cardData.variantType or '')
        table.insert(batchArgs, cardData.variantParam or '')
        table.insert(batchArgs, cardData.variantIndex or '')
     end
     end
      
      
     -- 创建一个模拟的 frame 调用 batch
     table.insert(html, '</div>')
    local batchFrame = {
        args = batchArgs,
        getParent = function() return frame end
    }
      
      
     return cardModule.batch(batchFrame)
     return table.concat(html, '')
end
end


-- 手动更新模块列表的函数(可选)
-- 配队模拟器专用:显示带有元数据的卡牌
function p.updateModules(frame)
function p.deck(frame)
     local args = getArgs(frame, { removeBlank = true })
     local args = getArgs(frame, { removeBlank = true })
      
      
     -- 这个函数可以用来动态更新 knownModules 列表
    local moduleName = safeString(args[1])
     -- 例如:{{#invoke:配队/卡牌|updateModules|新模块1|新模块2}}
    if moduleName == "" then
        return err("错误: 未指定战斗员模块名")
    end
   
     -- 加载战斗员卡牌数据模块
    local success, cardData = pcall(require, 'Module:卡牌/' .. moduleName)
    if not success or not cardData then
        return err('错误: 找不到模块 "Module:卡牌/' .. moduleName .. '"')
    end
   
     -- 获取 card.order
    local orderData = cardData.order
    if not orderData then
        return err('错误: 模块 "' .. moduleName .. '" 没有定义 card.order')
    end
      
      
     for i, moduleName in ipairs(args) do
     -- 如果 order 是表格,取第一个元素
        local found = false
    local orderStr = orderData
        for _, existing in ipairs(knownModules) do
    if type(orderData) == "table" then
            if existing == moduleName then
         if #orderData == 0 then
                found = true
             return err('错误: card.order 为空')
                break
            end
        end
         if not found then
             table.insert(knownModules, moduleName)
         end
         end
        orderStr = orderData[1]
    end
   
    orderStr = safeString(orderStr)
    if orderStr == "" then
        return err('错误: card.order 为空或格式错误')
    end
   
    -- 解析卡牌顺序
    local cardNames = parseCardOrder(orderStr)
    if #cardNames == 0 then
        return err('错误: card.order 解析后为空')
    end
   
    -- 构建带有特殊标记的 HTML
    local html = {}
    table.insert(html, '<div class="deck-cards-container" style="display:flex;gap:0px;flex-wrap:wrap;min-height:360px;">')
   
    for i, cardName in ipairs(cardNames) do
        -- 为每张卡牌创建包装器,包含元数据
        table.insert(html, '<div class="deck-card-wrapper" data-module="' .. mw.text.encode(moduleName) .. '" data-card="' .. mw.text.encode(cardName) .. '" style="display:inline-block;">')
       
        -- 调用原始的卡牌显示
        local subFrame = {
            args = {moduleName, cardName},
            getParent = function() return frame end
        }
        table.insert(html, cardModule.main(subFrame))
       
        table.insert(html, '</div>')
     end
     end
      
      
     return '已更新模块列表'
    table.insert(html, '</div>')
   
     return table.concat(html, '')
end
end


return p
return p

2025年11月1日 (六) 16:57的最新版本

此模块的文档可以在模块:配队/卡牌/doc创建

local p = {}

-- 引入依赖模块
local getArgs = require('Module:Arguments').getArgs
local cardModule = require('Module:卡牌')

-- 安全的错误输出
local function err(msg)
    return '<span style="color: red;">' .. mw.text.encode(msg) .. '</span>'
end

-- 安全的字符串处理函数
local function safeString(str)
    if not str then return "" end
    str = tostring(str)
    -- 确保字符串是有效的UTF-8
    if not mw.ustring then
        return str
    end
    -- 移除可能的BOM和其他非打印字符
    str = mw.text.trim(str)
    return str
end

-- 解析 card.order 字符串,返回卡牌名称数组
local function parseCardOrder(orderStr)
    orderStr = safeString(orderStr)
    if orderStr == "" then
        return {}
    end
    
    local cards = {}
    -- 保留卡牌名称中的中文标点符号
    for cardName in mw.ustring.gmatch(orderStr, '([^,]+)') do
        cardName = mw.text.trim(cardName)
        if cardName ~= "" then
            table.insert(cards, cardName)
        end
    end
    
    return cards
end

-- 主函数:批量显示指定战斗员的卡牌
-- 参数:
--   moduleName: 战斗员模块名(如 "凯隆")
function p.main(frame)
    local args = getArgs(frame, { removeBlank = true })
    
    local moduleName = args[1] or args.module
    
    moduleName = safeString(moduleName)
    if moduleName == "" then
        return err("错误: 未指定战斗员模块名")
    end
    
    -- 加载战斗员卡牌数据模块
    local success, cardData = pcall(require, 'Module:卡牌/' .. moduleName)
    if not success or not cardData then
        return err('错误: 找不到模块 "Module:卡牌/' .. moduleName .. '"')
    end
    
    -- 获取 card.order
    local orderData = cardData.order
    if not orderData then
        return err('错误: 模块 "' .. moduleName .. '" 没有定义 card.order')
    end
    
    -- 如果 order 是表格,取第一个元素
    local orderStr = orderData
    if type(orderData) == "table" then
        if #orderData == 0 then
            return err('错误: card.order 为空')
        end
        orderStr = orderData[1]
    end
    
    orderStr = safeString(orderStr)
    if orderStr == "" then
        return err('错误: card.order 为空或格式错误')
    end
    
    -- 解析卡牌顺序
    local cardNames = parseCardOrder(orderStr)
    if #cardNames == 0 then
        return err('错误: card.order 解析后为空,原始值: ' .. mw.text.encode(orderStr))
    end
    
    -- 直接构建 HTML 而不是调用 batch
    local html = {}
    table.insert(html, '<div style="display:flex;gap:0px;flex-wrap:wrap;">')
    
    for i, cardName in ipairs(cardNames) do
        -- 为每张卡牌创建独立的 frame
        local subFrame = {
            args = {moduleName, cardName},
            getParent = function() return frame end
        }
        table.insert(html, cardModule.main(subFrame))
    end
    
    table.insert(html, '</div>')
    
    return table.concat(html, '')
end

-- 自定义函数:允许指定特定卡牌列表
-- 用法:{{#invoke:配队/卡牌|custom|模块名|卡牌1|卡牌2|卡牌3|...}}
function p.custom(frame)
    local args = getArgs(frame, { removeBlank = true })
    
    local moduleName = safeString(args[1])
    if moduleName == "" then
        return err("错误: 未指定战斗员模块名")
    end
    
    -- 收集所有卡牌名称(从第2个参数开始)
    local cardNames = {}
    local i = 2
    while args[i] do
        local cardName = safeString(args[i])
        if cardName ~= "" then
            table.insert(cardNames, cardName)
        end
        i = i + 1
    end
    
    if #cardNames == 0 then
        return err("错误: 未指定任何卡牌")
    end
    
    -- 直接构建 HTML
    local html = {}
    table.insert(html, '<div style="display:flex;gap:0px;flex-wrap:wrap;">')
    
    for _, cardName in ipairs(cardNames) do
        local subFrame = {
            args = {moduleName, cardName},
            getParent = function() return frame end
        }
        table.insert(html, cardModule.main(subFrame))
    end
    
    table.insert(html, '</div>')
    
    return table.concat(html, '')
end

-- 显示指定战斗员的所有卡牌(按字母顺序)
-- 用法:{{#invoke:配队/卡牌|all|模块名}}
function p.all(frame)
    local args = getArgs(frame, { removeBlank = true })
    
    local moduleName = safeString(args[1])
    if moduleName == "" then
        return err("错误: 未指定战斗员模块名")
    end
    
    -- 加载战斗员卡牌数据模块
    local success, cardData = pcall(require, 'Module:卡牌/' .. moduleName)
    if not success or not cardData then
        return err('错误: 找不到模块 "Module:卡牌/' .. moduleName .. '"')
    end
    
    -- 收集所有卡牌名称(除了 info 和 order)
    local cardNames = {}
    for cardName, _ in pairs(cardData) do
        if cardName ~= "info" and cardName ~= "order" and type(cardData[cardName]) == "table" then
            table.insert(cardNames, cardName)
        end
    end
    
    table.sort(cardNames)  -- 按字母顺序排序
    
    if #cardNames == 0 then
        return err("错误: 模块中没有找到任何卡牌")
    end
    
    -- 直接构建 HTML
    local html = {}
    table.insert(html, '<div style="display:flex;gap:0px;flex-wrap:wrap;">')
    
    for _, cardName in ipairs(cardNames) do
        local subFrame = {
            args = {moduleName, cardName},
            getParent = function() return frame end
        }
        table.insert(html, cardModule.main(subFrame))
    end
    
    table.insert(html, '</div>')
    
    return table.concat(html, '')
end

-- 调试函数:显示 card.order 的原始内容
function p.debug(frame)
    local args = getArgs(frame, { removeBlank = true })
    local moduleName = safeString(args[1])
    
    if moduleName == "" then
        return err("错误: 未指定战斗员模块名")
    end
    
    local success, cardData = pcall(require, 'Module:卡牌/' .. moduleName)
    if not success or not cardData then
        return err('错误: 找不到模块 "Module:卡牌/' .. moduleName .. '"')
    end
    
    local orderData = cardData.order
    local html = {}
    
    table.insert(html, '<div style="background:#f9f9f9;border:1px solid #ccc;padding:0px;margin:10px 0;">')
    table.insert(html, '<b>调试信息:</b><br>')
    table.insert(html, '<b>order 类型:</b>' .. type(orderData) .. '<br>')
    
    if type(orderData) == "table" then
        table.insert(html, '<b>order 长度:</b>' .. #orderData .. '<br>')
        for i, v in ipairs(orderData) do
            table.insert(html, '<b>order[' .. i .. ']:</b>' .. mw.text.encode(tostring(v)) .. '<br>')
        end
    else
        table.insert(html, '<b>order 值:</b>' .. mw.text.encode(tostring(orderData)) .. '<br>')
    end
    
    local orderStr = type(orderData) == "table" and orderData[1] or orderData
    local cardNames = parseCardOrder(orderStr)
    
    table.insert(html, '<b>解析后的卡牌数量:</b>' .. #cardNames .. '<br>')
    for i, name in ipairs(cardNames) do
        table.insert(html, '<b>' .. i .. '.</b> ' .. mw.text.encode(name) .. '<br>')
    end
    
    table.insert(html, '</div>')
    
    return table.concat(html, '')
end

-- 配队模拟器专用:显示带有元数据的卡牌
function p.deck(frame)
    local args = getArgs(frame, { removeBlank = true })
    
    local moduleName = safeString(args[1])
    if moduleName == "" then
        return err("错误: 未指定战斗员模块名")
    end
    
    -- 加载战斗员卡牌数据模块
    local success, cardData = pcall(require, 'Module:卡牌/' .. moduleName)
    if not success or not cardData then
        return err('错误: 找不到模块 "Module:卡牌/' .. moduleName .. '"')
    end
    
    -- 获取 card.order
    local orderData = cardData.order
    if not orderData then
        return err('错误: 模块 "' .. moduleName .. '" 没有定义 card.order')
    end
    
    -- 如果 order 是表格,取第一个元素
    local orderStr = orderData
    if type(orderData) == "table" then
        if #orderData == 0 then
            return err('错误: card.order 为空')
        end
        orderStr = orderData[1]
    end
    
    orderStr = safeString(orderStr)
    if orderStr == "" then
        return err('错误: card.order 为空或格式错误')
    end
    
    -- 解析卡牌顺序
    local cardNames = parseCardOrder(orderStr)
    if #cardNames == 0 then
        return err('错误: card.order 解析后为空')
    end
    
    -- 构建带有特殊标记的 HTML
    local html = {}
    table.insert(html, '<div class="deck-cards-container" style="display:flex;gap:0px;flex-wrap:wrap;min-height:360px;">')
    
    for i, cardName in ipairs(cardNames) do
        -- 为每张卡牌创建包装器,包含元数据
        table.insert(html, '<div class="deck-card-wrapper" data-module="' .. mw.text.encode(moduleName) .. '" data-card="' .. mw.text.encode(cardName) .. '" style="display:inline-block;">')
        
        -- 调用原始的卡牌显示
        local subFrame = {
            args = {moduleName, cardName},
            getParent = function() return frame end
        }
        table.insert(html, cardModule.main(subFrame))
        
        table.insert(html, '</div>')
    end
    
    table.insert(html, '</div>')
    
    return table.concat(html, '')
end

return p