蒙纳多研究本部
菜单
导航
首页
最近更改
随机页面
翻译查询
乐园数据管理室
送行者的收集手册
搜索
链入页面
相关更改
特殊页面
页面信息
最近更改
帮助
登录
模块
查看“︁ArtsData”︁的源代码
←
模块:ArtsData
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您必须确认您的电子邮件地址才能编辑页面。请通过
参数设置
设置并确认您的电子邮件地址。
您可以查看和复制此页面的源代码。
-- Module:ArtsData —— 战技模块 v2(主模块,XBDB 调用全部收敛于 source) local p = {} local source = require("Module:ArtsData/source") local lv1 = require("Module:ArtsData/lv1") local descs = require("Module:ArtsData/desc") local getArgs = require("Module:Arguments").getArgs local html = require("Module:Html") local compress = html.compress local ROMAN = {"I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX", "X", "XI", "XII"} local MAX_RANK = 12 local function num(v) if v == nil then return 0 end return tonumber(v) or 0 end local function fmt(v, digits) digits = digits or 2 local factor = 10 ^ digits local scaled = v * factor local rounded if scaled >= 0 then rounded = math.floor(scaled + 0.5 + 1e-9) else rounded = -math.floor(-scaled + 0.5 + 1e-9) end if digits == 0 then return tostring(rounded) end local intPart = math.floor(math.abs(rounded) / factor) local fracPart = math.abs(rounded) % factor local fracStr = string.format("%0" .. digits .. "d", fracPart) fracStr = fracStr:gsub("0+$", "") local sign = rounded < 0 and "-" or "" if fracStr == "" then return sign .. tostring(intPart) end return sign .. tostring(intPart) .. "." .. fracStr end -- atk_type=4/6 为梅莉亚元素系(召唤/释放),攻击本质是以太伤害,标"以太" -- (旧扩展无此映射故落"未知";sim 数据验证:4=元素发射+召X术 7 个,6=X元素发射 6 个) local ATK_TYPE = {[1] = "物理", [2] = "以太", [3] = "状态", [4] = "以太", [6] = "以太"} -- 灵气判定(方案 A,数据驱动):atk_type=3 且 st_type >= 206 → 自身系状态(灵气/增益) -- 低段 st_type(<206)是对敌减益(破防 18、睡眠 9 等) local function isAura(data) return num(data.atk_type) == 3 and num(data.st_type) >= 206 end -- 状态类颜色:灵气=橙、状态(对敌)=紫(MediaWiki 标准色板) local AURA_COLOR = "#e69138" local DEBUFF_COLOR = "#674ea7" -- 类型着色徽章:物理=红、以太=青、灵气=橙、状态=紫 local TYPE_COLOR = { ["物理"] = "#cc0000", ["以太"] = "#3d85c6", } local function typeBadge(atype, aura) local color = aura and AURA_COLOR or DEBUFF_COLOR if atype == "物理" then color = TYPE_COLOR["物理"] end if atype == "以太" then color = TYPE_COLOR["以太"] end return '<span style="color:' .. color .. ';font-weight:bold;">' .. atype .. "</span>" end -- 效果摘要:去标签、截断(概览表用) -- 注意:截断必须用 mw.ustring(按码点),string.sub/# 按字节会把汉字切成 -- 非法 UTF-8,导致下游 Html compress 的 gsub 报 "string is not UTF-8" local function descSummary(artId, limit) local d = descs[artId] or "" d = d:gsub("%[[^%]]*%]", "") -- 去掉 [ML:icon ...] 类标记 d = d:gsub("%s+", " ") if mw.ustring.len(d) > limit then d = mw.ustring.sub(d, 1, limit) .. "…" end return d end local function learnText(data) if num(data.get_type) == 2 then return "剧情习得" end local lv = num(data.get_lv) if lv > 0 then return "等级 " .. lv end return "初始拥有" end local function series(rank1, grow, digits, scale) scale = scale or 1 local out = {} for r = 1, MAX_RANK do out[r] = fmt((num(rank1) + (r - 1) * num(grow)) / scale, digits) end return out end local function recastSeries(data) local recast = num(data.recast) if recast == 0 then return nil end local glow = num(data.glow_recast) local out = {} for r = 1, MAX_RANK do out[r] = fmt(recast * (1 - (r - 1) * glow / 100), 1) end return out end local function dexSeries(data) local dex = num(data.dex) local out = {} for r = 1, MAX_RANK do out[r] = "+" .. tostring(dex + 5 * (r - 1)) .. "%" end return out end local function apSeries(data) local pc = num(data.pc) local idx = num(data.idx) + 1 local rateRow = lv1.grow_arts_rate[pc] if not rateRow or not rateRow[idx] then return nil end local rate = rateRow[idx] local out = {} for r = 1, MAX_RANK do out[r] = tostring(math.floor(lv1.grow_arts_base[r] * rate / 100 + 0.5)) end return out end local function row12(label, cells) local t = {"<tr><th>" .. label .. "</th>"} for r = 1, MAX_RANK do local v = cells and cells[r] or nil t[#t + 1] = "<td>" .. (v or "—") .. "</td>" end t[#t + 1] = "</tr>" return table.concat(t) end local function rowSpan(label, text) if not text or text == "" then return "" end return '<tr><th>' .. label .. '</th><td colspan="' .. MAX_RANK .. '" style="text-align:left;">' .. text .. "</td></tr>" end function p.renderArt(artId) if not source.isValidArtId(artId) then return "" end local data = source.fetchArt(artId) if not data then return "" end local name = (data.name and data.name ~= "") and data.name or source.fetchDesc(artId) or ("战技 " .. artId) local atype = ATK_TYPE[num(data.atk_type)] or "未知" local learn = learnText(data) local isTalent = num(data.arts_type) == 1 local out = {} local aura = isAura(data) -- 方向 1 改版:每技一个可折叠块(MediaWiki 原生 mw-collapsible,零 JS) -- 状态类战技名与类型按 灵气(橙)/状态(紫) 着色 local nameHtml = name if num(data.atk_type) == 3 then nameHtml = '<span style="color:' .. (aura and AURA_COLOR or DEBUFF_COLOR) .. ';">' .. name .. "</span>" end out[#out + 1] = '<table class="wikitable mw-collapsible mw-collapsed" id="art-' .. artId .. '" style="width:100%;">' -- 折叠块头部:名(状态类着色)+ 类型(元素小字缀)/习得/目标范围 -- 属性段已删(2026-10-12),元素仅攻击技且非"无"/"物理"时以小字缀在类型后 local elemText = source.elemName(data) local tgt = source.tgtName(data) local rng = source.rangeName(data) local tgtTxt = "" if tgt then tgtTxt = " · " .. tgt if rng then tgtTxt = tgtTxt .. rng end end local typeHtml = typeBadge(atype, aura) if elemText and elemText ~= "无" and elemText ~= "物理" then typeHtml = typeHtml .. '<small style="color:#777;">' .. elemText .. "</small>" end out[#out + 1] = '<tr><th style="text-align:left;">' .. nameHtml .. '<small> (' .. typeHtml .. " · " .. learn .. tgtTxt .. ")</small></th></tr>" out[#out + 1] = '<tr><td style="text-align:left;">' local head = {"<tr><th>等级</th>"} for r = 1, MAX_RANK do head[#head + 1] = "<th>" .. ROMAN[r] .. "</th>" end head[#head + 1] = "</tr>" local rows = {} rows[#rows + 1] = rowSpan("效果", descs[artId] or "") if not isTalent then rows[#rows + 1] = row12("AP 消耗", apSeries(data)) end local r1, r2 = num(data.rate1), num(data.rate2) if r2 ~= r1 then rows[#rows + 1] = row12("倍率(下限)", series(r1, data.grow_powl, 2, 100)) rows[#rows + 1] = row12("倍率(上限)", series(r2, data.grow_powh, 2, 100)) else rows[#rows + 1] = row12("倍率", series(r1, data.grow_powl, 2, 100)) end local rs = recastSeries(data) if rs then rows[#rows + 1] = row12("填充时间(秒)", rs) else rows[#rows + 1] = row12("填充时间(秒)", nil) end if num(data.st_time) ~= 0 or num(data.grow_st_time) ~= 0 then rows[#rows + 1] = row12("效果时间(秒)", series(data.st_time, data.grow_st_time, 1, 10)) end rows[#rows + 1] = row12("命中修正(决定版)", dexSeries(data)) if num(data.st_val) ~= 0 or num(data.grow_st_val) ~= 0 then rows[#rows + 1] = row12("效果数值", series(data.st_val, data.grow_st_val, 0, 1)) end out[#out + 1] = '<table class="wikitable" style="text-align:center;">' .. table.concat(head) .. table.concat(rows) .. "</table>" out[#out + 1] = "</td></tr></table>" local maxRate if r2 ~= r1 then maxRate = (r2 + 11 * num(data.grow_powh)) / 100 else maxRate = (r1 + 11 * num(data.grow_powl)) / 100 end mw.smw.subobject({ artId = artId, artName = name, artType = atype, artLearn = learn, artRate = maxRate, artRecast = num(data.recast), artDesc = descs[artId] or "", artIsTalent = isTalent and "1" or "0", artIsAura = aura and "1" or "0", artElem = source.elemName(data) or "", artTarget = source.tgtName(data) or "", artRange = source.rangeName(data) or "", artHate = num(data.hate), artChain = source.chainName(data), }) return table.concat(out, "\n") end -- 总览表:一行一技,链接到下方折叠块的锚点(id = art-<id>) -- 列:战技名(着色+锚点)/ 类型(元素小字缀)/ 习得 / 目标 / 连锁 / 仇恨 / 效果摘要 -- 属性列已删(2026-10-12):带攻击元素的技基本只有梅莉亚/力奇,单独一列性价比低, -- 元素信息压缩进类型列小字(如 以太雷),状态技 elem 非攻击属性不显示 local function renderOverview(ids) local rows = {} for _, id in ipairs(ids) do local data = source.fetchArt(id) if data then local name = (data.name and data.name ~= "") and data.name or source.fetchDesc(id) or ("战技 " .. id) local atype = ATK_TYPE[num(data.atk_type)] or "未知" local aura = isAura(data) local nameHtml = name if num(data.atk_type) == 3 then nameHtml = '<span style="color:' .. (aura and AURA_COLOR or DEBUFF_COLOR) .. ';">' .. name .. "</span>" end -- 类型列:徽章 + 元素小字缀(仅攻击技且元素非"无"时) local typeHtml = typeBadge(atype, aura) local elem = source.elemName(data) if elem and elem ~= "无" and elem ~= "物理" then typeHtml = typeHtml .. '<small style="color:#777;">' .. elem .. "</small>" end -- 目标 / 范围 / 连锁 / 仇恨 local tgt = source.tgtName(data) or "—" local rng = source.rangeName(data) if rng then tgt = tgt .. "·" .. rng end local chain = source.chainName(data) local hate = source.hateText(data) or "—" rows[#rows + 1] = "<tr>" .. '<td style="text-align:left;">[[' .. "#art-" .. id .. "|" .. nameHtml .. "]]</td>" .. "<td>" .. typeHtml .. "</td>" .. "<td>" .. learnText(data) .. "</td>" .. "<td>" .. tgt .. "</td>" .. "<td>" .. chain .. "</td>" .. "<td>" .. hate .. "</td>" .. '<td style="text-align:left;">' .. descSummary(id, 40) .. "</td>" .. "</tr>" end end if #rows == 0 then return "" end return '<table class="wikitable" style="text-align:center;">' .. "<tr><th>战技名</th><th>类型</th><th>习得</th><th>目标</th><th>连锁</th><th>仇恨</th><th>效果摘要</th></tr>" .. table.concat(rows) .. "</table>" end function p.main(frame) local args = getArgs(frame) local out = {} local first = args[1] local role = first and lv1.roles[first] or nil if role then out[#out + 1] = html.h2("总览") out[#out + 1] = renderOverview(role.ids) local talent, normal = {}, {} for _, id in ipairs(role.ids) do local data = source.fetchArt(id) local isTalent = data and num(data.arts_type) == 1 table.insert(isTalent and talent or normal, id) end if #talent > 0 then out[#out + 1] = html.h2("天赋战技") for _, id in ipairs(talent) do out[#out + 1] = p.renderArt(id) end end if #normal > 0 then out[#out + 1] = html.h2("战技") for _, id in ipairs(normal) do out[#out + 1] = p.renderArt(id) end end else for _, v in ipairs(args) do local id = tonumber(mw.text.trim(v)) if id then out[#out + 1] = p.renderArt(id) end end end if #out == 0 then return "" end return compress(table.concat(out, "\n")) end return p
该页面使用的模板:
模块:ArtsData/doc
(
查看源代码
)
返回
模块:ArtsData
。