模块

装备:修订间差异

来自卡厄思梦境WIKI

律Rhyme留言 | 贡献
无编辑摘要
律Rhyme留言 | 贡献
无编辑摘要
第1行: 第1行:
local p = {}
local p = {}
local equipment_data = mw.loadData("模块:装备/data")
local equipmentData = mw.loadData('模块:装备/data')


-- 获取装备星级图标
-- 辅助函数:解析文本模板
local function getStarIcon(star)
local function parseText(text)
     return "[[File:icon_star_rating_" .. star .. ".png|link=]]"
     if not text then return "" end
    -- 将{{文本|橙|内容}}转换为HTML
    text = text:gsub("{{文本|橙|([^}]+)}}", '<span style="color:#FF9900">%1</span>')
    return text
end
end


-- 生成装备卡片HTML
-- 获取装备稀有度对应的背景图片
local function generateEquipmentCard(name, star)
local function getRarityBg(rarity)
     local equip = equipment_data[name]
    local rarityMap = {
     if not equip then
        ["蓝"] = "bg_equipment_rarity_蓝.png",
         return "装备不存在: " .. name
        ["紫"] = "bg_equipment_rarity_紫.png",
        ["金"] = "bg_equipment_rarity_金.png"
    }
    return rarityMap[rarity] or "bg_equipment_rarity_蓝.png"
end
 
-- 获取装备类型对应的图标
local function getTypeIcon(equipType, rarity)
    local typeMap = {
        ["武器"] = "武器",
        ["刀"] = "武器",
        ["装甲"] = "装甲",
        ["戒指"] = "戒指"
    }
    local mappedType = typeMap[equipType] or "武器"
    return string.format("icon_equip_%s_%s.png", mappedType, rarity)
end
 
