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

Module:FGOServantSkill

贴贴♀百科,万娘皆可贴的百科全书!转载请标注来源页面的网页链接,并声明引自贴贴百科。内容不可商用。
跳到导航 跳到搜索
Template-info.svg 模块文档  [查看] [编辑] [历史] [刷新]

本模块仅用于{{FGO_持有技能}},生成Fate/Grand Order系列从者的持有技能描述。

  1. -- Originally designed and coded by Maya (U:Maya-Maja-Maia)
  2. local getArgs = require("Module:Arguments").getArgs
  3. local getSkillIcon = require("Module:FGOSkillIcon").getSkillIcon
  4. local hashObj = require("Module:HashArgs").hashObj
  5. local upPattern = "%^"
  6. local upString = '<span style="color:gold">▲</span>'
  7. local getSkillValue = function (s)
  8. if mw.ustring.sub(s, 1, 4) == 'val:' then
  9. return nil, mw.ustring.sub(s, 5, -1)
  10. end
  11. local n = tonumber(s)
  12. if n then
  13. return n
  14. end
  15. local ssub = mw.ustring.sub(s, 1, -2)
  16. n = tonumber(ssub)
  17. if n then
  18. return n, mw.ustring.sub(s, -1, -1)
  19. end
  20. if s == '&empty;' or s == '∅' then
  21. return nil, '∅'
  22. end
  23. end
  24. local getRoundValue = function (s)
  25. if mw.ustring.sub(s, 1, 6) == 'round:' then
  26. return mw.ustring.sub(s, 7, -1)
  27. end
  28. end
  29. local roundTo = function (n, to)
  30. if not tonumber(to) then return n end
  31. local mult = 10 ^ to
  32. return math.floor(n * mult + 0.5) / mult
  33. end
  34. local packSkillArgs = function (args, startIdx)
  35. local i = startIdx
  36. local retobj = {}
  37. local addingobj = nil
  38. while args[i] do
  39. if args[i] ~= '' then
  40. local val, suffix = getSkillValue(args[i])
  41. if not val and not suffix then
  42. local round = getRoundValue(args[i])
  43. if round then
  44. addingobj.round = round
  45. else
  46. if addingobj then
  47. table.insert(retobj, addingobj)
  48. end
  49. addingobj = {}
  50. addingobj.name = args[i]
  51. end
  52. else
  53. table.insert(addingobj, { val = val, suffix = suffix })
  54. end
  55. end
  56. i = i + 1
  57. end
  58. if addingobj then table.insert(retobj, addingobj) end
  59. return retobj
  60. end
  61. local expandSkillArg = function (skillArg)
  62. if #skillArg == 10 then return skillArg end
  63. if #skillArg == 1 then return skillArg end
  64. if #skillArg == 0 then
  65. skillArg[1] = { suffix = '∅' }
  66. return skillArg
  67. end
  68. if #skillArg ~= 2 then error('技能数值参数数量有误。应为0个、1个、2个或10个,实为' .. #skillArg .. '个') end
  69. if skillArg[1].suffix ~= skillArg[2].suffix then
  70. error('技能数值参数单位不匹配,其一为' .. skillArg[1].suffix .. ',另一为' .. skillArg[2].suffix)
  71. end
  72. local skillDiff = (skillArg[2].val - skillArg[1].val) / 10
  73. skillArg[10] = skillArg[2]
  74. for i = 1, 8 do
  75. skillArg[i+1] = { val = roundTo(skillArg[1].val + skillDiff * i, skillArg.round), suffix = skillArg[1].suffix }
  76. end
  77. return skillArg
  78. end
  79. local formatSkillArg = function (val, suffix)
  80. if not val then
  81. return suffix
  82. else
  83. return val .. (suffix or '')
  84. end
  85. end
  86. local getStringPrefixLevelAndStrip = function (str, prefix)
  87. local level = 0
  88. local stripped = str
  89. local prefixlen = mw.ustring.len(prefix)
  90. while mw.ustring.sub(stripped, 0, prefixlen) == prefix do
  91. level = level + 1
  92. stripped = mw.ustring.sub(stripped, prefixlen + 1, -1)
  93. end
  94. return { level = level, stripped = stripped }
  95. end
  96. local getStrengthenLevel = function (skillStr)
  97. local addLevel = getStringPrefixLevelAndStrip(skillStr, '+')
  98. local changeLevel = getStringPrefixLevelAndStrip(skillStr, '>')
  99. local subbed
  100. if addLevel.level > 0 then
  101. subbed, _ = mw.ustring.gsub(addLevel.stripped, upPattern, upString)
  102. return {
  103. type = 'add',
  104. level = addLevel.level,
  105. subbed = subbed
  106. }
  107. end
  108. if changeLevel.level > 0 then
  109. subbed, _ = mw.ustring.gsub(changeLevel.stripped, upPattern, upString)
  110. return {
  111. type = 'change',
  112. level = changeLevel.level,
  113. subbed = subbed
  114. }
  115. end
  116. return { type = nil, level = 0, subbed = skillStr }
  117. end
  118. local stackSkillArgs = function (skillArgs)
  119. local retobj = {}
  120. local addingobj = nil
  121. local strengthenobj = nil
  122. local strengthenTimes = 0
  123. for i = 1, #skillArgs do
  124. strengthenobj = getStrengthenLevel(skillArgs[i].name)
  125. if strengthenobj.type ~= 'change' then
  126. if addingobj then table.insert(retobj, addingobj) end
  127. addingobj = {}
  128. end
  129. if strengthenTimes < strengthenobj.level then
  130. strengthenTimes = strengthenobj.level
  131. end
  132. if addingobj and #addingobj ~= 0 then
  133. addingobj[#addingobj].stopShow = strengthenobj.level - 1
  134. end
  135. skillArgs[i].name = strengthenobj.subbed
  136. table.insert(addingobj, {
  137. startShow = strengthenobj.level,
  138. skillArg = skillArgs[i]
  139. })
  140. end
  141. if addingobj then table.insert(retobj, addingobj) end
  142. retobj.strengthenTimes = strengthenTimes
  143. return retobj
  144. end
  145. local getUpStrings = function (num)
  146. local retstr = ''
  147. for i = 1, num do
  148. retstr = retstr .. upString
  149. end
  150. return retstr
  151. end
  152. local getChargeString = function (str)
  153. local num = tonumber(str)
  154. if num then
  155. return num .. '→<span style="color:red">' .. num - 1 ..
  156. '</span>→<span style="color:red">' .. num - 2 .. '</span>'
  157. else
  158. return str
  159. end
  160. end
  161. local generateSkillRowWithClass = function (skillArg, class, add)
  162. local retstr = ''
  163. local classaddstr = add or ''
  164. if class then
  165. classaddstr = 'class="' .. class .. '" ' .. classaddstr
  166. end
  167. retstr = retstr .. [[
  168. |-]] .. classaddstr .. [[
  169. ! colspan="10" |]] .. skillArg.name .. [[
  170. |-]] .. classaddstr
  171. if #(skillArg) > 1 then
  172. for j = 1, 10 do
  173. retstr = retstr .. [[
  174. | style="width:75px;max-width:20%]]
  175. if j == 6 or j == 10 then
  176. retstr = retstr .. ';color:red'
  177. end
  178. retstr = retstr .. '"'
  179. if j >= 6 then
  180. retstr = retstr .. ' class="nomobile"'
  181. end
  182. retstr = retstr .. ' |' .. formatSkillArg(skillArg[j].val, skillArg[j].suffix)
  183. end
  184. retstr = retstr .. [[
  185. |- class="mobileonly ]] .. (class or '') .. '" ' .. (add or '')
  186. for j = 6, 10 do
  187. retstr = retstr .. [[
  188. | style="width:75px;max-width:20%]]
  189. if j == 6 or j == 10 then
  190. retstr = retstr .. ';color:red'
  191. end
  192. retstr = retstr .. '" |' .. formatSkillArg(skillArg[j].val, skillArg[j].suffix)
  193. end
  194. else
  195. retstr = retstr .. [[
  196. | colspan="10" |]] .. formatSkillArg(skillArg[1].val, skillArg[1].suffix)
  197. end
  198. return retstr
  199. end
  200. local generateTable = function (args, skillArgs, frame, hash)
  201. local iconstr = getSkillIcon(args[1])
  202. local namezhstr = args[2]
  203. local namejastr = args[3]
  204. local chargestr = getChargeString(args[4])
  205. local retstr = ''
  206. if skillArgs.strengthenTimes ~= 0 then
  207. local defaultTab = hash .. args["默认"]
  208. local buttonArgs = {
  209. 'button',
  210. ['@default'] = defaultTab,
  211. ['@forceNoCancel'] = 'y',
  212. ['@radio'] = 'y'
  213. }
  214. local buttonSort = '@default|@forceNoCancel|@radio|'
  215. local buttonText = ''
  216. for i = 0, skillArgs.strengthenTimes do
  217. if i == 0 then
  218. buttonText = args['按钮0'] or '强化前'
  219. elseif skillArgs.strengthenTimes == 1 then
  220. buttonText = args['按钮1'] or '强化后'
  221. else
  222. buttonText = args['按钮' .. i] or ('强化后' .. i)
  223. end
  224. buttonArgs[hash .. i] = buttonText
  225. buttonSort = buttonSort .. hash .. i .. '|'
  226. if args['条件' .. i] then
  227. retstr = retstr ..
  228. '<span class="textToggleDisplay hidden" data-id="' .. hash .. i ..
  229. '">' .. args['条件' .. i] .. '</span>\n'
  230. end
  231. end
  232. buttonArgs['@sort'] = buttonSort .. '@sort|'
  233. retstr = frame:callParserFunction{
  234. name = '#invoke:切换显示',
  235. args = buttonArgs
  236. } .. '\n\n' .. retstr -- cannot use template directly, order preservance issues
  237. end
  238. retstr = retstr .. '{| class="wikitable" style="text-align:center;vertical-align:middle;line-height:1.75em;display:table;max-width:100%"'
  239. for i = 0, skillArgs.strengthenTimes do
  240. local switchClassStr = ''
  241. if skillArgs.strengthenTimes ~= 0 then
  242. switchClassStr = 'class="textToggleDisplay hidden" data-id="' .. hash .. i .. '"'
  243. end
  244. if args["图标" .. i] then iconstr = getSkillIcon(args["图标" .. i]) end
  245. namezhstr = args["中文名" .. i] or namezhstr
  246. namejastr = args["日文名" .. i] or namejastr
  247. if args["充能时间" .. i] then chargestr = getChargeString(args["充能时间" .. i]) end
  248. retstr = retstr .. [[
  249. |-]] .. switchClassStr .. [[
  250. ! rowspan="2" class="nomobile" style="width:75px;max-width:10%" |]] .. iconstr .. [[
  251. ! rowspan="3" class="mobileonly" style="width:75px;max-width:20%" |]] .. iconstr .. [[
  252. ! colspan="4" class="mobileonly" style="width:300px;max-width:80%" |]] .. namezhstr .. getUpStrings(i) .. [[
  253. ! colspan="6" class="nomobile" style="width:450px;max-width:60%" |]] .. namezhstr .. getUpStrings(i) .. [[
  254. ! rowspan="2" colspan="3" class="nomobile" style="width:225px;max-width:30%" |充能时间:]] .. chargestr .. [[
  255. |-]] .. switchClassStr .. [[
  256. | colspan="6" lang="ja" | -{]] .. namejastr .. getUpStrings(i) .. [[}-
  257. |-]] .. switchClassStr .. [[
  258. ! colspan="4" class="mobileonly" |充能时间:]] .. chargestr
  259. end
  260. for i = 1, #skillArgs do
  261. if #(skillArgs[i]) == 1 and skillArgs[i][1].startShow == 0 then
  262. retstr = retstr .. generateSkillRowWithClass(skillArgs[i][1].skillArg)
  263. else
  264. local currentAt = 1
  265. for j = 0, skillArgs.strengthenTimes do
  266. if skillArgs[i][currentAt].startShow <= j then
  267. retstr = retstr .. generateSkillRowWithClass(skillArgs[i][currentAt].skillArg,
  268. 'textToggleDisplay hidden',
  269. 'data-id="' .. hash .. j .. '"')
  270. end
  271. if skillArgs[i][currentAt].stopShow and skillArgs[i][currentAt].stopShow <= j then
  272. currentAt = currentAt + 1
  273. end
  274. end
  275. end
  276. end
  277. retstr = retstr .. [[
  278. |}]]
  279. return retstr
  280. end
  281. local FGOServantSkill = {
  282. main = function (frame)
  283. local args = getArgs(frame, { removeBlanks = false })
  284. -- 1. 图标 2. 中文名 3. 日文名 4. CT
  285. -- 从5开始是技能描述
  286. local hash = hashObj(args)
  287. local skillArgs = packSkillArgs(args, 5)
  288. for i = 1, #skillArgs do
  289. skillArgs[i] = expandSkillArg(skillArgs[i])
  290. end
  291. skillArgs = stackSkillArgs(skillArgs)
  292. return generateTable(args, skillArgs, frame, hash)
  293. end
  294. }
  295. return FGOServantSkill