本模块生成明日方舟的“范围”图示。main 的语法参见Template:Akrange;legacy 仅用于兼容Template:明日方舟:攻击范围。可以用 stringFromLegacy 从旧语法生成新语法的描述字符串。
-- This is an attempt to create a simpler way to build Arknights' "attack" -- range. It requires one string input to describe the mapping of the range. -- It generates a CSS grid instance for graphical output. -- Crappy code originally by One-Six(U:公的驱逐舰), released under CC BY 4.0. -- Gotta Praise the Crocc. local getArgs = require('Module:Arguments').getArgs local p = {} -- Interpret input string and break it into a 2D array local function interpret ( s ) local dataTable = {} local i = 1 local j = 1 dataTable[1] = {} -- Ignore newline at end of description string, -- then break string into individual char. for c in string.gmatch(s:gsub("n+$",""),".") do -- 'e' marks end of center row for symmetrical ranges. -- Generate the mirror and then break. if (c == 'e') then local iBar = i while (i > 1) do iBar = iBar + 1 i = i - 1 dataTable[iBar] = dataTable[i] end break -- 'n' marks end of row. Create the next row. elseif (c == 'n') then i = i + 1 j = 1 dataTable[i] = {} -- Not control char; add char to array and point to next var. else dataTable[i][j] = c j = j + 1 end end j = nil -- Check for longest row. -- If rows are not all of the same length, mark for space padding. i = 1 local maxWidth = #dataTable[1] local needSpacePadding = false while (dataTable[i] ~= nil) do if (#dataTable[i] > maxWidth) then maxWidth = #dataTable[i] needSpacePadding = true elseif ( (not needSpacePadding) and #dataTable[i] < maxWidth) then needSpacePadding = true end i = i + 1 end -- Space padding. i = 1 while (needSpacePadding and dataTable[i] ~= nil) do local length = #dataTable[i] for j = #dataTable[i] + 1, maxWidth do dataTable[i][j] = 'o' end i = i + 1 end return dataTable end -- Generate grid from parsed data table local function genGrid ( dataTable, sty, clr ) local style = sty local color = clr if (style == nil) then style = '' end if (color == nil or color == '') then color = "#808080" end -- prep output string and gridTemplateArea. local outputString = '' local gridTemplateArea = '' for i = 1, #dataTable do gridTemplateArea = gridTemplateArea .. [[ "]] for j = 1, #dataTable[i] do -- make gridTemplateArea gridTemplateArea = gridTemplateArea .. [[. ]] -- self: solid box if (dataTable[i][j] == 's') then outputString = outputString..'<div style="box-sizing:border-box;width:15px;height:15px;background-color:'..color..';"></div>' -- range: hollow box elseif (dataTable[i][j] == 'x') then outputString = outputString..'<div style="box-sizing:border-box;width:15px;height:15px;border:2px solid '..color..';"></div>' -- space: placeholder box elseif (dataTable[i][j] == 'o') then outputString = outputString..'<div style="box-sizing:border-box;width:15px;height:15px;"></div>' -- illegal input: warning box else outputString = outputString..'<div title="模块:Akrange 的警告:格式字符串包含不合法的值“'..dataTable[i][j]..'”。" style="box-sizing:border-box;text-align:center;font-size:12px;line-height:12px;padding:1.5px 0;width:15px;height:15px;color:#fff;background-color:#d44;">'..dataTable[i][j]..'</div>' end end gridTemplateArea = gridTemplateArea:sub(1, -2) .. [["]] end --return output (after closing the <div>) return [[<div class='ak-range-container' style='display:grid;grid-gap:2px;margin:5px;width:]]..(17 * #dataTable[1] - 2)..[[px;height:]]..(17 * #dataTable - 2)..[[px;grid-template-areas:]]..gridTemplateArea..[[;]]..style..[['>]]..outputString..[[</div>]] end -- Get and return grid from from raw description string function p.main ( frame ) local args = getArgs(frame, { wrappers = { 'Template:Akrange', 'Template:沙盒' } }) return p._main ( args ) end function p._main ( args ) return genGrid( interpret( args[1] ), args["style"], args["color"] ) end -- get and return raw description string from legacy data function p.stringFromLegacy ( frame ) local args = getArgs(frame, { wrappers = { 'Template:Akrange', 'Template:沙盒', 'Template:明日方舟:攻击范围' } }) return p._stringFromLegacy ( args ) end function p._stringFromLegacy ( args ) local dataString = "" local mr = tonumber(args["r"]) local mc = tonumber(args["c"]) local x = tonumber(args["x"]) local y = tonumber(args["y"]) local b = tonumber(args["broken"]) if b == '' or b == nil then b = 0 end if mr%2 == 1 and x == (mr+1)/2 then for r = 1, x do for c = 1, mc do if ( r == 1 and c > (mc - b) and c ~= 1 ) then break elseif (r == x and c == y) then dataString = dataString..'s' else dataString = dataString..'x' end end if r == x then dataString = dataString..'e'; else dataString = dataString..'n'; end end else for r = 1, mr do for c = 1, mc do if ( (r == 1 or r == mr) and c > (mc - b) and c ~= 1 ) then break elseif (r == x and c == y) then dataString = dataString..'s' else dataString = dataString..'x' end end dataString = dataString..'n'; end end return dataString end -- Get and return grid from legacy data function p.legacy ( frame ) local args = getArgs(frame, { wrappers = { 'Template:Akrange', 'Template:沙盒', 'Template:明日方舟:攻击范围' } }) return p._legacy ( args ) end function p._legacy ( args ) return genGrid( interpret( p._stringFromLegacy ( args ) ), args["style"], args["color"] ) end -- Return all legal chars in description string in string form function p.legalChar ( frame ) return 'oxsne' end return p