蒙纳多研究本部
菜单
导航
首页
最近更改
随机页面
翻译查询
乐园数据管理室
送行者的收集手册
搜索
链入页面
相关更改
特殊页面
页面信息
最近更改
帮助
登录
模块
查看“︁ArtsData”︁的源代码
←
模块:ArtsData
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您必须确认您的电子邮件地址才能编辑页面。请通过
参数设置
设置并确认您的电子邮件地址。
您可以查看和复制此页面的源代码。
--[[ Module:ArtsData —— 战技页面动态化模块 用法: {{#invoke:ArtsData|main|shulk}} 按角色渲染全部战技 {{#invoke:ArtsData|main|12|13|14}} 按战技 ID 渲染 依赖子模块(必须同名创建): Module:ArtsData/static —— 角色映射 / AP 消耗 / 中文名 / 官方描述 Module:ArtsData/acquire —— 获取表数据 数据来源: * 数值(倍率/填充/命中/效果时间/效果数值)—— XBDB 实时拉取 bdat_common.pc_arts + 公式计算 * AP 消耗 / 中文名 / 官方描述 —— Module:ArtsData/static(由 XC1 DE 解包数据生成) * 类型 / 习得条件 —— pc_arts 的 atk_type / get_type / get_lv 字段 公式(已用逐级数据标定,并对 wiki 原页面逐格校验 100%): 倍率 = (rate1 + (rank-1)*grow_powl) / 100 倍率上限 = (rate2 + (rank-1)*grow_powh) / 100 仅当 rate2 ~= rate1 填充时间 = recast * (1 - (rank-1)*glow_recast/100) 秒 命中修正 = dex + 5*(rank-1) % 效果时间 = (st_time + (rank-1)*grow_st_time) / 10 秒 效果数值 = st_val + (rank-1)*grow_st_val ]] local p = {} local post = require("Module:RequestHelper").post local getArgs = require("Module:Arguments").getArgs local html = require("Module:Html") local compress = html.compress -- 子模块(若你部署的模块名不是"模块:ArtsData",请把下面两行的前缀一并改掉) local static = require("Module:ArtsData/static") local acquire = require("Module:ArtsData/acquire") 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 --[[ 数值格式化(四舍五入 + 剥离小数尾零) 注意:绝不能对整数部分做尾零剥离("50" 不能变成 "5") ]] local function fmt(v, digits) digits = digits or 2 local factor = 10 ^ digits -- 用 floor(x+0.5) 实现 ROUND_HALF_UP;先加一个小 epsilon 抵消浮点表示误差 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: 1=物理 2=以太 3=状态 local ATK_TYPE = {[1] = "物理", [2] = "以太", [3] = "状态"} -- 习得条件:get_type 1=初始/等级, 2=剧情习得 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 -- ---------- 等级序列展开 ---------- -- 通用等差序列:(rank1 + (rank-1)*grow) / scale 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 -- 填充时间:按基础冷却的百分比递减;recast=0 返回 nil(页面显示 —) 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 -- 命中修正:dex + 5*(rank-1) 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 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 -- 安全查询:XBDB 查询未注册表会抛 PHP 异常,必须包裹 local function fetchArt(artId) local ok, data = pcall(post, "bdat_common.pc_arts", artId) if not ok then mw.log("Arts: 查询失败 id=" .. tostring(artId) .. " err=" .. tostring(data)) return nil end if type(data) ~= "table" or not data.row_id then return nil end return data end -- ---------- 单战技渲染 ---------- function p.renderArt(artId) local data = fetchArt(artId) if not data then return "" end local s = static.arts[artId] or {} local name = (data.name and data.name ~= "") and data.name or s.name or ("战技 " .. artId) local atype = ATK_TYPE[num(data.atk_type)] or "未知" local learn = learnText(data) local out = {} out[#out + 1] = html.h3(name) out[#out + 1] = "'''类型''':" .. atype .. " '''习得''':" .. learn -- 表头 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("效果", s.desc or "") -- AP 消耗(天赋战技无 AP 数据时输出全 0,与原页面保持一致) do local cells = {} for r = 1, MAX_RANK do cells[r] = s.ap and tostring(s.ap[r] or 0) or "0" end rows[#rows + 1] = row12("AP 消耗", cells) 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>" -- SMW 关键字段 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.set({ artId = artId, artName = name, artType = atype, artLearn = learn, artRate = maxRate, artRecast = num(data.recast), }) return table.concat(out, "\n") end -- ---------- 获取表渲染 ---------- local ACQ_HEADER = {"战技名", "等级", "地点", "掉落", "商店", "出售", "备注"} local function renderAcquire(roleKey) local rows = acquire[roleKey] if not rows or #rows == 0 then return "" end local out = {html.h2("获取")} out[#out + 1] = '<table class="wikitable sortable">' out[#out + 1] = "<tr>" for _, h in ipairs(ACQ_HEADER) do out[#out + 1] = "<th>" .. h .. "</th>" end out[#out + 1] = "</tr>" for _, r in ipairs(rows) do out[#out + 1] = "<tr>" out[#out + 1] = "<td>" .. (r.art or "") .. "</td>" out[#out + 1] = "<td>" .. (r.level or "") .. "</td>" out[#out + 1] = "<td>" .. (r.place or "") .. "</td>" out[#out + 1] = "<td>" .. (r.drop or "") .. "</td>" out[#out + 1] = "<td>" .. (r.shop or "") .. "</td>" out[#out + 1] = "<td>" .. (r.sell or "") .. "</td>" out[#out + 1] = "<td>" .. (r.note or "") .. "</td>" out[#out + 1] = "</tr>" end out[#out + 1] = "</table>" return table.concat(out) end -- ---------- 主入口 ---------- function p.main(frame) local args = getArgs(frame) local out = {} local first = args[1] local role = first and static.roles[first] or nil if role then out[#out + 1] = "== 战技 ==" for _, id in ipairs(role.ids) do out[#out + 1] = p.renderArt(id) end -- 获取表(可通过 noacquire=1 关闭) if args.noacquire ~= "1" then out[#out + 1] = renderAcquire(first) 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
。