Module:Akshop
跳到导航
跳到搜索
-- =================================================================
-- Module:Akshop - 移植自Template:Akshop
-- 功能: 渲染明日方舟游戏内的活动商店表格
-- =================================================================
local p = {}
-- 预先加载需要的模块,避免在函数中重复加载
local frame -- 将在主函数中被赋值
local args = {}
-- =================================================================
-- 帮助函数
-- =================================================================
-- 替代 {{Akitem}} 模板调用
local function akitem(itemArgs)
return frame:expandTemplate{ title = 'Akitem', args = itemArgs }
end
-- 替代 {{color}} 模板调用
local function color(color, text)
return frame:expandTemplate{ title = 'color', args = { color, text } }
end
-- 根据阵列值获取表头的样式和文本
local function getStageHeader(stageValue, customStyle)
local styles = {
['1'] = 'background:linear-gradient(120deg,yellow,rgb(223,167,46),rgb(188,121,35),rgb(161,83,69),rgb(116,76,78),rgb(114,88,89),rgb(111,96,102),grey);color:#fff;',
['2'] = 'background:linear-gradient(120deg,rgb(155,153,168),rgb(121,121,138),grey);color:#fff;',
['3'] = 'background:grey;color:#fff;',
['4'] = 'background:grey;color:#fff;'
}
local texts = {
['1'] = '阶段一',
['2'] = '阶段二',
['3'] = '阶段三',
['4'] = '无限库存区'
}
if styles[stageValue] then
return string.format('!style="%s" colspan="12"|%s', styles[stageValue], texts[stageValue])
else
-- #default 分支
return string.format('!style="%s" colspan="12"|%s', customStyle or '', stageValue)
end
end
-- 生成一个商品的单元格 (包含名称、图标和库存)
local function buildItemCell(itemIndex, rowIndex)
local itemName = args['商品' .. itemIndex .. rowIndex]
if not itemName then return nil end
local itemType = args['种类' .. itemIndex .. rowIndex] or 'mat'
local price = args['价格' .. itemIndex .. rowIndex] or ''
local quantity = args['数量' .. itemIndex .. rowIndex]
local singleNum = args['单件数量' .. itemIndex .. rowIndex] or '1'
local rarity = args['稀有度' .. itemIndex .. rowIndex] or '1'
-- 从全局参数获取,而不是按行获取
local opName = args['对应干员'] or ''
local skinStyle = args['款式'] or '1'
local isToken = (string.sub(itemName, -3) == ' 信物')
local isSkin = (itemType == 'skin')
-- 构建商品名称单元格 (td 1)
local nameCellStyle
if isToken or isSkin then
nameCellStyle = 'background:rgb(13,123,173);color:white;'
else
nameCellStyle = 'font-weight:bold;background:#333;color:white'
end
-- 构建商品图标单元格 (td 2)
local iconArgs = { size = 60, unit = 'px' }
if isSkin then
iconArgs[1] = 'skin'
iconArgs[2] = opName
iconArgs[3] = skinStyle
elseif itemType == 'con' then
iconArgs[1] = 'con'
iconArgs[2] = itemName
iconArgs[3] = rarity
else -- 默认mat及其他
iconArgs[1] = itemType
iconArgs[2] = itemName
iconArgs.num = singleNum
end
-- 构建价格单元格 (td 3)
local priceCell
if isToken then
-- 信物的特殊价格显示,带下拉菜单
local tokenPrices = {
args['代币阶段1'] or 200,
args['代币阶段2'] or 240,
args['代币阶段3'] or 280,
args['代币阶段4'] or 320,
args['代币阶段5'] or 360
}
local totalTokenPrice = 0
for _, p in ipairs(tokenPrices) do totalTokenPrice = totalTokenPrice + tonumber(p) end
local dropdownContent = string.format(
'阶段一 %s<br>阶段二 %s<br>阶段三 %s<br>阶段四 %s<br>阶段五 %s',
tokenPrices[1], tokenPrices[2], tokenPrices[3], tokenPrices[4], tokenPrices[5]
)
local priceIcon = akitem({ 'mat', args['代币'], num = totalTokenPrice, size = 60, unit = 'px' })
priceCell = string.format(
'style="background:#444;color:white;" rowspan=2|<div class="dropdown">%s<div class="dropdown-content">%s</div></div>',
priceIcon, dropdownContent
)
else
priceCell = string.format('rowspan=2|%s', akitem({ 'mat', args['代币'], num = price, size = 60, unit = 'px' }))
end
-- 构建库存/等级单元格 (在第二行)
local stockCell
if isToken then
stockCell = 'style="color:#88BBD1;background:#333;vertical-align:middle"|<big><b>1 – 5</b></big>'
else
stockCell = string.format('style="background:#333;color:white"|库存 %s', color('#2BF', quantity or ''))
end
return {
top = string.format('!style="%s"|%s\n!!rowspan=2 style="background:#333"|%s\n!!%s',
nameCellStyle, itemName, akitem(iconArgs), priceCell),
bottom = string.format('!%s', stockCell)
}
end
-- =================================================================
-- 主函数
-- =================================================================
function p.main(frameObj)
frame = frameObj
args = frame:getParent().args
local t = {}
table.insert(t, '<div style="max-width:100%;overflow:auto;white-space:nowrap">')
table.insert(t, '{|class="wikitable mw-collapsible mw-collapsed" style="width:100%;text-align:center;white-space:normal;display:table;background:white"')
-- 商店标题栏
table.insert(t, '|-style="background:#000;color:#FFF;-webkit-text-fill-color:#FFF;"')
table.insert(t, string.format('|colspan=6 style="border-style:solid none solid none;padding-left:1em;padding-top:1em;padding-bottom:1em;width:50%%;text-align:left" |<span style="font-size:150%%;font-weight:bold">%s</span><br/>%s',
args['商店名字'] or '', args['代币描述'] or ''))
local tokenItem = ''
if args['代币'] and args['代币'] ~= '' then
tokenItem = akitem({ 'mat', args['代币'], size = 'x60', unit = 'px' })
end
table.insert(t, string.format('|colspan=3 style="border-style:solid none solid none;width:25%%" |<span style="font-weight:bold">%s<br>%s</span>',
tokenItem, args['代币'] or ''))
local openTime = args['凌晨开门'] and '04:00' or args['中午开门'] and '12:00' or '16:00'
table.insert(t, string.format('|colspan=2 style="border-style:solid none solid none"|<big><b>开放时间</b></big><br/>%s %s<br/>至<br/>%s 03:59',
args['开放日期'] or '', openTime, args['关闭日期'] or ''))
table.insert(t, '|style="border-style:solid none solid none;width:8%" |') -- 空白单元格
-- 商品列表标题
table.insert(t, '|-style="height:50px;color:#FFF;border-bottom:2px solid #2BF"')
table.insert(t, '!colspan=2 style="background:#000" |商品\n!style="background:#000"|价格')
table.insert(t, '!colspan=2 style="background:#000" |商品\n!style="background:#000"|价格')
table.insert(t, '!colspan=2 style="background:#000" |商品\n!style="background:#000"|价格')
table.insert(t, '!colspan=2 style="background:#000" |商品\n!style="background:#000"|价格')
-- 循环渲染商品行
for i = 1, 50 do -- 假设最多50行
if not args['商品1' .. i] then break end -- 如果该行第一个商品不存在,则停止循环
-- 检查是否有阶段标题
local stageValue = args['商店阵列' .. i]
if stageValue then
table.insert(t, '|-')
table.insert(t, getStageHeader(stageValue, args['商店阵列格式' .. i]))
end
-- 渲染一行中的所有商品
table.insert(t, '|-')
local rowTop, rowBottom = {}, {}
for j = 1, 4 do -- 每行最多4个商品
local cell = buildItemCell(j, i)
if cell then
table.insert(rowTop, cell.top)
table.insert(rowBottom, cell.bottom)
end
end
table.insert(t, table.concat(rowTop, '\n'))
table.insert(t, '|-')
table.insert(t, table.concat(rowBottom, '\n'))
end
-- 底部总计
table.insert(t, '|-')
table.insert(t, '|colspan=6 style="background:linear-gradient(120deg,yellow,rgb(223,167,46),rgb(188,121,35),rgb(161,83,69),rgb(116,76,78),rgb(114,88,89),rgb(111,96,102),grey);color:#fff;font-weight:bold;font-size:125%"|总计需要')
if args['代币'] and args['代币'] ~= '' then
table.insert(t, string.format('|colspan=6|%s', akitem({ 'mat', args['代币'], num = args['总需求'] or '', size = 60, unit = 'px' })))
else
table.insert(t, '|colspan=6|')
end
table.insert(t, '|}')
table.insert(t, '</div>')
return table.concat(t, '\n')
end
return p