打开/关闭搜索
搜索
打开/关闭菜单
30
130
5
1.5K
骷髅女孩Wiki
导航
首页
最近更改
随机页面
MediaWiki帮助
特殊页面
上传文件
可选角色
菲莉亚
赛瑞贝拉
孔雀
帕娜索
幸运猫女
痛苦转轮
瓦伦汀
双形
丝瑰丽
大乐队
伊莱莎
芙库亚
贝奥武夫
机械猫女
安妮
小伞
黑色大丽花
玛丽
系统
入门问答
操纵方法
游戏界面
数据图例
启动选项
更新日志
机制
移动
进攻
防守
连段
组队
进阶
杂项
词典
术语
训练室
通知
打开/关闭个人菜单
未登录
未登录用户的IP地址会在进行任意编辑后公开展示。
user-interface-preferences
个人工具
创建账号
登录
查看“模块:FrameChart”的源代码
来自骷髅女孩Wiki
查看
阅读
查看源代码
查看历史
associated-pages
模块
讨论
更多操作
←
模块:FrameChart
因为以下原因,您没有权限编辑该页面:
您请求的操作仅限属于该用户组的用户执行:
用户
您可以查看和复制此页面的源代码。
-- FrameChart local p = {} local html local frameChartDataHtml local lineOneIndex = 1 local lineTwoIndex = 1 local lineThreeIndex = 1 local lineFourIndex = 1 local isSuperflash = false local superIndex = { l1 = 0, l2 = 0, l3 = 0, l4 = 0 } function p.drawFrameData(frame) -- 开始循环,遍历包含{startup, active, recovery}的列表 -- 对于每种帧类型,从fd中获取相应的帧数数据并存储在duration中 -- 如果frame参数中有对应的帧类型字段,使用frame:preprocess方法处理该字段值 -- _, frameKind表示,忽略迭代过程中的第一个返回值(即k,键),只关心第二个返回值(即v,值,循环变量命名为frameKind) -- inpairs保证以数组顺序(1-n)遍历数组,所以以下代码意为将frameKind依次赋值为s、a、r并进行循环体操作 for _, frameKind in ipairs({ "startup", "active", "recovery", "nsc", "linefour", "linetwo" }) do local duration if frame.args[frameKind] ~= nil then -- frame.args[frameKind]表示访问frame表中frameKind键对应的值 duration = frame:preprocess(frame.args[frameKind]) -- frame:preprocess的参数中如有MW模板或变量(如{{Var}}),会自动展开 end -- 如果duration为nil,则跳过这个帧类型 if duration == nil then -- 如果duration可以直接转化为数字,则直接赋值给frame.args[frameKind] elseif tonumber(duration) ~= nil then frame.args[frameKind] = duration -- 如果不是数字,则使用对应的解析函数解析帧数字并存储于 else local parsed = nil if frameKind == "active" then parsed = parseActive(duration) elseif frameKind == "startup" then parsed = parseStartup(duration) if string.find(duration, "+") then isSuperflash = true local i = 1 while i < 5 do superIndex['l' .. tostring(i)] = tonumber(string.match(duration, "^(%d+)%+")) i = i + 1 end end elseif frameKind == "recovery" then parsed = parseRecovery(duration) elseif frameKind == "nsc" then parsed = parseNSC(duration) elseif frameKind == "linefour" then parsed = parseLineFour(duration) elseif frameKind == "linetwo" then if frame.args[frameKind] ~= nil then parsed = parseLineTwo(duration) end end -- 如果parsed为nil,表示解析失败,报错 if parsed == nil then return string.format( '<span class="error">The number of %s frames is not a simple number (%s). Please specify explicitly.</span>', frameKind, tostring(duration)) end -- 如果解析成功,遍历解析后的表parsed,将每个字段值赋给frame.args[k] for k, v in pairs(parsed) do -- parsed格式会是{startup = s, active = a, recovery = r}的数据格式 frame.args[k] = v end end end -- 将此模块中p.drawFrameData的参数处理后输入给调用Module:MetaFrameChart的drawFrameData函数 return metaFrameData(frame) end function metaFrameData(frame) currentFrame = 0 --跟踪当前帧数的变量 html = mw.html.create('div') --mw的html方法,创造一个div标签 html:addClass('frameChart') --给这个div标签添加frameChart类 -- 如果传递的框架frame中有title参数,则将其值赋给title临时变量 local title if frame.args['title'] ~= nil then title = frame.args['title'] end -- 从传递的框架frame中获取startup、active、recovery值并赋值给同名变量 local startup = frame.args['startup'] local active = frame.args['active'] local inactive = frame.args['inactive2'] local recovery = frame.args['recovery'] local nsc = frame.args['nsc'] local spe = frame.args['spe'] local inv = frame.args['inv'] local frameAll = parseStartup(startup).startup + parseActive(active).active + parseRecovery(recovery).recovery if inactive ~= nil then local i = 2 while (frame.args['inactive' .. tostring(i)] ~= nil) do frameAll = frameAll + frame.args['inactive' .. tostring(i)] + frame.args['active' .. tostring(i + 1)] i = i + 2 end end if isSuperflash then frameAll = frameAll + 1 end local backWidth = 22 + 12 * frameAll local backWidthArg = 'width: ' .. (math.ceil((12 * frameAll - 60) / 60) * 60 + 82) .. 'px' local backBlockN = math.ceil((backWidth - 82) / 60) local scrollbarArg = 'scrollbar-color: var(--color-base) var(--color-surface-3); scrollbar-width: thin;' -- 如果提供title变量,则创建一个包含title的div标签,并添加到HTML结构中,添加frameChart-title类 if title ~= nil then html:tag('div'):addClass('frameChart-title'):wikitext(title):done() end -- 创建div标签并添加类frameChart-data,将此帧数数据容器添加到HTML主结构中 frameChartContainer = mw.html.create('div'):addClass('frameChart-back'):attr('style', scrollbarArg .. backWidthArg) :done() html:node(frameChartContainer) frameChartStrap = { frameChartStrap1, frameChartStrap2, frameChartStrap3, frameChartStrap4, frameChartStrap5, frameChartStrap6 } local frameChartStrapIndex = 1 while frameChartStrapIndex < 7 do frameChartContainer:node(mw.html.create('div'):addClass('frameChart-back-strap'):addClass( 'frameChart-back-strap-pos-' .. frameChartStrapIndex):attr('style', backWidthArg)) frameChartStrapIndex = frameChartStrapIndex + 1 end frameChartContainer:node(mw.html.create('div'):addClass('frameChart-back-block-first'):done()) local frameChartBlockIndex = 1 while frameChartBlockIndex < (backBlockN + 1) do local leftArg = 'left: ' .. (80 + 60 * (frameChartBlockIndex - 1) + 2) .. 'px' frameChartContainer:node(mw.html.create('div'):addClass('frameChart-back-block'):attr('style', leftArg)) frameChartBlockIndex = frameChartBlockIndex + 1 end frameChartContainer:node(mw.html.create('div'):addClass('frameChart-startline'):done()) frameChartBody = mw.html.create('div'):addClass('frameChart-body'):done() frameChartContainer:node(frameChartBody) frameChartDataHtml1 = mw.html.create('div'):addClass('frameChart-data'):done() frameChartBody:node(frameChartDataHtml1) -- 调用drawFrame函数,绘制第一行启动帧占位 drawFrame(startup, "placeholder", 1) if isThrow(frame.args['properties']) then drawFrame(active, "throw", 1) else drawFrame(active, "strike", 1) end -- 检查是否存在更多的非活跃帧,遍历处理,逻辑类似于上文的取消窗口 index = 2 while tonumber(frame.args['active' .. index]) ~= nil or tonumber(frame.args['inactive' .. index]) ~= nil do drawFrame(frame.args['active' .. index], "strike", 1) drawFrame(frame.args['inactive' .. index], "placeholder", 1) index = index + 1 end frameChartDataHtml2 = mw.html.create('div'):addClass('frameChart-data'):done() frameChartBody:node(frameChartDataHtml2) if isInvul(frame.args['properties']) == false and inv == nil then drawFrame(startup, "vuln", 2) drawFrame(active, "vuln", 2) index = 2 while tonumber(frame.args['active' .. index]) ~= nil or tonumber(frame.args['inactive' .. index]) ~= nil do drawFrame(frame.args['active' .. index], "vuln", 2) drawFrame(frame.args['inactive' .. index], "vuln", 2) index = index + 1 end drawFrame(recovery, "vuln", 2) else drawFrame(inv, tostring(frame.args['invtype']), 2) local invi = 2 while (frame.args['inv' .. tostring(invi)] ~= nil) do drawFrame(frame.args['inv' .. tostring(invi)], tostring(frame.args['invtype' .. tostring(invi)]), 2) invi = invi + 1 end end frameChartDataHtml3 = mw.html.create('div'):addClass('frameChart-data'):done() frameChartBody:node(frameChartDataHtml3) -- 调用drawFrame函数,绘制第一行启动帧占位 if tonumber(frame.args['nsc2']) == nil then drawFrame(nsc, "nsc", 3) else drawFrame(nsc, "placeholder", 3) -- 检查是否存在更多的非活跃帧,遍历处理,逻辑类似于上文的取消窗口 index = 2 while tonumber(frame.args['nsc' .. index]) ~= nil do drawFrame(frame.args['nsc' .. index], "nsc", 3) drawFrame(frame.args['nnsc' .. index], "placeholder", 3) index = index + 1 end end frameChartDataHtml4 = mw.html.create('div'):addClass('frameChart-data'):done() frameChartBody:node(frameChartDataHtml4) drawFrame(spe, tostring(frame.args['spetype']), 4) local spei = 2 while (frame.args['spe' .. tostring(spei)] ~= nil) do drawFrame(frame.args['spe' .. tostring(spei)], tostring(frame.args['spetype' .. tostring(spei)]), 4) spei = spei + 1 end -- 将生成的HTML结构转换为字符串,并使用定义在Module:FrameChart/styles.css中的样式渲染 return tostring(html) .. mw.getCurrentFrame():extensionTag { name = 'templatestyles', args = { src = 'Module:FrameChart/styles.css' } } end function drawFrame(frames, frameType, line) -- frames为绘制的帧数,是数字;frameType表示帧类型,如active等 if tonumber(frames) ~= nil then -- 将frames转化为数字,如果转化成功说明其为一个有效的数字字符串 for i = 1, tonumber(frames) do -- 循环从1到frames(帧数)次 local frameDataHtml = mw.html.create('div') --创建新div标签表示单个帧(小方块) if tonumber(line) == 1 then if lineOneIndex == superIndex[l1] then frameDataHtml:addClass('frame-data'):addClass('frame-data-superflash'):attr('id', 'framedata-' .. tostring(line) .. '-s'):done() superIndex[l1] = 0 else frameDataHtml:addClass('frame-data'):addClass('frame-data-' .. frameType):attr('id', 'framedata-' .. tostring(line) .. '-' .. tostring(lineOneIndex)):done() --为其添加类frame-data和类frame-data-frameType lineOneIndex = lineOneIndex + 1 end frameChartDataHtml1:node(frameDataHtml) --完成div标签列的构建并添加到frameChartDataHtml1结构中 elseif tonumber(line) == 2 then if lineTwoIndex == superIndex[l2] then frameDataHtml:addClass('frame-data'):addClass('frame-data-superflash'):attr('id', 'framedata-' .. tostring(line) .. '-s'):done() superIndex[l2] = 0 else frameDataHtml:addClass('frame-data'):addClass('frame-data-' .. frameType):attr('id', 'framedata-' .. tostring(line) .. '-' .. tostring(lineTwoIndex)):done() lineTwoIndex = lineTwoIndex + 1 end frameChartDataHtml2:node(frameDataHtml) elseif tonumber(line) == 3 then if lineThreeIndex == superIndex[l3] then frameDataHtml:addClass('frame-data'):addClass('frame-data-superflash'):attr('id', 'framedata-' .. tostring(line) .. '-s'):done() superIndex[l3] = 0 else frameDataHtml:addClass('frame-data'):addClass('frame-data-' .. frameType):attr('id', 'framedata-' .. tostring(line) .. '-' .. tostring(lineThreeIndex)):done() lineThreeIndex = lineThreeIndex + 1 end frameChartDataHtml3:node(frameDataHtml) elseif tonumber(line) == 4 then if lineFourIndex == superIndex[l4] then frameDataHtml:addClass('frame-data'):addClass('frame-data-superflash'):attr('id', 'framedata-' .. tostring(line) .. '-s'):done() superIndex[l4] = 0 else frameDataHtml:addClass('frame-data'):addClass('frame-data-' .. frameType):attr('id', 'framedata-' .. tostring(line) .. '-' .. tostring(lineFourIndex)):done() lineFourIndex = lineFourIndex + 1 end frameChartDataHtml4:node(frameDataHtml) end end end end -- 解析函数,类似MetaFrameChart模块中的功能 function parseActive(duration) -- simple number if tonumber(duration) ~= nil then return { active = tonumber(duration) } end if string.find(duration, "%d+%s*,") ~= nil then -- 1,2,3,4 format -- multihit with no gaps local totalActive = 0 -- first match - just a number local firstval, pos = string.match(duration, "^(%d+)%s*()") if firstval == nil then return nil end -- subsequent matches - coma, then number. Might have spaces between them totalActive = totalActive + tonumber(firstval) for p1, dur, p2 in string.gmatch(duration, "(),%s*(%d+)%s*()") do if pos ~= p1 then return nil end pos = p2 totalActive = totalActive + tonumber(dur) end if pos ~= string.len(duration) + 1 then return nil -- trailing stuff at the end end -- Done. local out = { active = totalActive } return out elseif mw.ustring.find(duration, "^%d+[x×]%d+$") ~= nil then -- 3x4 format -- also multihit with no gaps local a, b = mw.ustring.match(duration, "^(%d+)[x×](%d+)$") local out = { active = tonumber(a) * tonumber(b) } return out elseif string.find(duration, "^%d+%(%d+%)") ~= nil then -- 1(2)3(4)5 format -- multihit with gaps local out = {} -- special handling for the first number local firstval, pos = string.match(duration, "^(%d+)()") out['active'] = firstval local ordinal = 2 -- then we just have a groups of "(inactive)active" for p1, d1, d2, p2 in string.gmatch(duration, "()%((%d+)%)(%d+)()") do if pos ~= p1 then return nil -- not directly following the previous match, so basically not what we expect end out['inactive' .. tostring(ordinal)] = d1 out['active' .. tostring(ordinal + 1)] = d2 ordinal = ordinal + 2 pos = p2 end if pos ~= string.len(duration) + 1 then return nil -- trailing stuff at the end end -- Done. return out end -- unrecognized format return nil end function parseStartup(duration) -- simple number if tonumber(duration) ~= nil then return { startup = tonumber(duration) } end -- 1+2 -- common for supers if string.find(duration, "^%d+%+%d+$") ~= nil then local first, second = string.match(duration, "^(%d+)%+(%d+)$") return { startup = tonumber(first) + tonumber(second) } end return nil end function parseRecovery(duration) -- simple number if tonumber(duration) ~= nil then return { recovery = tonumber(duration) } end -- "Until L+10" -- aerial moves, such as grabs. if string.find(duration, "^Until L%+%d+$") ~= nil then local recovery = string.match(duration, "^Until L%+(%d+)$") return { recovery = 0, specialRecovery = recovery } end return nil end function isThrow(str) if str ~= nil then if string.find(str, "投") then if string.find(str, "对空投") then return false elseif string.find(str, "打击投") then return false else return true end else return false end end end function isInvul(str) if str ~= nil then if string.find(str, "无敌") then return true else return false end end end function parseNSC(duration) if tonumber(duration) ~= nil then return { nsc = tonumber(duration) } end if string.find(duration, "^%d+%(%d+%)") ~= nil then local out = {} local firstval, pos = string.match(duration, "^(%d+)()") out['nsc'] = firstval local ordinal = 2 for p1, d1, d2, p2 in string.gmatch(duration, "()%((%d+)%)(%d+)()") do if pos ~= p1 then return nil end out['nsc' .. tostring(ordinal)] = d1 out['nnsc' .. tostring(ordinal)] = d2 ordinal = ordinal + 1 pos = p2 end if pos ~= string.len(duration) + 1 then return nil -- trailing stuff at the end end return out end return nil end function parseLineFour(duration) local out = {} if tostring(duration) == nil then return out end local firsttype, firstval, pos = string.match(duration, "^(%a+)(%d+)()") out['spetype'] = firsttype out['spe'] = firstval if string.find(duration, ",") ~= nil then local ordinal = 2 for p1, d1, d2, p2 in string.gmatch(duration, "(),(%a+)(%d+)()") do if pos ~= p1 then return nil end out['spetype' .. tostring(ordinal)] = d1 out['spe' .. tostring(ordinal)] = d2 ordinal = ordinal + 1 pos = p2 end if pos ~= string.len(duration) + 1 then return nil end end out['spetype'] = replaceSpeAbbreviations(out['spetype']) local i = 2 while (out['spetype' .. tostring(i)] ~= nil) do out['spetype' .. tostring(i)] = replaceSpeAbbreviations(out['spetype' .. tostring(i)]) i = i + 1 end return out end function parseLineTwo(duration) local out = {} if tostring(duration) == nil then return out end local firsttype, firstval, pos = string.match(duration, "^(%a+)(%d+)()") out['invtype'] = firsttype out['inv'] = firstval if string.find(duration, ",") ~= nil then local ordinal = 2 for p1, d1, d2, p2 in string.gmatch(duration, "(),(%a+)(%d+)()") do if pos ~= p1 then return nil end out['invtype' .. tostring(ordinal)] = d1 out['inv' .. tostring(ordinal)] = d2 ordinal = ordinal + 1 pos = p2 end if pos ~= string.len(duration) + 1 then return nil end end out['invtype'] = replaceInvAbbreviations(out['invtype']) local i = 2 while (out['invtype' .. tostring(i)] ~= nil) do out['invtype' .. tostring(i)] = replaceInvAbbreviations(out['invtype' .. tostring(i)]) i = i + 1 end return out end function replaceInvAbbreviations(field) if field ~= nil then if string.find(field, "ph") ~= nil then field = string.gsub(field, "ph", "placeholder") end if string.find(field, "vul") ~= nil then field = string.gsub(field, "vul", "vuln") end if string.find(field, "ful") ~= nil then field = string.gsub(field, "ful", "invuln-full") end if string.find(field, "stk") ~= nil then field = string.gsub(field, "stk", "invuln-strike") end if string.find(field, "thr") ~= nil then field = string.gsub(field, "thr", "invuln-throw") end if string.find(field, "pro") ~= nil then field = string.gsub(field, "pro", "invuln-proj") end end return field end function replaceSpeAbbreviations(field) if field ~= nil then if string.find(field, "ph") ~= nil then field = string.gsub(field, "ph", "placeholder") end if string.find(field, "arm") ~= nil then field = string.gsub(field, "arm", "armor") end if string.find(field, "hyp") ~= nil then field = string.gsub(field, "hyp", "hyperarmor") end if string.find(field, "pro") ~= nil then field = string.gsub(field, "pro", "hyperarmor-proj") end if string.find(field, "hat") ~= nil then field = string.gsub(field, "hat", "hatredguard") end if string.find(field, "noc") ~= nil then field = string.gsub(field, "noc", "nocollision") end if string.find(field, "nwh") ~= nil then field = string.gsub(field, "nwh", "nocollision-when-hit") end end return field end p.drawFrame = drawFrame return p
该页面使用的模板:
模块:FrameChart/doc
(
查看源代码
)
返回
模块:FrameChart
。