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