BryghtShadow (talk | contribs) m (moving most autocat logic here.) |
No edit summary |
||
(37 intermediate revisions by 2 users not shown) | |||
Line 1: | Line 1: | ||
− | local |
+ | local p = {} |
+ | local mArguments -- lazy load |
||
+ | local mOrb = require("Module:Orb")._main |
||
+ | local mLink = require("Module:Link")._main |
||
− | util = require( 'Module:Utils' ) |
+ | local util = require( 'Module:Utils' ) |
− | box = require( 'Module:Infobox' ) |
+ | local box = require( 'Module:Infobox' ) |
− | style = require( 'Module:Infobox/CSS' ) |
+ | local style = require( 'Module:Infobox/CSS' ) |
− | auto = require( 'Module:AutoAbilities' ) |
+ | local auto = require( 'Module:AutoAbilities' ) |
− | COLS = "2" |
+ | local COLS = "2" |
− | skills = {} |
+ | local skills = {} |
local lang = mw.getContentLanguage() |
local lang = mw.getContentLanguage() |
||
+ | local title = mw.title.getCurrentTitle() |
||
+ | local NAMESPACE = title.namespace |
||
+ | local PAGENAME = title.text |
||
function p.main( frame ) |
function p.main( frame ) |
||
+ | mArguments = require("Module:Arguments") |
||
− | local pframe = frame:getParent() |
||
− | + | local args = mArguments.getArgs(frame) |
|
− | local config = frame.args |
||
− | t = p.parseArgs( frame.args ) |
||
− | boxes = {} |
||
− | -- Remove margin of the table |
||
− | style['table'].margin = "0" |
||
+ | local autocat = false |
||
− | for i, v in ipairs(t) do |
||
− | + | local cats = {} |
|
+ | if NAMESPACE == 0 or args.demospace == 'main' then |
||
− | -- Set box colors |
||
+ | autocat = true |
||
− | p.color( v.element:lower() ) |
||
+ | end |
||
− | html = { |
||
+ | local jobtype = lang:lc(args.type or '') |
||
− | [1] = { |
||
+ | if jobtype == "healer" then jobtype = "support" end |
||
− | ['bbottom'] = false, |
||
+ | local isMaterial = jobtype == "material" |
||
− | { p.image( v.image ), attr = { colspan = COLS } } |
||
+ | local isScroll = (mw.ustring.find(PAGENAME, "(scroll)", 1, true) or mw.ustring.find(PAGENAME, "(Scroll)", 1, true)) ~= nil |
||
− | }, |
||
+ | local ability = args.ability or '' |
||
− | [2] = { |
||
+ | local hasAbility = ability ~= "" and lang:lc(ability) ~= "none" and lang:lc(ability) ~= "n/a" |
||
− | { "Job Type", css = style.th }, |
||
+ | |||
− | { p.formatJobtype(v['type']), css = style.td } |
||
+ | t = p.parseArgs( args ) |
||
− | }, |
||
− | + | boxes = {} |
|
+ | -- Remove margin of the table |
||
− | { "Element", css = style.th }, |
||
+ | style['table'].margin = "0" |
||
− | { p.element( v.element ), css = style.td } |
||
− | }, |
||
− | [4] = { |
||
− | { "Skillseeds", css = style.th }, |
||
− | { p.formatSeed( v.seeds ), css = style.td } |
||
− | }, |
||
− | [5] = { |
||
− | ['type'] = "section", |
||
− | { "Ability", css = style.section, attr = {colspan='2'} } |
||
− | }, |
||
− | [6] = { |
||
− | { "Name", css = style.th }, |
||
− | { p.abilityLink( v.ability ), css = style.td } |
||
− | }, |
||
− | [7] = { |
||
− | ['type'] = "group", n = 3, ['bbottom'] = true, |
||
− | { "<div style='font-size:15px;'>'''Orbs'''</div>" .. p.orbs( v.orbs ) }, |
||
− | { "<div style='font-size:15px;'>'''Range'''</div>" .. v.range }, |
||
− | { "<div style='font-size:15px;'>'''Max Lv.'''</div>" .. v.maxlv }, |
||
− | }, |
||
− | [8] = { |
||
− | ['type'] = "group", n = 3, |
||
− | { "<div style='font-size:15px;'>'''Attack'''</div>" .. v.attack }, |
||
− | { "<div style='font-size:15px;'>'''Break Power'''</div>" .. v.breakpower }, |
||
− | { "<div style='font-size:15px;'>'''Crit Chance'''</div>" .. v.crit }, |
||
− | } |
||
− | } |
||
+ | for i, v in ipairs(t) do |
||
− | if ( (v.extraskills ~= "" and v.extraskills ~= nil) or next(skills) ~= nil ) then |
||
− | + | html = {} |
|
+ | -- Set box colors |
||
− | ['type'] = "section", |
||
+ | p.color( lang:lc(v.element) ) |
||
− | { "Extra Skills", css = style.section, attr = { colspan = COLS } } |
||
+ | html = { |
||
− | } |
||
− | + | [1] = { |
|
+ | ['bbottom'] = false, |
||
− | { p.extraSkills( v.extraskills ), attr = { colspan = COLS } } |
||
+ | { p.image( v.image ), attr = { colspan = COLS } } |
||
− | } |
||
+ | }, |
||
− | end |
||
− | + | [2] = { |
|
+ | { "Job Type", css = style.th }, |
||
− | html[#html+1] = { |
||
− | + | { p.formatJobtype(v['type']), css = style.td } |
|
+ | }, |
||
− | { "Auto-Abilities", css = style.section, attr = { colspan = COLS } } |
||
+ | [3] = { |
||
− | } |
||
+ | { "Element", css = style.th }, |
||
− | html[#html+1] = { |
||
− | + | { p.element( v.element ), css = style.td } |
|
+ | }, |
||
− | } |
||
+ | } |
||
− | end |
||
+ | if not isMaterial then |
||
− | if( v.augment ~= "" and v.augment ~= nil ) then |
||
+ | -- Only non-material cards create skillseeds. |
||
− | -- TODO: Utilize the plus (+) symbolizing Fast Learner cards. |
||
+ | html[#html+1] = { |
||
− | local star, plus = string.match(v.star, '(-?%d+)(%+?)') |
||
+ | { "Skillseeds", css = style.th }, |
||
− | star = tonumber( star ) + 1 |
||
+ | { p.formatSeed( v.seeds ), css = style.td } |
||
− | html[#html+1] = { |
||
+ | } |
||
− | ['type'] = "section", |
||
+ | end |
||
− | { "Augment to " .. util.stars( star ), css = style.section, attr = { colspan = COLS } } |
||
+ | if hasAbility then |
||
− | } |
||
− | + | html[#html+1] = { |
|
+ | ['type'] = "section", |
||
− | { p.augment( v.augment ), attr = { colspan = COLS } } |
||
+ | { "Ability", css = style.section, attr = {colspan='2'} } |
||
− | } |
||
+ | } |
||
− | end |
||
+ | html[#html+1] = { |
||
+ | { "Name", css = style.th }, |
||
+ | { p.abilityLink( v.ability ), css = style.td } |
||
+ | } |
||
+ | html[#html+1] = { |
||
+ | ['type'] = "group", n = 3, ['bbottom'] = true, |
||
+ | { "<div style='font-size:15px;'>'''Orbs'''</div>" .. p.orbs( v.orbs ) }, |
||
+ | { "<div style='font-size:15px;'>'''Range'''</div>" .. (v.range or "") }, |
||
+ | { "<div style='font-size:15px;'>'''Max Lv.'''</div>" .. (v.maxlv or "") }, |
||
+ | } |
||
+ | html[#html+1] = { |
||
+ | ['type'] = "group", n = 3, |
||
+ | { "<div style='font-size:15px;'>'''Attack'''</div>" .. (v.attack or "") }, |
||
+ | { "<div style='font-size:15px;'>'''Break Power'''</div>" .. (v.breakpower or "") }, |
||
+ | { "<div style='font-size:15px;'>'''Crit Chance'''</div>" .. (v.crit or "") }, |
||
+ | } |
||
+ | end |
||
+ | if (v.extraskills ~= "" and v.extraskills ~= nil) or next(skills) ~= nil then |
||
+ | html[#html+1] = { |
||
+ | ['type'] = "section", |
||
+ | { "Extra Skills", css = style.section, attr = { colspan = COLS } } |
||
+ | } |
||
+ | html[#html+1] = { |
||
+ | { p.extraSkills( v.extraskills ), attr = { colspan = COLS } } |
||
+ | } |
||
+ | end |
||
+ | if v.auto ~= "" and v.auto ~= nil then |
||
+ | html[#html+1] = { |
||
+ | ['type'] = "section", |
||
+ | { "Auto-Abilities", css = style.section, attr = { colspan = COLS } } |
||
+ | } |
||
+ | html[#html+1] = { |
||
+ | { p.autoAbilities( v.auto ), attr = { colspan = COLS } } |
||
+ | } |
||
+ | end |
||
+ | if v.augment ~= "" and v.augment ~= nil then |
||
+ | -- TODO: Utilize the plus (+) symbolizing Fast Learner cards. |
||
+ | local star, plus = string.match(v.star, '(-?%d+)(%+?)') |
||
+ | star = tonumber( star ) + 1 |
||
+ | html[#html+1] = { |
||
+ | ['type'] = "section", |
||
+ | { "Augment to " .. util.stars( star ), css = style.section, attr = { colspan = COLS } } |
||
+ | } |
||
+ | html[#html+1] = { |
||
+ | { p.augment( v.augment ), attr = { colspan = COLS } } |
||
+ | } |
||
+ | end |
||
− | + | boxes[i] = box.build ( util.sortTable(html), style, COLS ) |
|
− | + | end |
|
+ | |||
+ | -- the root html node |
||
+ | local root = mw.html.create() |
||
+ | -- tabbed infoboxes |
||
− | local tabs = mw.html.create( 'div' ) |
||
+ | local tabs = mw.html.create( 'div' ) |
||
− | tabs :css( 'margin', "10px 10px 20px 20px" ) |
||
+ | tabs |
||
− | :attr( 'class', 'cardtabs' ) |
||
+ | :addClass( 'cardtabs' ) |
||
− | :wikitext( p.tabber( frame ) ) |
||
+ | :css( 'margin', "10px 10px 20px 20px" ) |
||
− | if mw.title.getCurrentTitle().namespace == 0 or args.demospace == 'main' then |
||
+ | :css( "width", "300px" ) |
||
− | tabs:wikitext('[[Category:Cards]]') |
||
+ | :css( "float", "right" ) |
||
− | local jobtype = mw.ustring.lower(args['type'] or '') |
||
+ | :wikitext( p.tabber( frame ) ) |
||
− | local jobtype_cats = { |
||
+ | :allDone() |
||
− | warrior = '[[Category:Warrior Cards]]', |
||
+ | root:node(tabs) |
||
− | mage='[[Category:Mage Cards]]', |
||
+ | |||
− | meia='[[Category:Mage Cards]][[Category:Meia Cards]]', |
||
+ | -- description quote |
||
− | ranger='[[Category:Ranger Cards]]', |
||
+ | local info = args.info or args.description or '' |
||
− | sarah='[[Category:Ranger Cards]][[Category:Sarah Cards]]', |
||
+ | if info ~= '' then |
||
− | monk='[[Category:Monk Cards]]', |
||
+ | local quote_node = mw.html.create() |
||
− | support='[[Category:Healer Cards]][[Category:Support Cards]]', |
||
+ | local quote = frame:expandTemplate{title="quote", args={info, "In-game description"}} |
||
− | healer='[[Category:Healer Cards]][[Category:Support Cards]]', |
||
+ | quote_node:newline():wikitext(quote) |
||
− | material='[[Category:Material Cards]]', |
||
+ | root:node(quote_node) |
||
− | } |
||
+ | end |
||
− | tabs:wikitext(jobtype_cats[jobtype] or '') |
||
+ | |||
− | local element = mw.ustring.lower(args.element or '') |
||
+ | -- auto category |
||
− | local element_cats = { |
||
+ | if autocat then |
||
− | none = '[[Category:Non-Elemental]]', |
||
− | + | cats[#cats+1] = '[[Category:Ability cards]]' |
|
+ | local jobtype_cats = { |
||
− | water = '[[Category:Water Element]]', |
||
− | + | warrior = '[[Category:Warrior Cards]]', |
|
− | + | mage = '[[Category:Mage Cards]]', |
|
− | + | meia = '[[Category:Mage Cards]][[Category:Meia Cards]]', |
|
− | + | ranger = '[[Category:Ranger Cards]]', |
|
− | + | sarah = '[[Category:Ranger Cards]][[Category:Sarah Cards]]', |
|
− | + | monk = '[[Category:Monk Cards]]', |
|
+ | support = '[[Category:Support Cards]]', |
||
− | } |
||
+ | healer = '[[Category:Support Cards]]', |
||
− | tabs:wikitext(element_cats[element] or '') |
||
+ | material = '[[Category:Material Cards]]', |
||
− | local auto = args.auto or '' |
||
+ | } |
||
− | local ability = args.ability or '' |
||
+ | cats[#cats+1] = jobtype_cats[jobtype] or '' |
||
− | if ability ~= '' then |
||
+ | local ele = lang:lc(args.element or '') |
||
− | local abilities = util.explode('//', ability) |
||
+ | local ele_cats = { |
||
− | tabs:wikitext('[[Category:'.. abilities[#abilities] ..' Cards]]') |
||
+ | none = '[[Category:Non-Elemental]]', |
||
− | end |
||
+ | fire = '[[Category:Fire Element]]', |
||
− | if auto == '' then |
||
− | + | water = '[[Category:Water Element]]', |
|
+ | wind = '[[Category:Wind Element]]', |
||
− | end |
||
+ | earth = '[[Category:Earth Element]]', |
||
− | end |
||
+ | light = '[[Category:Light Element]]', |
||
− | return tostring( tabs ) |
||
+ | dark = '[[Category:Dark Element]]', |
||
+ | life = '[[Category:Life Element]]', |
||
+ | prismatic = '[[Category:Prismatic Element]]', |
||
+ | } |
||
+ | cats[#cats+1] = ele_cats[ele] or '' |
||
+ | if hasAbility then |
||
+ | local abis = mw.text.split(ability, '%s*//%s*') |
||
+ | cats[#cats+1] = '[[Category:'.. abis[#abis] ..' Cards]]' |
||
+ | -- TODO: Allow overrides. Such as if it's expecting augment or ES, but "none" is specified? |
||
+ | -- TODO: Check if Meia scrolls have only "Meia Synchro"? |
||
+ | if isScroll then |
||
+ | -- Scrolls do not have augment, don't track. |
||
+ | -- Scrolls do not have extra skills, don't track. |
||
+ | else |
||
+ | local stars = mw.text.split(args.star or '', "%s*//%s*") |
||
+ | local augments = mw.text.split(args.augment or '', "%s*//%s*") |
||
+ | local extras = mw.text.split(args.extraskills or '', "%s*//%s*") |
||
+ | local hasAugment = true |
||
+ | local hasExtra = true |
||
+ | for i=1,#stars do |
||
+ | local s=stars[i] or '' |
||
+ | local a=augments[i-1] or '' |
||
+ | local e=extras[i] or '' |
||
+ | mw.log(string.format('"%s", "%s", "%s"', s,a,e), 'augment:', hasAugment, 'extra:', hasExtra) |
||
+ | if i > 1 and hasAugment and s ~= "" and a=="" then |
||
+ | hasAugment = false |
||
+ | end |
||
+ | if hasExtra and s ~= "" and e == "" then |
||
+ | hasExtra = false |
||
+ | end |
||
+ | end |
||
+ | if not hasAugment and not isScroll then |
||
+ | -- Expected augment but found some missing. |
||
+ | -- Scrolls do not have augment, don't track. |
||
+ | cats[#cats+1] = '[[Category:Cards without augment]]' |
||
+ | end |
||
+ | if not hasExtra then |
||
+ | -- Expected extra skill but found some missing. |
||
+ | cats[#cats+1] = '[[Category:Cards without extra skill]]' |
||
+ | end |
||
+ | end |
||
+ | end |
||
+ | local auto = args.auto or '' |
||
+ | if auto == '' and not isScroll and not isMaterial then |
||
+ | cats[#cats+1] = '[[Category:Cards without auto-abilities]]' |
||
+ | end |
||
+ | root:wikitext(table.concat(cats,"")) |
||
+ | end |
||
+ | |||
+ | return tostring( root ) |
||
end |
end |
||
function p.tabber( frame ) |
function p.tabber( frame ) |
||
− | + | local param = "" |
|
− | + | for i, box in ipairs( boxes ) do |
|
− | + | param = param .. t[i].star .. "=" .. box |
|
− | + | if i == #boxes then break end |
|
− | + | param = param .. "|-|" |
|
− | + | end |
|
− | + | return frame:extensionTag( 'tabber', param ) |
|
end |
end |
||
Line 154: | Line 229: | ||
Example : star = "1 // 2 // 3"; job = "Mage"; attack = "10 // 20 // 30" |
Example : star = "1 // 2 // 3"; job = "Mage"; attack = "10 // 20 // 30" |
||
gives { |
gives { |
||
− | + | { star = 1, job = "Mage", attack = "10" } |
|
− | + | { star = 2, job = "Mage", attack = "20" } |
|
− | + | { star = 3, job = "Mage", attack = "30" } |
|
− | + | } |
|
]] |
]] |
||
function p.parseArgs( args ) |
function p.parseArgs( args ) |
||
− | + | local t = {} |
|
− | + | local n = 1 |
|
− | + | for k, v in pairs( args ) do |
|
− | + | params = mw.text.split( v, "%s*//%s*" ) |
|
− | + | if #params > n then n = #params end |
|
− | + | for i=1, #params do |
|
− | + | if not t[i] then t[i] = {} end |
|
− | + | t[i][k] = mw.text.trim( params[i] ) |
|
− | + | end |
|
− | + | end |
|
− | + | --[[ if a value is lacking, get the previous one |
|
− | + | except for image, extraskills, upgrade mats ]] |
|
− | + | for k, v in pairs( args ) do |
|
− | + | if ( k ~= 'extraskills' and k ~= 'image' and k ~= 'augment' ) then |
|
− | + | for i=1, n do |
|
− | + | if not t[i][k] then t[i][k] = t[i-1][k] end |
|
− | + | end |
|
− | + | end |
|
− | + | end |
|
− | + | return t |
|
end |
end |
||
-- Change box colors based on the element |
-- Change box colors based on the element |
||
function p.color( element ) |
function p.color( element ) |
||
− | + | if element == "fire" then |
|
− | + | style.th['background-color'] = "#f44336" |
|
− | + | style.section['background-color'] = "#b71c1c" |
|
− | + | style.color.color = "#f44336" |
|
− | + | elseif element == "water" then |
|
− | + | style.th['background-color'] = "#448aff" |
|
− | + | style.section['background-color'] = "#0d47a1" |
|
− | + | style.color.color = "#2196f3" |
|
− | + | elseif element == "earth" then |
|
− | + | style.th['background-color'] = "#795548" |
|
− | + | style.section['background-color'] = "#3e2723" |
|
− | + | style.color.color = "#795548" |
|
− | + | elseif element == "wind" then |
|
− | + | style.th['background-color'] = "#8bc34a" |
|
− | + | style.th.color = "#212121" |
|
− | + | style.section['background-color'] = "#33691e" |
|
− | + | style.color.color = "#8bc34a" |
|
− | + | elseif element == "dark" then |
|
− | + | style.th['background-color'] = "#673ab7" |
|
− | + | style.section['background-color'] = "#311b92" |
|
− | + | style.color.color = "#673ab7" |
|
− | + | elseif element == "light" then |
|
− | + | style.th['background-color'] = "#ffff8d" |
|
− | + | style.th.color = "#212121" |
|
− | + | style.section['background-color'] = "#f57f17" |
|
− | + | style.color.color = "#ffc107" |
|
− | + | elseif element == "life" then |
|
− | + | style.th['background-color'] = "#f48fb1" |
|
− | + | style.th.color = "#212121" |
|
− | + | style.section['background-color'] = "#d81b60" |
|
− | + | style.color.color = "#f06292" |
|
− | + | elseif element == "prismatic" then |
|
− | + | style.th['background-color'] = "#cddc39" |
|
− | + | style.section['background-color'] = "#0d47a1" |
|
− | + | end |
|
end |
end |
||
-- Format image, displays title if no image |
-- Format image, displays title if no image |
||
function p.image( img ) |
function p.image( img ) |
||
− | + | if ( img ~= nil and img ~= "" ) then |
|
− | + | return "[[File:" .. img .. "|300px]]" |
|
− | + | else |
|
− | + | local div = mw.html.create( 'div' ) |
|
− | + | div :wikitext( util.cleanTitle( mw.title.getCurrentTitle().text ) ) |
|
− | + | :css( { ['font-size'] = "20px", ['background-color'] = "#212121", |
|
− | + | color = "white", ['text-align'] = "center" } ) |
|
− | + | :css( style.td ) |
|
− | + | return tostring( div ) |
|
− | + | end |
|
end |
end |
||
-- Format skillseeds display |
-- Format skillseeds display |
||
function p.formatSeed( data ) |
function p.formatSeed( data ) |
||
− | + | local data = data or "" |
|
+ | if data == "" then return "" end |
||
− | local t = util.explode( ',', data ) |
||
+ | data = mw.text.trim(data) |
||
− | local elmnt = {} |
||
+ | local elmnt = {} |
||
− | for k, v in pairs(t) do |
||
− | + | for v in mw.text.gsplit( data, "%s*,%s*" ) do |
|
+ | local ele, qty = string.match(v, '(%a-)%s*x%s*(%d+)') |
||
− | end |
||
+ | elmnt[#elmnt+1] = string.format("%s x %s", p.seed( ele ), qty) |
||
− | local seeds = '' |
||
+ | end |
||
− | for k, v in pairs(elmnt) do |
||
+ | local seeds = table.concat(elmnt, " ") |
||
− | seeds = seeds .. p.seed( mw.text.trim( v[1] ) ) .." x " .. mw.text.trim( v[2] ) .. " " |
||
+ | return seeds |
||
− | end |
||
− | return seeds |
||
end |
end |
||
function p.formatJobtype( jobtype ) |
function p.formatJobtype( jobtype ) |
||
− | + | local t = lang:lc( jobtype ) |
|
− | + | local icon, name |
|
− | + | if t == 'warrior' then |
|
− | + | icon = 'File:Warrior_Icon.png' |
|
− | + | name = 'Warrior' |
|
− | + | elseif t == 'mage' then |
|
− | + | icon = 'File:Mage_Icon.png' |
|
− | + | name = 'Mage' |
|
− | + | elseif t == 'ranger' then |
|
− | + | icon = 'File:Ranger_Icon.png' |
|
− | + | name = 'Ranger' |
|
− | + | elseif t == 'monk' then |
|
− | + | icon = 'File:Monk_Icon.png' |
|
− | + | name = 'Monk' |
|
− | + | elseif t == 'support' or t == 'healer' then |
|
− | + | icon = 'File:Support_Icon.png' |
|
− | + | name = 'Support' |
|
− | + | elseif t == 'material' then |
|
− | + | icon = 'File:Material_Icon.png' |
|
− | + | name = 'Material' |
|
− | + | elseif t == 'meia' then |
|
− | + | icon = 'File:Meia_Icon.png' |
|
− | + | name = 'Mage' |
|
− | + | else |
|
− | + | return jobtype |
|
− | + | end |
|
− | + | return '[[' .. icon .. '|link=|x20px]] ' .. name |
|
end |
end |
||
function p.seed(elmt) |
function p.seed(elmt) |
||
+ | local elmt = elmt or '' |
||
− | return "[[File:Seed_" .. elmt .. ".png|link=|x20px]]" |
||
+ | return "[[File:Seed_" .. mw.text.trim(elmt) .. ".png|link=|x20px]]" |
||
end |
end |
||
-- Format orbs |
-- Format orbs |
||
function p.orbs( orb ) |
function p.orbs( orb ) |
||
− | + | local data = mw.text.split( orb, "x" ) |
|
+ | local icon = mOrb(data[1]) |
||
− | return "{{Orb|" .. data[1] .. "}} x" .. mw.text.trim( data[2] ) |
||
+ | local text = "x" .. mw.text.trim( data[2] ) |
||
+ | return icon .. " " .. text |
||
end |
end |
||
-- Format element |
-- Format element |
||
function p.element( element ) |
function p.element( element ) |
||
− | + | local icon = mOrb(element) |
|
− | + | local text = util.colorText( lang:ucfirst( element ), element ) |
|
− | + | return icon .. " " .. text |
|
end |
end |
||
-- Add element color to ability name |
-- Add element color to ability name |
||
function p.abilityLink( name ) |
function p.abilityLink( name ) |
||
− | + | local name = name or "" |
|
+ | if name == '' then return '' end |
||
− | span:css( style.color ):wikitext( name ) |
||
+ | local span = mw.html.create( 'span' ) |
||
− | return "[[" .. name .. "|" .. tostring(span) .. "]]" |
||
+ | span:css( style.color ):wikitext( name ) |
||
+ | return "[[" .. name .. "|" .. tostring(span) .. "]]" |
||
end |
end |
||
-- Format extra skills display |
-- Format extra skills display |
||
function p.extraSkills( data ) |
function p.extraSkills( data ) |
||
− | + | local es = mw.html.create( 'div' ) |
|
− | + | es:css( style.td ) |
|
− | + | if ( data ~= nil and data ~= "" ) then |
|
− | + | for v in mw.text.gsplit( data, ";" ) do |
|
− | + | table.insert( skills, v ) |
|
− | + | end |
|
− | + | end |
|
− | + | for i, v in ipairs( skills ) do |
|
− | + | local skill = util.explode( ' ', mw.text.trim(v), 2 ) |
|
− | + | local span = mw.html.create( 'span' ) |
|
− | + | span:css( { position = "absolute", right = "0", ["padding-left"] = "15px" } ) |
|
− | + | span:wikitext( "A.Lv. " .. skill[1] ) |
|
− | + | local div = mw.html.create( 'div' ) |
|
− | + | local text = skill[2] |
|
− | + | if text:sub( 1, 1 ) == "*" then |
|
− | + | text = text:sub( 2 ) |
|
− | + | skills[i] = "" |
|
− | + | end |
|
− | + | div:css( "position", "relative" ):wikitext( mLink{text} ):node( span ) |
|
− | + | es:node (div ) |
|
− | + | end |
|
− | + | -- Clean skills table by removing empty string |
|
− | + | local n, skillsNew = 1, {} |
|
− | + | for i, v in ipairs( skills ) do |
|
− | + | if v ~= "" then |
|
− | + | skillsNew[n] = v |
|
− | + | n = n + 1 |
|
− | + | end |
|
− | + | end |
|
− | + | skills = skillsNew |
|
− | + | return tostring(es) |
|
end |
end |
||
-- Format auto abilities |
-- Format auto abilities |
||
function p.autoAbilities( data ) |
function p.autoAbilities( data ) |
||
− | + | local formatString = auto._formatString or auto.formatString |
|
− | + | local data = data or "" |
|
− | + | local div = mw.html.create( 'div' ) |
|
+ | local text = "" |
||
− | local abilities = util.explode( ',', data ) |
||
+ | local abilities = mw.text.split( data, "%s*,%s*" ) |
||
− | for i, v in ipairs( abilities ) do |
||
+ | for i, v in ipairs( abilities ) do |
||
− | text = text .. "<div>" .. auto.formatString( v ) .. "</div>" |
||
+ | text = text .. "<div>" .. formatString( v ) .. "</div>" |
||
− | end |
||
+ | end |
||
− | div:css( style.td ):wikitext( text ) |
||
+ | div:css( style.td ):wikitext( text ) |
||
− | return tostring( div ) |
||
+ | return tostring( div ) |
||
end |
end |
||
-- Format upgrade mats |
-- Format upgrade mats |
||
function p.augment( data ) |
function p.augment( data ) |
||
− | + | local data = data or "" |
|
− | + | local div = mw.html.create( 'div' ) |
|
− | + | local text = "" |
|
− | + | local mats = mw.text.split( data, "%s*,%s*" ) |
|
− | + | for i, v in ipairs( mats ) do |
|
− | + | local mat = mw.text.split( v, "x" ) |
|
− | + | local title = "{{MaterialLink|" .. util.cleanTitle( util.trim(mat[1]) ) .. "}}" |
|
− | + | if mat[2] then |
|
− | + | text = text .. "<div>" .. title .. " x" .. mat[2] .. "</div>" |
|
− | + | else |
|
− | + | text = text .. "<div>" .. title .. "</div>" |
|
− | + | end |
|
− | + | end |
|
− | + | div:css( style.td ):wikitext( text ) |
|
− | + | return tostring( div ) |
|
end |
end |
||
Latest revision as of 08:20, 28 October 2021
local p = {}
local mArguments -- lazy load
local mOrb = require("Module:Orb")._main
local mLink = require("Module:Link")._main
local util = require( 'Module:Utils' )
local box = require( 'Module:Infobox' )
local style = require( 'Module:Infobox/CSS' )
local auto = require( 'Module:AutoAbilities' )
local COLS = "2"
local skills = {}
local lang = mw.getContentLanguage()
local title = mw.title.getCurrentTitle()
local NAMESPACE = title.namespace
local PAGENAME = title.text
function p.main( frame )
mArguments = require("Module:Arguments")
local args = mArguments.getArgs(frame)
local autocat = false
local cats = {}
if NAMESPACE == 0 or args.demospace == 'main' then
autocat = true
end
local jobtype = lang:lc(args.type or '')
if jobtype == "healer" then jobtype = "support" end
local isMaterial = jobtype == "material"
local isScroll = (mw.ustring.find(PAGENAME, "(scroll)", 1, true) or mw.ustring.find(PAGENAME, "(Scroll)", 1, true)) ~= nil
local ability = args.ability or ''
local hasAbility = ability ~= "" and lang:lc(ability) ~= "none" and lang:lc(ability) ~= "n/a"
t = p.parseArgs( args )
boxes = {}
-- Remove margin of the table
style['table'].margin = "0"
for i, v in ipairs(t) do
html = {}
-- Set box colors
p.color( lang:lc(v.element) )
html = {
[1] = {
['bbottom'] = false,
{ p.image( v.image ), attr = { colspan = COLS } }
},
[2] = {
{ "Job Type", css = style.th },
{ p.formatJobtype(v['type']), css = style.td }
},
[3] = {
{ "Element", css = style.th },
{ p.element( v.element ), css = style.td }
},
}
if not isMaterial then
-- Only non-material cards create skillseeds.
html[#html+1] = {
{ "Skillseeds", css = style.th },
{ p.formatSeed( v.seeds ), css = style.td }
}
end
if hasAbility then
html[#html+1] = {
['type'] = "section",
{ "Ability", css = style.section, attr = {colspan='2'} }
}
html[#html+1] = {
{ "Name", css = style.th },
{ p.abilityLink( v.ability ), css = style.td }
}
html[#html+1] = {
['type'] = "group", n = 3, ['bbottom'] = true,
{ "<div style='font-size:15px;'>'''Orbs'''</div>" .. p.orbs( v.orbs ) },
{ "<div style='font-size:15px;'>'''Range'''</div>" .. (v.range or "") },
{ "<div style='font-size:15px;'>'''Max Lv.'''</div>" .. (v.maxlv or "") },
}
html[#html+1] = {
['type'] = "group", n = 3,
{ "<div style='font-size:15px;'>'''Attack'''</div>" .. (v.attack or "") },
{ "<div style='font-size:15px;'>'''Break Power'''</div>" .. (v.breakpower or "") },
{ "<div style='font-size:15px;'>'''Crit Chance'''</div>" .. (v.crit or "") },
}
end
if (v.extraskills ~= "" and v.extraskills ~= nil) or next(skills) ~= nil then
html[#html+1] = {
['type'] = "section",
{ "Extra Skills", css = style.section, attr = { colspan = COLS } }
}
html[#html+1] = {
{ p.extraSkills( v.extraskills ), attr = { colspan = COLS } }
}
end
if v.auto ~= "" and v.auto ~= nil then
html[#html+1] = {
['type'] = "section",
{ "Auto-Abilities", css = style.section, attr = { colspan = COLS } }
}
html[#html+1] = {
{ p.autoAbilities( v.auto ), attr = { colspan = COLS } }
}
end
if v.augment ~= "" and v.augment ~= nil then
-- TODO: Utilize the plus (+) symbolizing Fast Learner cards.
local star, plus = string.match(v.star, '(-?%d+)(%+?)')
star = tonumber( star ) + 1
html[#html+1] = {
['type'] = "section",
{ "Augment to " .. util.stars( star ), css = style.section, attr = { colspan = COLS } }
}
html[#html+1] = {
{ p.augment( v.augment ), attr = { colspan = COLS } }
}
end
boxes[i] = box.build ( util.sortTable(html), style, COLS )
end
-- the root html node
local root = mw.html.create()
-- tabbed infoboxes
local tabs = mw.html.create( 'div' )
tabs
:addClass( 'cardtabs' )
:css( 'margin', "10px 10px 20px 20px" )
:css( "width", "300px" )
:css( "float", "right" )
:wikitext( p.tabber( frame ) )
:allDone()
root:node(tabs)
-- description quote
local info = args.info or args.description or ''
if info ~= '' then
local quote_node = mw.html.create()
local quote = frame:expandTemplate{title="quote", args={info, "In-game description"}}
quote_node:newline():wikitext(quote)
root:node(quote_node)
end
-- auto category
if autocat then
cats[#cats+1] = '[[Category:Ability cards]]'
local jobtype_cats = {
warrior = '[[Category:Warrior Cards]]',
mage = '[[Category:Mage Cards]]',
meia = '[[Category:Mage Cards]][[Category:Meia Cards]]',
ranger = '[[Category:Ranger Cards]]',
sarah = '[[Category:Ranger Cards]][[Category:Sarah Cards]]',
monk = '[[Category:Monk Cards]]',
support = '[[Category:Support Cards]]',
healer = '[[Category:Support Cards]]',
material = '[[Category:Material Cards]]',
}
cats[#cats+1] = jobtype_cats[jobtype] or ''
local ele = lang:lc(args.element or '')
local ele_cats = {
none = '[[Category:Non-Elemental]]',
fire = '[[Category:Fire Element]]',
water = '[[Category:Water Element]]',
wind = '[[Category:Wind Element]]',
earth = '[[Category:Earth Element]]',
light = '[[Category:Light Element]]',
dark = '[[Category:Dark Element]]',
life = '[[Category:Life Element]]',
prismatic = '[[Category:Prismatic Element]]',
}
cats[#cats+1] = ele_cats[ele] or ''
if hasAbility then
local abis = mw.text.split(ability, '%s*//%s*')
cats[#cats+1] = '[[Category:'.. abis[#abis] ..' Cards]]'
-- TODO: Allow overrides. Such as if it's expecting augment or ES, but "none" is specified?
-- TODO: Check if Meia scrolls have only "Meia Synchro"?
if isScroll then
-- Scrolls do not have augment, don't track.
-- Scrolls do not have extra skills, don't track.
else
local stars = mw.text.split(args.star or '', "%s*//%s*")
local augments = mw.text.split(args.augment or '', "%s*//%s*")
local extras = mw.text.split(args.extraskills or '', "%s*//%s*")
local hasAugment = true
local hasExtra = true
for i=1,#stars do
local s=stars[i] or ''
local a=augments[i-1] or ''
local e=extras[i] or ''
mw.log(string.format('"%s", "%s", "%s"', s,a,e), 'augment:', hasAugment, 'extra:', hasExtra)
if i > 1 and hasAugment and s ~= "" and a=="" then
hasAugment = false
end
if hasExtra and s ~= "" and e == "" then
hasExtra = false
end
end
if not hasAugment and not isScroll then
-- Expected augment but found some missing.
-- Scrolls do not have augment, don't track.
cats[#cats+1] = '[[Category:Cards without augment]]'
end
if not hasExtra then
-- Expected extra skill but found some missing.
cats[#cats+1] = '[[Category:Cards without extra skill]]'
end
end
end
local auto = args.auto or ''
if auto == '' and not isScroll and not isMaterial then
cats[#cats+1] = '[[Category:Cards without auto-abilities]]'
end
root:wikitext(table.concat(cats,""))
end
return tostring( root )
end
function p.tabber( frame )
local param = ""
for i, box in ipairs( boxes ) do
param = param .. t[i].star .. "=" .. box
if i == #boxes then break end
param = param .. "|-|"
end
return frame:extensionTag( 'tabber', param )
end
--[[ frame.args are named parameters with several values separated
by a // separator. This function creates tables of key, values.
Example : star = "1 // 2 // 3"; job = "Mage"; attack = "10 // 20 // 30"
gives {
{ star = 1, job = "Mage", attack = "10" }
{ star = 2, job = "Mage", attack = "20" }
{ star = 3, job = "Mage", attack = "30" }
}
]]
function p.parseArgs( args )
local t = {}
local n = 1
for k, v in pairs( args ) do
params = mw.text.split( v, "%s*//%s*" )
if #params > n then n = #params end
for i=1, #params do
if not t[i] then t[i] = {} end
t[i][k] = mw.text.trim( params[i] )
end
end
--[[ if a value is lacking, get the previous one
except for image, extraskills, upgrade mats ]]
for k, v in pairs( args ) do
if ( k ~= 'extraskills' and k ~= 'image' and k ~= 'augment' ) then
for i=1, n do
if not t[i][k] then t[i][k] = t[i-1][k] end
end
end
end
return t
end
-- Change box colors based on the element
function p.color( element )
if element == "fire" then
style.th['background-color'] = "#f44336"
style.section['background-color'] = "#b71c1c"
style.color.color = "#f44336"
elseif element == "water" then
style.th['background-color'] = "#448aff"
style.section['background-color'] = "#0d47a1"
style.color.color = "#2196f3"
elseif element == "earth" then
style.th['background-color'] = "#795548"
style.section['background-color'] = "#3e2723"
style.color.color = "#795548"
elseif element == "wind" then
style.th['background-color'] = "#8bc34a"
style.th.color = "#212121"
style.section['background-color'] = "#33691e"
style.color.color = "#8bc34a"
elseif element == "dark" then
style.th['background-color'] = "#673ab7"
style.section['background-color'] = "#311b92"
style.color.color = "#673ab7"
elseif element == "light" then
style.th['background-color'] = "#ffff8d"
style.th.color = "#212121"
style.section['background-color'] = "#f57f17"
style.color.color = "#ffc107"
elseif element == "life" then
style.th['background-color'] = "#f48fb1"
style.th.color = "#212121"
style.section['background-color'] = "#d81b60"
style.color.color = "#f06292"
elseif element == "prismatic" then
style.th['background-color'] = "#cddc39"
style.section['background-color'] = "#0d47a1"
end
end
-- Format image, displays title if no image
function p.image( img )
if ( img ~= nil and img ~= "" ) then
return "[[File:" .. img .. "|300px]]"
else
local div = mw.html.create( 'div' )
div :wikitext( util.cleanTitle( mw.title.getCurrentTitle().text ) )
:css( { ['font-size'] = "20px", ['background-color'] = "#212121",
color = "white", ['text-align'] = "center" } )
:css( style.td )
return tostring( div )
end
end
-- Format skillseeds display
function p.formatSeed( data )
local data = data or ""
if data == "" then return "" end
data = mw.text.trim(data)
local elmnt = {}
for v in mw.text.gsplit( data, "%s*,%s*" ) do
local ele, qty = string.match(v, '(%a-)%s*x%s*(%d+)')
elmnt[#elmnt+1] = string.format("%s x %s", p.seed( ele ), qty)
end
local seeds = table.concat(elmnt, " ")
return seeds
end
function p.formatJobtype( jobtype )
local t = lang:lc( jobtype )
local icon, name
if t == 'warrior' then
icon = 'File:Warrior_Icon.png'
name = 'Warrior'
elseif t == 'mage' then
icon = 'File:Mage_Icon.png'
name = 'Mage'
elseif t == 'ranger' then
icon = 'File:Ranger_Icon.png'
name = 'Ranger'
elseif t == 'monk' then
icon = 'File:Monk_Icon.png'
name = 'Monk'
elseif t == 'support' or t == 'healer' then
icon = 'File:Support_Icon.png'
name = 'Support'
elseif t == 'material' then
icon = 'File:Material_Icon.png'
name = 'Material'
elseif t == 'meia' then
icon = 'File:Meia_Icon.png'
name = 'Mage'
else
return jobtype
end
return '[[' .. icon .. '|link=|x20px]] ' .. name
end
function p.seed(elmt)
local elmt = elmt or ''
return "[[File:Seed_" .. mw.text.trim(elmt) .. ".png|link=|x20px]]"
end
-- Format orbs
function p.orbs( orb )
local data = mw.text.split( orb, "x" )
local icon = mOrb(data[1])
local text = "x" .. mw.text.trim( data[2] )
return icon .. " " .. text
end
-- Format element
function p.element( element )
local icon = mOrb(element)
local text = util.colorText( lang:ucfirst( element ), element )
return icon .. " " .. text
end
-- Add element color to ability name
function p.abilityLink( name )
local name = name or ""
if name == '' then return '' end
local span = mw.html.create( 'span' )
span:css( style.color ):wikitext( name )
return "[[" .. name .. "|" .. tostring(span) .. "]]"
end
-- Format extra skills display
function p.extraSkills( data )
local es = mw.html.create( 'div' )
es:css( style.td )
if ( data ~= nil and data ~= "" ) then
for v in mw.text.gsplit( data, ";" ) do
table.insert( skills, v )
end
end
for i, v in ipairs( skills ) do
local skill = util.explode( ' ', mw.text.trim(v), 2 )
local span = mw.html.create( 'span' )
span:css( { position = "absolute", right = "0", ["padding-left"] = "15px" } )
span:wikitext( "A.Lv. " .. skill[1] )
local div = mw.html.create( 'div' )
local text = skill[2]
if text:sub( 1, 1 ) == "*" then
text = text:sub( 2 )
skills[i] = ""
end
div:css( "position", "relative" ):wikitext( mLink{text} ):node( span )
es:node (div )
end
-- Clean skills table by removing empty string
local n, skillsNew = 1, {}
for i, v in ipairs( skills ) do
if v ~= "" then
skillsNew[n] = v
n = n + 1
end
end
skills = skillsNew
return tostring(es)
end
-- Format auto abilities
function p.autoAbilities( data )
local formatString = auto._formatString or auto.formatString
local data = data or ""
local div = mw.html.create( 'div' )
local text = ""
local abilities = mw.text.split( data, "%s*,%s*" )
for i, v in ipairs( abilities ) do
text = text .. "<div>" .. formatString( v ) .. "</div>"
end
div:css( style.td ):wikitext( text )
return tostring( div )
end
-- Format upgrade mats
function p.augment( data )
local data = data or ""
local div = mw.html.create( 'div' )
local text = ""
local mats = mw.text.split( data, "%s*,%s*" )
for i, v in ipairs( mats ) do
local mat = mw.text.split( v, "x" )
local title = "{{MaterialLink|" .. util.cleanTitle( util.trim(mat[1]) ) .. "}}"
if mat[2] then
text = text .. "<div>" .. title .. " x" .. mat[2] .. "</div>"
else
text = text .. "<div>" .. title .. "</div>"
end
end
div:css( style.td ):wikitext( text )
return tostring( div )
end
return p