-- 生成装备卡片
function p.card(frame)
    local args = frame:getParent().args or frame.args
     local name = args[1] or args.name
    local level = args[2] or args.level or "1"
   
     if not name or not equipmentData[name] then
         return "装备不存在: " .. (name or "未指定")
     end
     end
      
      
    local equip = equipmentData[name]
     local base = equip.base
     local base = equip.base
    -- 确保 star 是数字类型
     local levelData = equip[level] or equip["1"]
    star = tonumber(star) or 1
     local level = equip[star]
   
    if not level then
        return "错误: 装备 " .. name .. " 没有 " .. star .. " 星级数据"
    end
      
      
     local html = mw.html.create('div')
     local rarityBg = getRarityBg(base.rarity)
        :addClass('equipment-card')
        :attr('data-name', name)
        :attr('data-star', star)
        :css({
            position = 'relative',
            display = 'inline-block',
            width = '150px',
            height = '230px',
            cursor = 'pointer'
        })
      
      
     -- 背景
     -- 生成唯一ID用于弹窗
     html:tag('div')
     local uniqueId = "equip_" .. mw.hash.hashValue('md5', name .. os.time() .. math.random())
        :css({position = 'absolute', top = '0px', left = '0px'})
        :wikitext('[[File:bg_equipment_rarity_' .. base.rarity .. '.png|150px|link=]]')
      
      
     -- 装备图片
     -- 使用单引号包裹HTML字符串,避免双引号冲突
     html:tag('div')
     local html = string.format([=[
        :css({position = 'absolute', top = '43px', left = '13px'})
<div class="equipment-card" data-equipment="%s" data-level="%s" style="position: relative; display: inline-block; width:150px; height: 230px; cursor: pointer;">
        :wikitext('[[File:' .. base.art .. '|124px|link=]]')
<div style="position: absolute; top: 0px; left: 0px;">[[File:%s|150px|link=]]</div>
<div style="position: absolute; top: 43px; left: 13px;">[[File:%s|124px|link=]]</div>
<div style="position: absolute; bottom: 5px; left: 5px; width: 140px; height: 35px; background-color: rgba(0,0,0,0.5); border-radius: 0px 0px 8px 8px"></div>
<div style="position: absolute; bottom: 10px; left: 20px;">[[File:icon_star_rating_%s.png|link=]]</div>
<div style="position: absolute; top: 0px; left: 0px;">[[File:equipment_顶层蒙版.png|150px|link=]]</div>
</div>]=],
        uniqueId,
        level,
        rarityBg,
        base.art,
        level
    )
      
      
     -- 底部暗色遮罩
     return frame:preprocess(html)
    html:tag('div')
        :css({
            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')
        :css({position = 'absolute', bottom = '10px', left = '20px'})
        :wikitext(getStarIcon(star))
   
    -- 顶层蒙版
    html:tag('div')
        :css({position = 'absolute', top = '0px', left = '0px'})
        :wikitext('[[File:equipment_顶层蒙版.png|150px|link=]]')
   
    return tostring(html)
end
end


-- 生成装备弹窗HTML
-- 生成装备弹窗内容
local function generateEquipmentModal(name, star)
function p.popup(frame)
     local equip = equipment_data[name]
    local args = frame:getParent().args or frame.args
     if not equip then
     local name = args[1] or args.name
    local level = args[2] or args.level or "1"
   
     if not name or not equipmentData[name] then
         return ""
         return ""
     end
     end
      
      
    local equip = equipmentData[name]
     local base = equip.base
     local base = equip.base
     -- 确保 star 是数字类型
     local levelData = equip[level] or equip["1"]
    star = tonumber(star) or 1
    local level = equip[star]
      
      
     if not level then
     local collectionBg = "bg_collection_rarity_" .. base.rarity .. ".png"
        return ""
    local typeIcon = getTypeIcon(base.type, base.rarity)
     end
    local valueTypeText = base.value_type == "atk" and "攻击力" or "防御力"
     local desc = parseText(levelData.desc_global)
      
      
     local html = mw.html.create('div')
     local html = string.format([=[
        :addClass('equipment-modal')
<div style="position: relative; display: inline-block; width:368px; height: 335px; background-color: #343434; border-radius: 9px">
        :css({
<div style="position: absolute; top: 0px; left: 0px;">[[File:%s|link=]]</div>
            position = 'relative',
<div style="position: absolute; top: 40px; left: 128px;">[[File:%s|124px|link=]]</div>
            display = 'inline-block',
<div style="position: absolute; top: 167px; left: 0px; width: 368px; height: 35px; background-color: rgba(0,0,0,0.5); border-radius: 0px 0px 8px 8px"></div>
            width = '368px',
<div style="position: absolute; top: 173px; left: 128px;">[[File:icon_star_rating_%s.png|link=]]</div>
            height = '335px',
<div style="position: absolute; top: 205px; left: 5px; color: white">[[File:%s|25px|link=]]</div>
            ['background-color'] = '#343434',
<div style="position: absolute; top: 209px; left: 33px; color: white">%s</div>
            ['border-radius'] = '9px'
<div style="position: absolute; top: 235px; left: 9px; width: 350px; height: 35px; background-color: rgba(255,255,255,0.3); border-radius: 2px"></div>
         })
<div style="position: absolute; top: 242px; left: 14px; color: white">%s</div>
<div style="position: absolute; top: 242px; right: 14px; color: white">%s</div>
<div style="position: absolute; top: 277px; left: 10px; right: 10px; color: white">%s</div>
</div>]=],
        collectionBg,
        base.art,
        level,
        typeIcon,
        name,
        valueTypeText,
        levelData.value,
         desc
    )
      
      
     -- 背景
     return frame:preprocess(html)
    html:tag('div')
        :css({position = 'absolute', top = '0px', left = '0px'})
        :wikitext('[[File:bg_collection_rarity_' .. base.rarity .. '.png|link=]]')
   
    -- 装备图片
    html:tag('div')
        :css({position = 'absolute', top = '40px', left = '128px'})
        :wikitext('[[File:' .. base.art .. '|124px|link=]]')
   
    -- 分隔线遮罩
    html:tag('div')
        :css({
            position = 'absolute',
            top = '167px',
            left = '0px',
            width = '368px',
            height = '35px',
            ['background-color'] = 'rgba(0,0,0,0.5)',
            ['border-radius'] = '0px 0px 8px 8px'
        })
   
    -- 星级
    html:tag('div')
        :css({position = 'absolute', top = '173px', left = '128px'})
        :wikitext(getStarIcon(star))
   
    -- 装备类型图标
    html:tag('div')
        :css({position = 'absolute', top = '205px', left = '5px', color = 'white'})
        :wikitext('[[File:icon_equip_' .. base.type .. '_' .. base.rarity .. '.png|25px|link=]]')
   
    -- 装备名称
    html:tag('div')
        :css({position = 'absolute', top = '209px', left = '33px', color = 'white'})
        :wikitext(name)
   
    -- 属性背景
    html:tag('div')
        :css({
            position = 'absolute',
            top = '235px',
            left = '9px',
            width = '350px',
            height = '35px',
            ['background-color'] = 'rgba(255,255,255,0.3)',
            ['border-radius'] = '2px'
        })
   
    -- 属性类型
    html:tag('div')
        :css({position = 'absolute', top = '242px', left = '14px', color = 'white'})
        :wikitext(base.value_type)
   
    -- 属性值
    html:tag('div')
        :css({position = 'absolute', top = '242px', right = '14px', color = 'white'})
        :wikitext(level.value)
   
    -- 描述
    html:tag('div')
        :css({position = 'absolute', top = '277px', left = '10px', color = 'white', ['font-size'] = '12px'})
        :wikitext(level.desc_global)
   
    return tostring(html)
end
end


-- 主函数
-- 获取装备数据的JSON格式(供JS使用)
function p.show(frame)
function p.getDataJson(frame)
     -- 直接使用 frame.args 而不是 getParent().args
     local args = frame:getParent().args or frame.args
     local args = frame.args
     local name = args[1] or args.name
      
      
    -- 如果 frame.args 为空,尝试使用 getParent().args(用于模板调用)
     if not name or not equipmentData[name] then
     if not args[1] and not args.name then
         return "{}"
         args = frame:getParent().args
     end
     end
      
      
     local name = args[1] or args.name or ""
     local equip = equipmentData[name]
     local star = tonumber(args[2] or args.star or 1)
     local data = {
   
        name = name,
    -- 去除可能的空格
        base = equip.base,
    name = mw.text.trim(name)
         levels = {}
   
     }
    if name == "" then
         return "错误: 未指定装备名称"
     end
      
      
     -- 检查装备是否存在
     for i = 1, 5 do
    if not equipment_data[name] then
        if equip[tostring(i)] then
         return "错误: 装备不存在 - " .. name
            data.levels[i] = equip[tostring(i)]
         end
     end
     end
      
      
     -- 检查星级数据是否存在
     return mw.text.jsonEncode(data)
    if not equipment_data[name][star] then
        return "错误: 装备 " .. name .. " 没有 " .. star .. " 星级数据(可用星级: 1-5)"
    end
   
    local card = generateEquipmentCard(name, star)
    local modal = generateEquipmentModal(name, star)
   
    return card .. '<div class="equipment-modal-container" style="display:none;">' .. modal .. '</div>'
end
end


return p
return p

2025年10月17日 (五) 15:30的版本

此模块的文档可以在模块:装备/doc创建

local p = {}
local equipmentData = mw.loadData('模块:装备/data')

-- 辅助函数:解析文本模板
local function parseText(text)
    if not text then return "" end
    -- 将{{文本|橙|内容}}转换为HTML
    text = text:gsub("{{文本|橙|([^}]+)}}", '<span style="color:#FF9900">%1</span>')
    return text
end

-- 获取装备稀有度对应的背景图片
local function getRarityBg(rarity)
    local rarityMap = {
        ["蓝"] = "bg_equipment_rarity_蓝.png",
        ["紫"] = "bg_equipment_rarity_紫.png",
        ["金"] = "bg_equipment_rarity_金.png"
    }
    return rarityMap[rarity] or "bg_equipment_rarity_蓝.png"
end

-- 获取装备类型对应的图标
local function getTypeIcon(equipType, rarity)
    local typeMap = {
        ["武器"] = "武器",
        ["刀"] = "武器",
        ["装甲"] = "装甲",
        ["戒指"] = "戒指"
    }
    local mappedType = typeMap[equipType] or "武器"
    return string.format("icon_equip_%s_%s.png", mappedType, rarity)
end

-- 生成装备卡片
function p.card(frame)
    local args = frame:getParent().args or frame.args
    local name = args[1] or args.name
    local level = args[2] or args.level or "1"
    
    if not name or not equipmentData[name] then
        return "装备不存在: " .. (name or "未指定")
    end
    
    local equip = equipmentData[name]
    local base = equip.base
    local levelData = equip[level] or equip["1"]
    
    local rarityBg = getRarityBg(base.rarity)
    
    -- 生成唯一ID用于弹窗
    local uniqueId = "equip_" .. mw.hash.hashValue('md5', name .. os.time() .. math.random())
    
    -- 使用单引号包裹HTML字符串,避免双引号冲突
    local html = string.format([=[
<div class="equipment-card" data-equipment="%s" data-level="%s" style="position: relative; display: inline-block; width:150px; height: 230px; cursor: pointer;">
<div style="position: absolute; top: 0px; left: 0px;">[[File:%s|150px|link=]]</div>
<div style="position: absolute; top: 43px; left: 13px;">[[File:%s|124px|link=]]</div>
<div style="position: absolute; bottom: 5px; left: 5px; width: 140px; height: 35px; background-color: rgba(0,0,0,0.5); border-radius: 0px 0px 8px 8px"></div>
<div style="position: absolute; bottom: 10px; left: 20px;">[[File:icon_star_rating_%s.png|link=]]</div>
<div style="position: absolute; top: 0px; left: 0px;">[[File:equipment_顶层蒙版.png|150px|link=]]</div>
</div>]=],
        uniqueId,
        level,
        rarityBg,
        base.art,
        level
    )
    
    return frame:preprocess(html)
end

-- 生成装备弹窗内容
function p.popup(frame)
    local args = frame:getParent().args or frame.args
    local name = args[1] or args.name
    local level = args[2] or args.level or "1"
    
    if not name or not equipmentData[name] then
        return ""
    end
    
    local equip = equipmentData[name]
    local base = equip.base
    local levelData = equip[level] or equip["1"]
    
    local collectionBg = "bg_collection_rarity_" .. base.rarity .. ".png"
    local typeIcon = getTypeIcon(base.type, base.rarity)
    local valueTypeText = base.value_type == "atk" and "攻击力" or "防御力"
    local desc = parseText(levelData.desc_global)
    
    local html = string.format([=[
<div style="position: relative; display: inline-block; width:368px; height: 335px; background-color: #343434; border-radius: 9px">
<div style="position: absolute; top: 0px; left: 0px;">[[File:%s|link=]]</div>
<div style="position: absolute; top: 40px; left: 128px;">[[File:%s|124px|link=]]</div>
<div style="position: absolute; top: 167px; left: 0px; width: 368px; height: 35px; background-color: rgba(0,0,0,0.5); border-radius: 0px 0px 8px 8px"></div>
<div style="position: absolute; top: 173px; left: 128px;">[[File:icon_star_rating_%s.png|link=]]</div>
<div style="position: absolute; top: 205px; left: 5px; color: white">[[File:%s|25px|link=]]</div>
<div style="position: absolute; top: 209px; left: 33px; color: white">%s</div>
<div style="position: absolute; top: 235px; left: 9px; width: 350px; height: 35px; background-color: rgba(255,255,255,0.3); border-radius: 2px"></div>
<div style="position: absolute; top: 242px; left: 14px; color: white">%s</div>
<div style="position: absolute; top: 242px; right: 14px; color: white">%s</div>
<div style="position: absolute; top: 277px; left: 10px; right: 10px; color: white">%s</div>
</div>]=],
        collectionBg,
        base.art,
        level,
        typeIcon,
        name,
        valueTypeText,
        levelData.value,
        desc
    )
    
    return frame:preprocess(html)
end

-- 获取装备数据的JSON格式(供JS使用)
function p.getDataJson(frame)
    local args = frame:getParent().args or frame.args
    local name = args[1] or args.name
    
    if not name or not equipmentData[name] then
        return "{}"
    end
    
    local equip = equipmentData[name]
    local data = {
        name = name,
        base = equip.base,
        levels = {}
    }
    
    for i = 1, 5 do
        if equip[tostring(i)] then
            data.levels[i] = equip[tostring(i)]
        end
    end
    
    return mw.text.jsonEncode(data)
end

return p