七日内新公告:全站维护公告
  • 你好~!欢迎来到萌娘百科镜像站!如需查看或编辑,请联系本站管理员注册账号。
  • 本镜像站和其他萌娘百科的镜像站无关,请注意分别。

Module:ImasIcon/ML

猛汉♂百科,万男皆可猛的百科全书!转载请标注来源页面的网页链接,并声明引自猛汉百科。内容不可商用。
跳到导航 跳到搜索
Template-info.svg 模块文档  [创建] [刷新]
local getArgs = require('Module:Arguments').getArgs
local data = require('Module:ImasIcon/ML/Data')  -- 引入角色数据

local p = {}

-- 预建小写名称到ID的映射表
local nameToId = {}
for name, id in pairs(data) do
    nameToId[name:lower()] = id
end

-- 常量定义
local DEFAULT_SIZE = 146
local MIN_SIZE = 20  -- 允许生成的最小尺寸
local MAX_SIZE = 300  -- 允许生成的最大尺寸
local DEFAULT_ID = 0
local SPRITE_COLS = 16
local BORDER_RATIO = 1/18  -- 圆角矩形边框比例
local CONTENT_RATIO = 1 - 2 * BORDER_RATIO  -- 内容区域比例

-- 根据输入获取角色编号,支持编号或名称
local function getCharacterId(input)
    if not input or input == "" then
        return DEFAULT_ID, "未提供角色参数"
    end
    -- 尝试直接转换为数字
    local num = tonumber(input)
    if num then
        -- 处理负值和0的情况
        if num <= 0 then
            return DEFAULT_ID, "无效角色ID:" .. input
        end
        return num, nil
    end
    -- 从预建索引中查找名称
    local id = nameToId[input:lower()]
    if id then
        return id, nil
    end

    return DEFAULT_ID, "无效角色信息:" .. input
end

function p.main(frame)
    local args = getArgs(frame)
    -- 获取角色编号和错误信息
    local id, errorMsg = getCharacterId(args[1])
    local isValidId = id > 0  -- 只接受正整数ID
    
    -- 处理尺寸参数,并限制范围
    local size = tonumber(args[2]) or DEFAULT_SIZE
    size = math.max(MIN_SIZE, math.min(size, MAX_SIZE))
    
    -- 处理形状参数
    local shape = args.shape or ""
    local validShapes = {
        circle = true,
        roundedrect = true
    }
    local isCircle = validShapes[shape] and shape == "circle"
    local isRoundedRect = validShapes[shape] and shape == "roundedrect"
    
    -- 边框处理
    local hasBorder = args.border and true or false
    
    -- 计算实际显示尺寸
    local dimension = size
    if hasBorder and isRoundedRect then
        dimension = size * CONTENT_RATIO
    end
    
    -- 构建class属性
    local classes = {"imas-ml-sprite"}
    -- 添加形状类,传入非有效形状默认无形状
    if isCircle then
        table.insert(classes, "ml-sprite-circle")
    elseif isRoundedRect then
        table.insert(classes, "ml-sprite-roundedrect")
    end
    -- 添加边框类
    if hasBorder then
        table.insert(classes, "ml-sprite-bordered")
    end
    -- 添加错误状态类
    if not isValidId then
        table.insert(classes, "ml-sprite-error")
    end
    -- 添加用户自定义类(如果存在)
    if args.class and args.class ~= "" then
        table.insert(classes, args.class)
    end
    
    -- 计算背景位置 - 使用改进后的计算方法
    local bgSize, bgPos
    if isValidId then
        -- 计算精灵图中的位置
        local typeOffset = args.type == "N+" and 1 or 0
        local positionId = 2 * id - 1 + typeOffset
        
        -- 计算行列位置
        local col = (positionId - 1) % SPRITE_COLS
        local row = math.floor((positionId - 1) / SPRITE_COLS)
        
        -- 计算背景图总宽度
        local bgWidth = SPRITE_COLS * size
        bgSize = string.format("%dpx auto", bgWidth)
        bgPos = string.format("%dpx %dpx", -col * size, -row * size)
        
        -- 圆角矩形边框位置微调
        if hasBorder and isRoundedRect then
            -- 转换为像素偏移量
            local borderOffset = size * BORDER_RATIO
            bgPos = string.format("%dpx %dpx", 
                -col * size - borderOffset, 
                -row * size - borderOffset)
        end
    else
        -- 无效ID处理:显示透明区域
        bgSize = "0 0"
        bgPos = "0 0"
    end
    
    -- 边框宽度处理
    local borderStyle = ""
    if hasBorder then
        borderStyle = isRoundedRect and 
            string.format("border-width: %.2fpx;", size * BORDER_RATIO) or 
            "border-width: medium;"
    end
    
    -- 组合所有样式
    local styles = {
        string.format("height: %.2fpx;", dimension),
        string.format("width: %.2fpx;", dimension),
        string.format("background-size: %s;", bgSize),
        string.format("background-position: %s;", bgPos),
        borderStyle,
        args.style or ""
    }
    
    -- 生成最终HTML
    return string.format(
        '<span class="%s" style="%s" title="%s"></span>',
        table.concat(classes, " "),
        table.concat(styles, ""),
        errorMsg or ""  -- 错误提示(鼠标悬停显示)
    )
end

return p