置顶公告:【置顶】关于临时开启评论区所有功能的公告(2022.10.22) | 【置顶】关于本站Widget恢复使用的公告
  • 你好~!欢迎来到萌娘百科镜像站!如需查看或编辑,请联系本站管理员注册账号。
  • 本镜像站和其他萌娘百科的镜像站无关,请注意分别。

Module:Akopbasics/canary

贴贴♀百科,万娘皆可贴的百科全书!转载请标注来源页面的网页链接,并声明引自贴贴百科。内容不可商用。
跳到导航 跳到搜索
  1. -- This is the canary version of M:Akopbasics. New versions are tested here before copy-paste
  2. -- deployment to M:Akopbasics.
  3. -- This Module should never be called in T:明日方舟干员 save for preview tests. Deployment tests
  4. -- should use T:明日方舟干员/canary instead.
  5. -- Long-term TODO: modulize T:Tabs and T:雷达图; clear this module of HTML generation
  6. -- Crappy code originally by U:公的驱逐舰 (One-Six) of Moegirlpedia. Released under CC BY 4.0.
  7. -- Gotta praise the Crocc.
  8. local p = {}
  9. local getArgs = require ( 'Module:Arguments' ).getArgs
  10. local getSabunArray = require ( 'Module:Aksabun' )._getSabunArray
  11. local akMatData = require ( 'Module:明日方舟材料' )._skill
  12. local genOpComplex = require ( 'Module:Akopbasics/canary/genwikitext' ).genOpComplex
  13. local wrapperArray = { 'Template:明日方舟干员', 'Template:明日方舟干员/canary', 'Template:沙盒' }
  14. -- F: is string empty?
  15. local function isEmpty( s )
  16. return (s == nil or s == '')
  17. end
  18. -- F: get arguments, alias-aware. Aliases towards the front of the array have priority.
  19. local function getArgFromAlias ( args, argsAliasArray, defaultReturn )
  20. for i = 1, #argsAliasArray do
  21. if ( args[argsAliasArray[i]] ~= nil ) then
  22. return args[argsAliasArray[i]]
  23. end
  24. end
  25. return defaultReturn
  26. end
  27. -- F: same as getArgFromAlias, but will also ignore empty strings. Default return is still nil, check compatibility.
  28. local function getNonEmptyArgs ( args, argsAliasArray, defaultReturn )
  29. for i = 1, #argsAliasArray do
  30. if ( not isEmpty( args[argsAliasArray[i]] ) ) then
  31. return args[argsAliasArray[i]]
  32. end
  33. end
  34. return defaultReturn
  35. end
  36. -- F: generate parameter array from string; insert a common string for each instance
  37. local function parseArray ( s, ins )
  38. -- When input string is entirely empty, return empty array.
  39. if ( isEmpty(s) ) then
  40. return {}
  41. end
  42. -- if common string is empty, make damn sure it's empty, not nil
  43. if ( isEmpty(ins) ) then
  44. ins = ''
  45. end
  46. local parsedArray = {}
  47. -- \239\188\155 是UTF-8全角分号(";")
  48. for temp in (s:gsub("\239\188\155",";"):gsub("[;]?%s*$",";") ):gmatch("([^;]*);%s*") do
  49. local tempArray = {}
  50. -- \227\128\129 是UTF-8顿号("、")
  51. for w in (temp:gsub("\227\128\129","\\"):gsub("[\\]?%s*$","\\")..ins):gmatch("([^\\]*)\\%s*") do
  52. tempArray[#tempArray+1] = w
  53. end
  54. parsedArray[#parsedArray+1] = tempArray
  55. end
  56. return parsedArray
  57. end
  58. -- F: generate datatable for genOpComplex.
  59. local function genData ( frame, args, opType )
  60. local d = {}
  61. -- expected components
  62. d.name = getArgFromAlias ( args, { "name", "中文名" } ) -- MUST BE PROVIDED BY USER
  63. d.dataName = getArgFromAlias ( args, { "data-name", "数据名" }, d.name )
  64. d.rarity = getArgFromAlias ( args, { "rarity", "稀有度" }, '' )
  65. d.rarity = tonumber( d.rarity ) or #d.rarity/3
  66. d.profession = getArgFromAlias ( args, { "profession","职业" } )
  67. d.placementTag = getArgFromAlias ( args, { "placement-tag","位置标签","站位" } )
  68. if isEmpty(d.placementTag) then
  69. if d.profession == "狙击" or d.profession == "术师" or d.profession == "医疗" or d.profession == "辅助" then
  70. placementTag = '远程位'
  71. elseif d.profession == "先锋" or d.profession == "近卫" or d.profession == "重装" then
  72. d.placementTag = "近战位"
  73. end
  74. end
  75. -- the radarPPS monstrosity
  76. local radarText = {
  77. "物理强度",
  78. "战场机动",
  79. "生理耐受",
  80. "战术规划",
  81. "战斗技巧",
  82. "源石<br />技艺<br />适应性"
  83. }
  84. local radarTextOffset = {"-32px","-24px"}
  85. local radarNumText = {}
  86. local radarNum = {}
  87. local radarLookup = {
  88. [""] = 0,
  89. ["N/A"] = 0,
  90. ["---"] = 0,
  91. ["缺陷"] = 20,
  92. ["普通"] = 40,
  93. ["标准"] = 60,
  94. ["优良"] = 80,
  95. ["卓越"] = 100
  96. }
  97. local isRobot = ( string.lower( opType or '' ) == "robot" )
  98. if isRobot then
  99. radarText = {
  100. "最高速度",
  101. "爬坡能力",
  102. "制动性能",
  103. "通过性",
  104. "续航",
  105. "结构<br />稳定性"
  106. }
  107. radarTextOffset = {"-24px","-10px"}
  108. radarNumText[1] = getNonEmptyArgs ( args, { "radar-text1","雷达图文字1", "最高速度"},"---" ):gsub("([Kk][Mm]/[Hh])?$","km/h")
  109. local speed = radarNumText[1]:gsub("[^0-9%.]*","" )
  110. speed = tonumber( speed ~= '' and speed or 0 )
  111. radarNum[1] = tonumber( getNonEmptyArgs ( args, { "radar-num1","雷达图数值1", "最高速度数值"} ) ) or math.log(speed+1)*12.47+speed
  112. radarNumText[6] = getNonEmptyArgs ( args, { "radar-text6","雷达图文字6","结构稳定性" },"---" )
  113. radarNum[6] = tonumber( getNonEmptyArgs ( args, { "radar-num"..6,"雷达图数值"..6, "结构稳定性数值"} ) ) or radarLookup[radarNumText[6]]
  114. else
  115. radarNumText[1] = getNonEmptyArgs ( args, { "radar-text1","雷达图文字1", "物理强度"},"---" )
  116. radarNum[1] = tonumber( getNonEmptyArgs ( args, { "radar-num1","雷达图数值1", "物理强度数值"} ) ) or radarLookup[radarNumText[1]]
  117. radarNumText[6] = getNonEmptyArgs ( args, { "radar-text6","雷达图文字6","源石技艺适应性" },"---" )
  118. radarNum[6] = tonumber( getNonEmptyArgs ( args, { "radar-num6","雷达图数值6","源石技艺适应性数值"} ) ) or radarLookup[radarNumText[6]]
  119. end
  120. for i = 2, 5 do
  121. radarNumText[i] = getNonEmptyArgs ( args, { "radar-text"..i,"雷达图文字"..i,radarText[i] },"---" )
  122. radarNum[i] = tonumber( getNonEmptyArgs ( args, { "radar-num"..i,"雷达图数值"..i, radarText[i].."数值"} ) ) or radarLookup[radarNumText[i]]
  123. end
  124. local radarString = '{{雷达图|size=100'
  125. radarString = radarString .. '|text1=<span class="aoc-radar-cat-text" style="display:inline-block;position:absolute;width:60px;left:-12px;font-size:14px;">'..radarText[1]..'</span>'
  126. radarString = radarString .. '|var1='..radarNum[1]
  127. radarString = radarString .. '|num1=<span style="display:inline-block;position:absolute;text-align: center;width:max-content;left:6px;top:12px;transform:translateX(-50%);background-color:rgba(255,255,255,0.3);border-radius:5px;font-size:14px;">'..radarNumText[1]..'</span>'
  128. radarString = radarString .. '|text2=<span class="aoc-radar-cat-text" style="display:inline-block;position:absolute;width:30px;left:-30px;top:-10px;font-size:14px;">'..radarText[2]..'</span>'
  129. radarString = radarString .. '|var2='..radarNum[2]
  130. radarString = radarString .. '|num2=<span style="display:inline-block;position:absolute;text-align: center;width:30px;left:-35px;top:5px;background-color:rgba(255,255,255,0.3);border-radius:5px;font-size:14px;">'..radarNumText[2]..'</span>'
  131. radarString = radarString .. '|text3=<span class="aoc-radar-cat-text" style="display:inline-block;position:absolute;width:30px;left:-30px;top:-32px;font-size:14px;">'..radarText[3]..'</span>'
  132. radarString = radarString .. '|var3='..radarNum[3]
  133. radarString = radarString .. '|num3=<span style="display:inline-block;position:absolute;width:30px;left:-35px;top:-27px;background-color:rgba(255,255,255,0.3);border-radius:5px;font-size:14px;">'..radarNumText[3]..'</span>'
  134. radarString = radarString .. '|text4=<span class="aoc-radar-cat-text" style="display:inline-block;position:absolute;text-align: center;width:60px;left:-12px;top:-20px;font-size:14px;">'..radarText[4]..'</span>'
  135. radarString = radarString .. '|var4='..radarNum[4]
  136. radarString = radarString .. '|num4=<span style="display:inline-block;position:absolute;text-align: center;width:30px;left:-7px;top:-35px;background-color:rgba(255,255,255,0.3);border-radius:5px;font-size:14px;">'..radarNumText[4]..'</span>'
  137. radarString = radarString .. '|text5=<span class="aoc-radar-cat-text" style="display:inline-block;position:absolute;width:30px;top:'..radarTextOffset[1]..';font-size:14px;">'..radarText[5]..'</span>'
  138. radarString = radarString .. '|var5='..radarNum[5]
  139. radarString = radarString .. '|num5=<span style="display:inline-block;position:absolute;text-align: center;width:30px;left:5px;top:-27px;background-color:rgba(255,255,255,0.3);border-radius:5px;font-size:14px;">'..radarNumText[5]..'</span>'
  140. radarString = radarString .. '|text6=<span class="aoc-radar-cat-text" style="display:inline-block;position:absolute;width:45px;left:-15px;top:'..radarTextOffset[2]..';text-align:center;font-size:14px;">'..radarText[6]..'</span>'
  141. radarString = radarString .. '|var6='..radarNum[6]
  142. radarString = radarString .. '|num6=<span style="display:inline-block;position:absolute;text-align: center;width:30px;left:5px;top:5px;background-color:rgba(255,255,255,0.3);border-radius:5px;font-size:14px;">'..radarNumText[6]..'</span>'
  143. radarString = radarString .. '|color=#999|bgcolor=#333|ftcolor=#000|numcolor=white|num=}}'
  144. d.radarPPS = frame:preprocess( radarString )
  145. radarString = nil
  146. radarText = nil
  147. radarTextOffset = nil
  148. radarNumText = nil
  149. radarNum = nil
  150. radarLookup = nil
  151. -- optional components
  152. d.categoryArray = {}
  153. d.enName = getArgFromAlias ( args, { "en-name", "英文名" } )
  154. d.subProfession = getArgFromAlias ( args, { "sub-profession", "branch", "分支", "characterbranch" } )
  155. d.operatorModule = getArgFromAlias ( args, { "operatorModule", "模组", "characterequipt" } )
  156. d.altOpOverride = getArgFromAlias ( args, { "alt-op-override", "spcharacter", "异格任务" } )
  157. d.spIllustrator = getNonEmptyArgs ( args, { "spIllustrator", "multi-illustrator", "特殊画师", "多位画师" }, nil )
  158. if d.spIllustrator == nil then
  159. d.illustrator = parseArray ( getNonEmptyArgs ( args, { "illustrator", "illust", "画师" } ) )
  160. mw.logObject(d.illustrator)
  161. if isEmpty ( d.illustrator[1] ) then
  162. d.illustrator = nil
  163. d.spIllustrator = '无资料'
  164. else
  165. local i = 1
  166. while not isEmpty ( d.illustrator[i] ) do
  167. if d.illustrator[i][3] == "FORCENOLINK" then
  168. d.illustrator[i][3] = nil
  169. d.illustrator[i]["nolink"] = true
  170. end
  171. i=i+1
  172. end
  173. end
  174. end
  175. d.spcv = getNonEmptyArgs ( args, { "spcv", "multi-cv", "特殊配音", "多位配音" }, nil )
  176. if d.spcv == nil then
  177. d.cv = parseArray ( getNonEmptyArgs ( args, { "cv","配音" } ) )
  178. mw.logObject(d.cv)
  179. if isEmpty ( d.cv[1] ) then
  180. d.cv = nil
  181. d.spcv = '无资料'
  182. else
  183. -- add CV name(s) into category array. TODO: remove category processing
  184. local i = 1
  185. while not isEmpty ( d.cv[i] ) do
  186. if d.cv[i][3] == "FORCENOLINK" then
  187. d.cv[i][3] = nil
  188. d.cv[i]["nolink"] = true
  189. end
  190. d.categoryArray[#d.categoryArray+1] = d.cv[i][1]
  191. i = i + 1
  192. end
  193. end
  194. end
  195. -- tachie array
  196. local tachieInfo = {
  197. getNonEmptyArgs( args, { "e0name", "初始名" }, "初始"),
  198. getNonEmptyArgs( args, { "e0img", "初始图" }, '明日方舟立绘_' .. d.name .. '_1.png' ),
  199. getNonEmptyArgs( args, { "e1name", "精一名", "精1名" }, "精英一"),
  200. getNonEmptyArgs( args, { "e1img", "精一图", "精1图" }, '明日方舟立绘_' .. d.name .. '_1+.png' ),
  201. getNonEmptyArgs( args, { "e2name", "精二名", "精2名" }, "精英二"),
  202. getNonEmptyArgs( args, { "e2img", "精二图", "精2图" }, '明日方舟立绘_' .. d.name .. '_2.png' )
  203. }
  204. d.tachieArray = {}
  205. -- All operators have E0 state and E0 tachie's. Generate unless explicitly disabled.
  206. if tachieInfo[1] ~= "FORCENOTAB" then
  207. d.tachieArray[#d.tachieArray+1] = { label = tachieInfo[1], file = tachieInfo[2] }
  208. end
  209. -- Amiya is the only operator right now that possesses E1 tachie; treat as special case, generate unless explicitly disabled.
  210. if d.name == '阿米娅' and tachieInfo[3] ~= "FORCENOTAB" then
  211. d.tachieArray[#d.tachieArray+1] = { label = tachieInfo[3], file = tachieInfo[4] }
  212. end
  213. -- All 4star+ operators have E2 states and E2 tachie's. Generate unless explicitly disabled.
  214. if d.rarity > 3 and tachieInfo[5] ~= "FORCENOTAB" then
  215. d.tachieArray[#d.tachieArray+1] = { label = tachieInfo[5], file = tachieInfo[6] }
  216. end
  217. tachieInfo = nil
  218. -- skins.
  219. local skinArray = parseArray ( getArgFromAlias ( args, { "skins","skin","时装","服装" } ) )
  220. for i = 1, #skinArray do
  221. -- if no explicit skin filename is provided, generate filename according to naming customs.
  222. if isEmpty(skinArray[i][2]) then
  223. skinArray[i][2] = '明日方舟立绘_'..d.name..'_skin'..i..'.png'
  224. end
  225. -- attach skin array.
  226. d.tachieArray[#d.tachieArray+1] = { label = skinArray[i][1], file = skinArray[i][2] }
  227. end
  228. skinArray = nil
  229. -- sabun's. TODO: offload work to new M:Aksabun (WIP)
  230. d.sabunArray = {}
  231. local sabunType = getArgFromAlias ( args, { "sabun-type","差分类型","sabun-type1","差分类型1" } )
  232. local sabunCode = getArgFromAlias ( args, { "sabun-code","差分代号","sabun-code1","差分代号1" } )
  233. local manualSabun = getArgFromAlias ( args, { "manual-sabun1","手动差分1" } )
  234. i = 1
  235. while ( ( not isEmpty( sabunCode ) ) or ( not isEmpty( manualSabun ) ) ) do
  236. sabunType = ( sabunType == 'npc' or sabunType == 'avg_npc' ) and 'avg_npc' or 'char'
  237. d.sabunArray[#d.sabunArray+1] = getSabunArray ( frame, {
  238. verbose = manualSabun,
  239. ["suffix-list"] = getArgFromAlias ( args, { "sabun-suffix"..i, "差分后缀"..i } ),
  240. ["sabun-type"] = sabunType,
  241. ["sabun-code"] = sabunCode,
  242. separator = getArgFromAlias ( args, { "sabun-sep"..i, "差分分隔"..i } ),
  243. first = getArgFromAlias ( args, { "sabun-f"..i, "差分首"..i } ),
  244. last = getArgFromAlias ( args, { "sabun-l"..i, "差分末"..i } ),
  245. omit = getArgFromAlias ( args, { "sabun-omit"..i, "差分忽略"..i } )
  246. } )
  247. i = i + 1
  248. sabunType = getArgFromAlias ( args, { ("sabun-type"..i),("差分类型"..i) } )
  249. sabunCode = getArgFromAlias ( args, { ("sabun-code"..i),("差分代号"..i) } )
  250. manualSabun = getArgFromAlias ( args, { "manual-sabun"..i,"手动差分"..i } )
  251. end
  252. sabunType = nil
  253. sabunCode = nil
  254. manualSabun = nil
  255. -- other tachie. This includes lone AVG tachie's, tachie of related sub-characters/objects (e.g. summons, pets...), etc.
  256. d.otherTachie = parseArray ( getArgFromAlias ( args, { "other-tachie","其他立绘" } ) )
  257. for i = 1, #d.otherTachie do
  258. d.otherTachie[i] = d.otherTachie[i][1]
  259. end
  260. d.faction = getNonEmptyArgs ( args, { "faction","势力" }, "罗德岛" )
  261. d.factionImgPath = frame:callParserFunction('filepath:Aklogo_'..d.faction..'.png')
  262. -- main game data.
  263. d.data = {
  264. maxHealth = getNonEmptyArgs ( args, { "max-health","生命上限" }, '暂无数据' ),
  265. attack = getNonEmptyArgs ( args, { "attack","atk","攻击" }, '暂无数据' ),
  266. defense = getNonEmptyArgs ( args, { "defense","def","防御" }, '暂无数据' ),
  267. artsResistance = getNonEmptyArgs ( args, { "arts-resist","法术抗性" }, '暂无数据' ),
  268. redeploy = getNonEmptyArgs ( args, { "redeploy","再部署" }, '暂无数据' ),
  269. cost = getNonEmptyArgs ( args, { "cost","部署费用" }, '暂无数据' ),
  270. block = getNonEmptyArgs ( args, { "block","阻挡数" }, '暂无数据' ),
  271. attackInterval = getNonEmptyArgs ( args, { "atk-int","攻击速度" }, '暂无数据' )
  272. }
  273. -- range. Must use Akrange-compatible descrpition strings.
  274. d.rangeArray = { { label = 'E0', rangeString = getArgFromAlias ( args, { "E0range","初始范围" } ) } }
  275. if not isEmpty(getArgFromAlias ( args, { "E1range","精一范围","精1范围" } )) then
  276. d.rangeArray[#d.rangeArray+1] = { label = 'E1', rangeString = getArgFromAlias ( args, { "E1range","精一范围","精1范围" } ) }
  277. end
  278. if not isEmpty(getArgFromAlias ( args, { "E2range","精二范围","精2范围" } )) then
  279. d.rangeArray[#d.rangeArray+1] = { label = 'E2', rangeString = getArgFromAlias ( args, { "E2range","精二范围","精2范围" } ) }
  280. end
  281. if not isEmpty(getArgFromAlias ( args, { "modulerange","模组范围","模组范围" } )) then
  282. d.rangeArray[#d.rangeArray+1] = { label = '模组', rangeString = getArgFromAlias ( args, { "modulerange","模组范围","模组范围" } ) }
  283. end
  284. -- potential buffs.
  285. d.potentialBuffArray = {}
  286. -- get raw potential. if it actually exists, then make Lookup table.
  287. local rawPotential = getArgFromAlias ( args, { "potential","潜能" } )
  288. if rawPotential then
  289. local potentialNameLookup = {
  290. ["n/a"] = false, ["false"] = false, [""] = false, [" "] = false, ["nil"] = false,
  291. ["生命上限"] = "生命", ["生命"] = "生命", ["health"] = "生命", ["hp"] = "生命",
  292. ["攻击力"] = "攻击", ["攻击"] = "攻击", ["attack"] = "攻击", ["atk"] = "攻击",
  293. ["防御力"] = "防御", ["防御"] = "防御", ["defense"] = "防御", ["def"] = "生命",
  294. ["法术抗性"] = "法抗", ["法抗"] = "法抗", ["arts-resist"] = "法抗", ["ar"] = "法抗",
  295. ["再部署时间"]="再部署",["再部署"]="再部署", ["redeploy"]="再部署",
  296. ["部署费用"] = "费用", ["费用"] = "费用", ["cost"] = "费用",
  297. ["阻挡数"] = "阻挡", ["阻挡"] = "阻挡", ["block"] = "阻挡",
  298. ["攻击速度"] = "攻速", ["攻速"] = "攻速", ["atk-int"]= "攻速",
  299. ["天赋"] = "天赋", ["talent"] = "天赋",
  300. ["第一天赋"] ="天赋一", ["天赋一"]="天赋一", ["talent1"]= "天赋一",
  301. ["第二天赋"] ="天赋二", ["天赋二"]="天赋二", ["talent2"]= "天赋二"
  302. }
  303. -- parse raw potential.
  304. d.orderedPotentialBuffArray = {}
  305. -- \239\188\155 是UTF-8全角分号(";")
  306. i = 1
  307. for item in (rawPotential:gsub("\239\188\155",";"):gsub("[;]?%s*$",";") ):gmatch("([^;]*);%s*") do
  308. -- \227\128\129 是UTF-8顿号("、")
  309. local tempArray = {}
  310. for w in (item:gsub("\227\128\129","\\"):gsub("[\\]?%s*$","\\")):gmatch("([^\\]*)\\%s*") do
  311. tempArray[#tempArray+1] = string.lower( w )
  312. end
  313. d.orderedPotentialBuffArray[i] = {}
  314. d.orderedPotentialBuffArray[i][1] = potentialNameLookup[ tostring ( tempArray[1] ) ]
  315. if d.orderedPotentialBuffArray[i][1] then
  316. d.orderedPotentialBuffArray[i][2] = tempArray[2]
  317. -- remove "秒" and non-number-nor-sign characters
  318. local temp = tempArray[2]:gsub('\xe7\xa7\x92$',''):gsub('[^%d+-]','')
  319. temp = tonumber( temp )
  320. if temp then d.potentialBuffArray[ d.orderedPotentialBuffArray[i][1] ] = ( d.potentialBuffArray[ d.orderedPotentialBuffArray[i][1] ] or 0 ) + temp end
  321. end
  322. i = i + 1
  323. end
  324. -- if provided potential buff is less then 5, fill the rest with emtpy array
  325. while i <= 5 do
  326. d.orderedPotentialBuffArray[i] = {}
  327. i = i + 1
  328. end
  329. rawPotential = nil
  330. -- provide plus sign
  331. for k,v in pairs(d.potentialBuffArray) do
  332. if v > 0 then d.potentialBuffArray[k] = '+'..v end
  333. end
  334. end
  335. -- tag-characteristic-talent
  336. d.tags = getArgFromAlias ( args, { "tags","标签" }, '' )
  337. d.characteristic = getNonEmptyArgs ( args, { "characteristic","特性" }, '暂无资料' )
  338. d.talent = getArgFromAlias ( args, { "talent","天赋"}, '' )
  339. if d.talent == '' then
  340. local talentComponent = getNonEmptyArgs ( args, { "talent1","天赋1"} )
  341. if talentComponent ~= nil then
  342. d.talent = talentComponent
  343. talentComponent = getNonEmptyArgs ( args, { "talent2","天赋2"} )
  344. i = 2
  345. while talentComponent do
  346. d.talent = d.talent .. '<hr />' .. talentComponent
  347. i = i + 1
  348. talentComponent = getNonEmptyArgs ( args, { "talent"..i,"天赋1"..i} )
  349. end
  350. else
  351. d.talent = '暂无资料'
  352. end
  353. end
  354. d.talent = d.talent:gsub('%<%/talent%>','</span>'):gsub('%<talent%>','<span class="talentblock">')
  355. -- rouge stuff
  356. local rogueOnlyRaw = string.lower ( getArgFromAlias ( args, { 'rogue-only', '肉鸽限定' }, '' ) )
  357. d.isRogueOnly = ( rogueOnlyRaw == "true" or rogueOnlyRaw == "yes" or rogueOnlyRaw == "是" or rogueOnlyRaw == "was" or rogueOnlyRaw == "曾" )
  358. d.wasRogueOnly = ( rogueOnlyRaw == "was" or rogueOnlyRaw == "曾" )
  359. rogueOnlyRaw = nil
  360. d.rogueEvents = getNonEmptyArgs ( args, { 'rogue-events', 'rogue-event', '肉鸽活动' } )
  361. -- skills and related material consumptions
  362. d.skillArray = {}
  363. d.skillArray.useSwitch = string.lower( getArgFromAlias ( args, { 'skill-switch', '技能切换' }, '' ) )
  364. d.skillArray.useSwitch = not ( d.skillArray.useSwitch == "false" or d.skillArray.useSwitch == "no" or d.skillArray.useSwitch == "否" )
  365. d.skillArray.useItem = string.lower( getArgFromAlias ( args, { 'display-item', '显示材料' }, '' ) )
  366. d.skillArray.useItem = not ( d.skillArray.useItem == "false" or d.skillArray.useItem == "no" or d.skillArray.useItem == "否" )
  367. local possibleSkillDesp = getArgFromAlias ( args, { "sk1", "技能1", "技能一" } )
  368. local i = 1
  369. local skillLookup = { '一', '二', '三', '' } -- need an extra item so skillLookup[i+1] after the last item is exhausted wouldn't throw err
  370. while possibleSkillDesp ~= nil and i <= #skillLookup - 1 do
  371. local tabString = ( d.skillArray.useItem and d.rarity >= 4 ) and frame:preprocess( "{{tabs|color=black aoc-skill-masterTabs|DefaultTab=1|AutoWidth=yes"
  372. ..'|bt1=专精一|tab1=[[File:明日方舟技能专精 1.png|50px|link=]]' .. akMatData ( frame, { d.dataName, 'v'..i..'7' } )
  373. ..'|bt2=专精二|tab2=[[File:明日方舟技能专精 2.png|50px|link=]]' .. akMatData ( frame, { d.dataName, 'v'..i..'8' } )
  374. ..'|bt3=专精三|tab3=[[File:明日方舟技能专精 3.png|50px|link=]]' .. akMatData ( frame, { d.dataName, 'v'..i..'9' } )..'}}'
  375. ) or ''
  376. d.skillArray[i] = {
  377. skillName = getArgFromAlias ( args, { ('sk'..i..'name'), ('技能'..i..'名称'), ('技能'..skillLookup[i]..'名称') } ),
  378. activation = getArgFromAlias ( args, { "sk"..i.."a", "技能"..i.."触发", "技能"..skillLookup[i].."触发" }, ''),
  379. skillPoint = getArgFromAlias ( args, { "sk"..i.."sp", "技能"..i.."技力", "技能"..skillLookup[i].."技力" }, ''),
  380. description = possibleSkillDesp,
  381. masterTabsPPS = tabString
  382. }
  383. d.skillArray[i].icon = getArgFromAlias ( args, { "skill"..i.."icon", "技能"..i.."图", "技能"..skillLookup[i].."图", "技能"..i.."补", "技能"..skillLookup[i].."补" }, '明日方舟技能_'..(d.skillArray[i].skillName or '')..'.png' )
  384. i = i + 1
  385. possibleSkillDesp = getArgFromAlias ( args, { "sk"..i, "技能"..i, "技能"..skillLookup[i] } )
  386. end
  387. d.skillArray.switchPPS = frame:expandTemplate { title = '明日方舟技能条', ["args"] = { [1]='#style' } } -- '<templatestyles src="Template:明日方舟技能条/style.css" />'
  388. if d.rarity >= 4 then -- don't know why the and-or shorthand doesn't work
  389. d.skillArray.switchPPS = d.skillArray.switchPPS .. frame:expandTemplate { title = '明日方舟技能条', ["args"] = { [1]='#skill2' } }
  390. else
  391. d.skillArray.switchPPS = d.skillArray.switchPPS .. frame:expandTemplate { title = '明日方舟技能条', ["args"] = { [1]='#skill1' } }
  392. end
  393. -- base skills.
  394. d.baseSkillArray = {}
  395. i = 1
  396. local baseSkDesp = getArgFromAlias ( args, { "bsk"..i, "后勤"..i } )
  397. while baseSkDesp do
  398. d.baseSkillArray[#d.baseSkillArray+1] = { icon = getArgFromAlias ( args, { "bsk-icon"..i, "后勤"..i.."图标" } ), description = baseSkDesp }
  399. i = i + 1
  400. baseSkDesp = getArgFromAlias ( args, { "bsk"..i, "后勤"..i } )
  401. end
  402. --if not in article space, destroy category array
  403. if frame:preprocess('{{NAMESPACENUMBER}}') ~= '0' then d.categoryArray = nil end
  404. return d
  405. end
  406. function p.main ( frame )
  407. local args = getArgs ( frame, { wrappers = wrapperArray } )
  408. return p._exposed ( frame, args, "normal" )
  409. end
  410. function p.robot ( frame )
  411. local args = getArgs ( frame, { wrappers = wrapperArray } )
  412. return p._exposed ( frame, args, "robot" )
  413. end
  414. function p.exposed ( frame )
  415. local args = getArgs ( frame, { wrappers = wrapperArray } )
  416. return p._exposed ( frame, args, args["op-type"] )
  417. end
  418. function p._exposed ( frame, args, opType )
  419. return genOpComplex ( frame, genData ( frame, args, opType ) )
  420. end
  421. return p