No edit summary |
No edit summary |
||
Line 930: | Line 930: | ||
result = mw.html.create():tag('tr'):addClass('tr-force-show') |
result = mw.html.create():tag('tr'):addClass('tr-force-show') |
||
:tag('th'):cssText('width: 30%; text-align:left; background-color: #092949'):wikitext('Card Name'):done() |
:tag('th'):cssText('width: 30%; text-align:left; background-color: #092949'):wikitext('Card Name'):done() |
||
− | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0'):wikitext('[[File:General Booster Pack HD.png|40px|link=]]'):attr('title', 'General Booster Pack (Card Pool: '..counter[1]..')'):done() |
+ | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:General Booster Pack HD.png|40px|link=]]'):attr('title', 'General Booster Pack (Card Pool: '..counter[1]..')'):done() |
− | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0'):wikitext('[[File:Fire Booster Pack HD.png|40px|link=]]'):attr('title', 'Fire Booster Pack (Card Pool: '..counter[2]..')'):done() |
+ | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Fire Booster Pack HD.png|40px|link=]]'):attr('title', 'Fire Booster Pack (Card Pool: '..counter[2]..')'):done() |
− | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0'):wikitext('[[File:Frost Booster Pack HD.png|40px|link=]]'):attr('title', 'Frost Booster Pack (Card Pool: '..counter[3]..')'):done() |
+ | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Frost Booster Pack HD.png|40px|link=]]'):attr('title', 'Frost Booster Pack (Card Pool: '..counter[3]..')'):done() |
− | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0'):wikitext('[[File:Nature Booster Pack HD.png|40px|link=]]'):attr('title', 'Nature Booster Pack (Card Pool: '..counter[4]..')'):done() |
+ | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Nature Booster Pack HD.png|40px|link=]]'):attr('title', 'Nature Booster Pack (Card Pool: '..counter[4]..')'):done() |
− | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0'):wikitext('[[File:Shadow Booster Pack HD.png|40px|link=]]'):attr('title', 'Shadow Booster Pack (Card Pool: '..counter[5]..')'):done() |
+ | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Shadow Booster Pack HD.png|40px|link=]]'):attr('title', 'Shadow Booster Pack (Card Pool: '..counter[5]..')'):done() |
− | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0'):wikitext('[[File:Amii Booster Pack HD.png|40px|link=]]'):attr('title', 'Amii Booster Pack (Card Pool: '..counter[6]..')'):done() |
+ | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Amii Booster Pack HD.png|40px|link=]]'):attr('title', 'Amii Booster Pack (Card Pool: '..counter[6]..')'):done() |
− | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0'):wikitext('[[File:Bandits Booster Pack HD.png|40px|link=]]'):attr('title', 'Bandits Booster Pack (Card Pool: '..counter[7]..')'):done() |
+ | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Bandits Booster Pack HD.png|40px|link=]]'):attr('title', 'Bandits Booster Pack (Card Pool: '..counter[7]..')'):done() |
− | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0'):wikitext('[[File:Fire Frost Booster Pack HD.png|40px|link=]]'):attr('title', 'Fire Frost Booster Pack (Card Pool: '..counter[8]..')'):done() |
+ | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Fire Frost Booster Pack HD.png|40px|link=]]'):attr('title', 'Fire Frost Booster Pack (Card Pool: '..counter[8]..')'):done() |
− | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0'):wikitext('[[File:Lost Souls Booster Pack HD.png|40px|link=]]'):attr('title', 'Lost Souls Booster Pack (Card Pool: '..counter[9]..')'):done() |
+ | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Lost Souls Booster Pack HD.png|40px|link=]]'):attr('title', 'Lost Souls Booster Pack (Card Pool: '..counter[9]..')'):done() |
− | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0'):wikitext('[[File:Stonekin Booster Pack HD.png|40px|link=]]'):attr('title', 'Stonekin Booster Pack (Card Pool: '..counter[10]..')'):done() |
+ | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Stonekin Booster Pack HD.png|40px|link=]]'):attr('title', 'Stonekin Booster Pack (Card Pool: '..counter[10]..')'):done() |
− | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0'):wikitext('[[File:Twilight Booster Pack HD.png|40px|link=]]'):attr('title', 'Twilight Booster Pack (Card Pool: '..counter[11]..')'):done() |
+ | :tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Twilight Booster Pack HD.png|40px|link=]]'):attr('title', 'Twilight Booster Pack (Card Pool: '..counter[11]..')'):done() |
:done():node(result:done()):done() |
:done():node(result:done()):done() |
||
end |
end |
Revision as of 19:24, 11 June 2021
Description
Handles the creation of the playable cards' appearences in the wiki.
See also
- Module Card/class
- Module Card/for each
- Module Card/custom
- Module Card/get
- Module Card/has
- Module Card/data
- Category Modules
-- Questions? Ask them on Message_Wall:FabianLars or Discord (User:FabianLars for contact details)
local p = {}
local get = require('Module:Card/get')
local has = require('Module:Card/has')
local lib = require('Module:Shared')
local concat = lib.concat
local format = lib.format
local getArgs = lib.getArgs
--- get name, affinity and promo from given cardname
---@param n string name of card in form of 'name', 'name (affinity)' or 'name (Promo)'
---@return string, string|nil, boolean Cardname without parantheses; affinity or nil; true if promo
---@private
local function verifyName(n)
local aff, promo = nil, false
local name, var = string.find(n, ' (', 1, true)
name, _ = name and string.sub(n, 1, (name or 0) - 1) or n, nil
var, _ = string.gsub(string.sub(n, (var or 0) + 1), '%)', '')
if var ~= name then
if var == 'Promo' then
promo = true
elseif var == 'Lost Souls' or var == 'Twilight' or var == 'Superpig' then
name = format('%s (%s)', name, var)
elseif var == 'Fire' or var == 'Frost' or var == 'Nature' or var == 'Shadow' then
if has.affinity(name, var) then
aff = var
end
end
end
return name, aff, promo
end
local function CardClass(init)
local self = type(init) == 'table' and init or {}
self.scaling = self.scaling or 0.74
self.cardupgrade = self.cardupgrade or 0
self.applied_charges = self.applied_charges or 0
self.notooltip = self.notooltip or false
self.infobox = self.infobox or false
self.orbs = self.orbs or {}
function self.build()
local card_container = mw.html.create('div')
:addClass(format('hidden cv-card-container%s', self.promo and ' cv-promo' or ''))
:cssText(format('transform: scale(%s)', self.scaling))
if self.err then
card_container:attr('title', self.err or 'Error: Check your input')
end
local card_artwork = mw.html.create('div'):addClass('cv-art'):wikitext(self.artwork_wktxt or ''):cssText(self.err and 'top: 0;' or ''):done()
local card_background = mw.html.create('div'):addClass('cv-bg c'.. (self.is_upgrade and 'u' or '') ..'v-bg-'..(self.factionLR or 'Blank')):wikitext((self.link and self.link ~= '') and ('[['..self.link..']]') or '')
if self.spell_background_wktxt then
card_background:tag('div'):addClass('cv-bg-spell'):wikitext(self.spell_background_wktxt):done()
end
card_background:done()
self.cardupgrade = self.cardupgrade or 0
self.applied_charges = self.applied_charges or 0
local upgradeLeft = mw.html.create()
if self.infobox or self.cardupgrade == 1 then
upgradeLeft:tag('div'):addClass('cv-upgradeparts cv-U1'):css{
['position'] = 'absolute',
['bottom'] = '168px',
['left'] = 0,
['z-index'] = 150,
['display'] = (self.cardupgrade == 1 and '' or 'none')
}:wikitext(self.upgrade_left_1_wktxt or ''):done()
end
if self.infobox or self.cardupgrade == 2 then
upgradeLeft:tag('div'):addClass('cv-upgradeparts cv-U2'):css{
['position'] = 'absolute',
['bottom'] = '168px',
['left'] = 0,
['z-index'] = 150,
['display'] = (self.cardupgrade == 2 and '' or 'none')
}:wikitext(self.upgrade_left_2_wktxt or ''):done()
end
if self.infobox or self.cardupgrade == 3 then
upgradeLeft:tag('div'):addClass('cv-upgradeparts cv-U3'):css{
['position'] = 'absolute',
['bottom'] = '168px',
['left'] = 0,
['z-index'] = 150,
['display'] = (self.cardupgrade == 3 and '' or 'none')
}:wikitext(self.upgrade_left_3_wktxt or ''):done()
end
if self.infobox or self.cardupgrade >= 1 then
upgradeLeft:tag('div'):addClass('cv-chargeparts cv-C1'):css{
['position'] = 'absolute',
['bottom'] = (self.factionLeft == 'Neutral' and '232px' or '233px'),
['left'] = (self.factionLeft == 'Neutral' and '10px' or '4px'),
['z-index'] = 200,
['display'] = ((self.applied_charges >= 1 and self.applied_charges <= self.cardupgrade) and '' or 'none')
}:wikitext(self.charge_left_1_wktxt or ''):done()
end
if self.infobox or self.cardupgrade >= 2 then
upgradeLeft:tag('div'):addClass('cv-chargeparts cv-C2'):css{
['position'] = 'absolute',
['bottom'] = (self.factionLeft == 'Neutral' and '312px' or '304px'),
['left'] = (self.factionLeft == 'Neutral' and '10px' or '4px'),
['z-index'] = 200,
['display'] = ((self.applied_charges >= 2 and self.applied_charges <= self.cardupgrade) and '' or 'none')
}:wikitext(self.charge_left_2_wktxt or ''):done()
end
if self.infobox or self.cardupgrade >= 3 then
upgradeLeft:tag('div'):addClass('cv-chargeparts cv-C3'):css{
['position'] = 'absolute',
['bottom'] = (self.factionLeft == 'Neutral' and '394px' or '372px'),
['left'] = (self.factionLeft == 'Neutral' and '10px' or '4px'),
['z-index'] = 200,
['display'] = ((self.applied_charges >= 3 and self.applied_charges <= self.cardupgrade) and '' or 'none')
}:wikitext(self.charge_left_3_wktxt or ''):done()
end
if self.promo_icon_wktxt then
upgradeLeft:tag('div'):addClass('cv-promo-icon ' .. (self.promo_icon_class or '')):wikitext(self.promo_icon_wktxt):done()
end
upgradeLeft:done()
local upgradeRight = mw.html.create()
if self.infobox or self.cardupgrade >= 1 then
upgradeRight:tag('div'):addClass('cv-upgradeparts cv-U1'):css{
['position'] = 'absolute',
['bottom'] = '168px',
['right'] = 0,
['z-index'] = 150,
['display'] = (self.cardupgrade >= 1 and '' or 'none')
}:wikitext(self.upgrade_right_1_wktxt or ''):done()
end
if self.infobox or self.cardupgrade >= 2 then
upgradeRight:tag('div'):addClass('cv-upgradeparts cv-U2'):css{
['position'] = 'absolute',
['bottom'] = (self.factionRight == 'Neutral' and '248px' or '296px'),
['right'] = (self.factionRight == 'Neutral' and 0 or '4px'),
['z-index'] = 150,
['display'] = (self.cardupgrade >= 2 and '' or 'none')
}:wikitext(self.upgrade_right_2_wktxt or ''):done()
end
if self.infobox or self.cardupgrade >= 3 then
upgradeRight:tag('div'):addClass('cv-upgradeparts cv-U3'):css{
['position'] = 'absolute',
['bottom'] = (self.factionRight == 'Neutral' and '326px' or '362px'),
['right'] = (self.factionRight == 'Neutral' and 0 or '4px'),
['z-index'] = 150,
['display'] = (self.cardupgrade == 3 and '' or 'none')
}:wikitext(self.upgrade_right_3_wktxt or ''):done()
end
if self.infobox or self.cardupgrade >= 1 then
upgradeRight:tag('div'):addClass('cv-chargeparts cv-C1'):css{
['position'] = 'absolute',
['bottom'] = (self.factionRight == 'Neutral' and '232px' or '221px'),
['right'] = (self.factionRight == 'Neutral' and '11px' or '4px'),
['z-index'] = 200,
['display'] = ((self.applied_charges >= 1 and self.applied_charges <= self.cardupgrade) and '' or 'none')
}:wikitext(self.charge_right_1_wktxt or ''):done()
end
if self.infobox or self.cardupgrade >= 2 then
upgradeRight:tag('div'):addClass('cv-chargeparts cv-C2'):css{
['position'] = 'absolute',
['bottom'] = (self.factionRight == 'Neutral' and '312px' or '294px'),
['right'] = (self.factionRight == 'Neutral' and '11px' or '4px'),
['z-index'] = 200,
['display'] = ((self.applied_charges >= 2 and self.applied_charges <= self.cardupgrade) and '' or 'none')
}:wikitext(self.charge_right_2_wktxt or ''):done()
end
if self.infobox or self.cardupgrade >= 3 then
upgradeRight:tag('div'):addClass('cv-chargeparts cv-C3'):css{
['position'] = 'absolute',
['bottom'] = (self.factionRight == 'Neutral' and '390px' or '362px'),
['right'] = (self.factionRight == 'Neutral' and '11px' or '4px'),
['z-index'] = 200,
['display'] = ((self.applied_charges >= 3 and self.applied_charges <= self.cardupgrade) and '' or 'none')
}:wikitext(self.charge_right_3_wktxt or ''):done()
end
upgradeRight:done()
local card_name = mw.html.create('div'):addClass('cv-name'):wikitext(self.display_name or ''):done()
local card_tokenslot = self.is_upgrade and mw.html.create() or mw.html.create('div'):addClass(format('cv-slot cv-slot-%s card-viewer-color-%s', self.factionLR == 'FireNature' and 'FireNature' or (self.factionRight or 'blank'), string.lower(self.affinity or 'blank'))):wikitext(self.affinity and '[[File:Affinity Tokenslot Overlay Blank.png|link=]]' or '')
local orb1 = mw.html.create('div'):addClass('cv-orb1 cv-orb-'..(self.orbs[1] or 'None')):done()
local orb2 = mw.html.create('div'):addClass('cv-orb2 cv-orb-'..(self.orbs[2] or 'None')):done()
local orb3 = mw.html.create('div'):addClass('cv-orb3 cv-orb-'..(self.orbs[3] or 'None')):done()
local orb4 = mw.html.create('div'):addClass('cv-orb4 cv-orb-'..(self.orbs[4] or 'None')):done()
local card_power_cost = mw.html.create('div'):addClass('cv-cost'):attr('data-cost', self.data_cost_attr or ''):wikitext(self.power_cost_wktxt or ''):done()
local card_charges_squadsize_class = mw.html.create('div'):addClass('cv-squad')
:tag('span')
:addClass('cv-charges')
:attr('data-charges', self.data_charges_attr or '')
:wikitext(self.charges_wktxt or ''):done()
if self.squadsize and self.squadsize > 1 then
card_charges_squadsize_class:wikitext(format('x%s', self.squadsize))
end
card_charges_squadsize_class:wikitext(format(' %s', self.class or '')):done()
local card_affinity_icon = self.affinity
and (mw.html.create('div'):addClass('cv-aff-icon cv-aff-icon-'..self.affinity)
or mw.html.create()):done()
local card_abilities = mw.html.create('div'):addClass('cv-abilities'):node(self.abilities_node or '')
local card_weapon_type = mw.html.create('div'):addClass(format('cv-weapon card-viewer-layer-%s', string.lower(self.factionLeft or 'blank'))):wikitext(self.weapon_type_wktxt or ''):done()
local card_counter = mw.html.create('div'):addClass(format('cv-counter card-viewer-layer-%s', string.lower(self.factionLeft or 'blank'))):wikitext(self.counter_wktxt or ''):done()
local card_damage = mw.html.create('div'):addClass('cv-damage'):attr('data-damage', self.data_damage_attr or ''):wikitext(self.damage_wktxt or ''):done()
local card_size_class = mw.html.create('div'):addClass('cv-size card-viewer-unit-size')
if self.unit_size_wktxt or self.health_wktxt then
card_size_class:addClass(format('card-viewer-layer-%s', string.lower(self.factionRight or 'blank')))
:wikitext('[[File:Card_Icon_HP.png||link=]]')
:wikitext(self.unit_size_wktxt or '')
end
local card_health = mw.html.create('div'):addClass('cv-health'):attr('data-health', self.data_health_attr or ''):wikitext(self.health_wktxt or ''):done()
local card_edition_icon = mw.html.create('div'):addClass((not self.edition or not self.rarity) and 'cv-edition cv-edition-blank' or format('cv-edition cv-edition-%s-%s', string.gsub(self.edition, ' ', '-'), string.gsub(self.rarity, ' ', '-')))
card_container
:node(card_artwork):node(card_background):node(upgradeLeft):node(upgradeRight):node(card_name)
:node(card_tokenslot):node(orb1):node(orb2):node(orb3):node(orb4)
:node(card_power_cost):node(card_charges_squadsize_class):node(card_affinity_icon):node(card_abilities)
:node(card_weapon_type):node(card_counter):node(card_damage):node(card_size_class):node(card_health):node(card_edition_icon)
:done()
local return_val = mw.html.create('div'):addClass((not self.notooltip and not self.err) and 'custom-tooltip' or ''):attr('data-tt-type', 'card'):attr('data-1', (self.full_name or self.display_name) .. (self.promo and ' (Promo)' or (self.affinity and ' ('..self.affinity..')' or ''))):css{
['width'] = format('%spx', 370 * self.scaling),
['height'] = format('%spx', 510 * self.scaling),
['display'] = 'inline-block'
}:tag('div'):cssText('display:none'):wikitext(self.display_name and '[['..self.display_name..']]' or ''):done():node(card_container):allDone()
if self.filter then
return_val
:attr('data-search', self.full_name or self.display_name)
:attr('data-rarity', self.rarity)
:attr('data-cost', self.power_cost_wktxt)
:attr('data-edition', self.edition)
:attr('data-faction', self.faction)
:attr('data-counter', self.counter)
:attr('data-weapontype', self.weapon_type)
:attr('data-special', (self.promo and 'Promo' or '') ..','.. (self.starter and 'Starter' or '')..','..(self.normal and 'Normal' or '')..','..((function() for _,v in ipairs(self.orbs) do if v and v~='Neutral' then return true end end end)() and 'Non-Legendary' or ''))
:attr('data-orbs', concat(self.orbs, ','))
:attr('data-orbsamount', #self.orbs)
:attr('data-affinities', concat(self.affinity, ','))
:attr('data-size', self.size)
:attr('data-type', self.type)
end
return return_val
end
return self
end
local function ErrorCard(err, scaling)
return CardClass{
scaling = scaling,
display_name = 'ERROR',
artwork_wktxt = '[[File:Quests_warning.png||link=|320px]]',
abilities_node = mw.html.create('div'):cssText('width: 320px'):wikitext(err),
err = err,
}.build()
end
local function chargeRules(index)
local charge_rules = {
[4] = { 1, 1, 1, 1 },
[8] = { 4, 2, 1, 1 },
[10] = { 5, 2, 2, 1 },
[12] = { 6, 2, 2, 2 },
[16] = { 8, 3, 3, 2 },
[20] = { 10, 4, 3, 3 },
[24] = { 12, 4, 4, 4 }
}
if index then return charge_rules[index] end
return charge_rules
end
local function getProgressionArgs(v1, v2, v3, v4)
if v1 and v1 ~= '' then
return {texttip = 'true', v1, 'Base / U-0', v2, 'U-1', v3, 'U-2', v4, 'U-3'}
elseif v2 and v2 ~= '' then
return {texttip = 'true', v2, 'U-1', v3, 'U-2', v4, 'U-3'}
elseif v3 and v3 ~= '' then
return {texttip = 'true', v3, 'U-2', v4, 'U-3'}
elseif v4 and v4 ~= '' then
return {texttip = 'true', v4, 'U-3'}
else return end
end
local function getAbilAvail(t)
if type(t) ~= 'table' then return nil end
local from, to
for k,v in ipairs(t) do
if v and not from then from = k-1 end
if from and not v then to = k-2 end
end
if from == 3 then return 3 end
if from == to then
if from == 0 then return nil end
return from
else
return (from or 0) .. '-' .. (to or 3)
end
end
function p.abilities(frame)
local args = getArgs(frame)
local tagArgs = {}
local getInfo = function(aData, affinity, promo)
local res = ''
local key = 'Z'
for _,v in ipairs(aData or {}) do
local text = v.description or ''
if v.values and v.values[1] then
local temp = {}
if type(v.values[1]) == 'number' or type(v.values[1]) == 'string' then
temp[#temp+1] = frame:expandTemplate{title = 'p', args = getProgressionArgs(v.values[1], v.values[2], v.values[3], v.values[4])}
else
for _,vv in ipairs(v.values) do
temp[#temp+1] = frame:expandTemplate{title = 'p', args = getProgressionArgs(vv[1], vv[2], vv[3], vv[4])}
end
end
local temp_text,_ = mw.ustring.gsub(text, '%%([^s])', '%%%%%1')
text = format(temp_text, unpack(temp))
end
local icon_name = format("%s %s Ability Icon.png", args.name or args[1], v.name)
res = res .. frame:expandTemplate{
title = 'Ability',
args = {
hotkey = (v.type == 'Active' or v.type == 'Toggle') and key or nil,
name = v.name,
type = v.type,
cost = type(v.cost) == 'table'
and frame:expandTemplate{title = 'p', args = getProgressionArgs(v.cost[1], v.cost[2], v.cost[3], v.cost[4])}
or v.cost,
affinity_dependency = v.affinity_dependency and affinity or nil,
upgrade_availability = getAbilAvail(v.upgrade_availability),
icon = mw.title.new( icon_name, 'File' ).exists and icon_name or nil,
details = args['ability_details_'..(tostring(v.name or ''):lower():gsub('%s+', '_'))] and frame:preprocess(args['ability_details_'..(tostring(v.name or ''):lower():gsub('%s+', '_'))]) or nil,
description = text
}
}
if v.type == "Active" or v.type == "Toggle" then
if key == 'Z' then key = 'X'
elseif key == 'X' then key = 'C'
elseif key == 'C' then key = 'V'
end
end
end
return res
end
local promo_aff = get.affinity(args[1] .. ' (Promo)')
if get.abilities(args[1]) then tagArgs[#tagArgs+1] = args[1]..'='..getInfo(get.abilities(args[1])) end
if get.abilities(args[1]..' (Fire)') then tagArgs[#tagArgs+1] = args[1]..' (Fire)='..getInfo(get.abilities(args[1]..' (Fire)'), 'Fire') end
if get.abilities(args[1]..' (Frost)') then tagArgs[#tagArgs+1] = args[1]..' (Frost)='..getInfo(get.abilities(args[1]..' (Frost)'), 'Frost') end
if get.abilities(args[1]..' (Nature)') then tagArgs[#tagArgs+1] = args[1]..' (Nature)='..getInfo(get.abilities(args[1]..' (Nature)'), 'Nature') end
if get.abilities(args[1]..' (Shadow)') then tagArgs[#tagArgs+1] = args[1]..' (Shadow)='..getInfo(get.abilities(args[1]..' (Shadow)'), 'Shadow') end
if get.abilities(args[1]..' (Promo)') then tagArgs[#tagArgs+1] = args[1]..' (Promo)='..getInfo(get.abilities(args[1]..' (Promo)'), promo_aff, true) end
if get.abilities(args[1]..' (Lost Souls)') then tagArgs[#tagArgs+1] = args[1]..' (Lost Souls)='..getInfo(get.abilities(args[1]..' (Lost Souls)')) end
if get.abilities(args[1]..' (Twilight)') then tagArgs[#tagArgs+1] = args[1]..' (Twilight)='..getInfo(get.abilities(args[1]..' (Twilight)')) end
if get.abilities(args[1]..' (Superpig)') then tagArgs[#tagArgs+1] = args[1]..' (Superpig)='..getInfo(get.abilities(args[1]..' (Superpig)')) end
return (#tagArgs or 0) <= 1 and (tagArgs[1] or ''):gsub('^.-=', '', 1) or frame:preprocess('<tabber>'..concat(tagArgs, '|-|')..'</tabber>')
end
--- returns html for a card to display
---@param frame table mw.frame object
---@return string card as mw.html
---@public
function p.card(frame)
local args = getArgs(frame)
if not get.exists(args.name or args[1]) then
return ErrorCard(
format('Card or Variant "%s" not found', args.name or args[1]),
args.scaling or args.displayscaling or 0.74
)
end
local data = get.card(args.name or args[1])
local card = CardClass()
local charge_rules = chargeRules()
local name = args.name or args[1] or 'Name missing'
local display_name, aff, promo = verifyName(args.name or args[1] or 'Name missing')
if data.affinity then aff = data.affinity end
if data.promo then promo = data.promo end
if data.temporary_card then promo = true end
local scaling = args.scaling or data.scaling or args.displayscaling or data.displayscaling or 0.74
--local err = nil
local check_size = {
S = true,
M = true,
L = true,
XL = true,
}
local link = display_name
if data.nolink or args.nolink then
link = ''
end
local res = data.orbs and get['factions'](name, data.orbs)
local factionLR = data.orbs and (res[1] ~= res[2] and res[1] .. res[2] or res[1]) or 'Blank'
local factionLeft = res and res[1] or nil
local factionRight = res and res[2] or nil
card.filter = args.filter
card.infobox = args.infobox
card.link = link
card.type = data.type
card.faction = get.faction(name)
card.factionLR = factionLR
card.factionLeft = factionLeft
card.factionRight = factionRight
card.affinity = aff
card.notooltip = args.notooltip or data.notooltip or false
card.scaling = scaling
card.artwork_wktxt = format(data.artwork and format('[[File:%s||link=|320px]]', data.artwork) or '[[File:%s%s_Card_Artwork.png||link=]]', display_name, promo and '_(Promo)' or '')
card.spell_background_wktxt = data.type == 'Spell' and format('[[File:Spell_Card_Overlay_%s.png||link=]]', factionLR) or nil
local cardupgrade = promo and 3 or (tonumber(data.cardupgrade) or tonumber(args.cardupgrade) or 0)
local applied_charges = promo and 3 or (tonumber(data.applied_charges) or tonumber(args.applied_charges) or 0)
card.cardupgrade = cardupgrade
card.applied_charges = applied_charges
if promo and not data.temporary_card then
card.promo = true
card.promo_icon_wktxt = format('[[File:Promo_Icon_%s.png||link=]]', factionLeft)
elseif data.starter_card and (args.infobox or (cardupgrade or 0) == 0) then
card.promo_icon_class = 'cv-upgradeparts cv-A0'
card.promo_icon_wktxt = format('[[File:Starter_Icon_%s.png||link=]]', factionLeft)
elseif data.temporary_card then
card.promo_icon_wktxt = format('[[File:Temporary_Icon_%s.png||link=]]', factionLeft)
end
card.upgrade_left_1_wktxt = format('[[File:%s_Upgrade_1_Left.png||link=]]', factionLeft)
card.upgrade_left_2_wktxt = format('[[File:%s_Upgrade_2_Left.png||link=]]', factionLeft)
card.upgrade_left_3_wktxt = format('[[File:%s_Upgrade_3_Left.png||link=]]', factionLeft)
card.charge_left_1_wktxt =
factionLeft == 'Neutral'
and '[[File:Neutral_Charge_All.png||link=]]'
or format('[[File:%s_Charge_1_Left.png||link=]]', factionLeft)
card.charge_left_2_wktxt =
factionLeft == 'Neutral'
and '[[File:Neutral_Charge_All.png||link=]]'
or format('[[File:%s_Charge_2_Left.png||link=]]', factionLeft)
card.charge_left_3_wktxt =
factionLeft == 'Neutral'
and '[[File:Neutral_Charge_All.png||link=]]'
or format('[[File:%s_Charge_3_Left.png||link=]]', factionLeft)
card.upgrade_right_1_wktxt = format('[[File:%s_Upgrade_1_Right.png||link=]]', factionRight)
card.upgrade_right_2_wktxt = format('[[File:%s_Upgrade_%s_Right.png||link=]]', factionRight, factionRight == 'Neutral' and '1' or '2')
card.upgrade_right_3_wktxt = format('[[File:%s_Upgrade_%s_Right.png||link=]]', factionRight, factionRight == 'Neutral' and '1' or '3')
card.charge_right_1_wktxt =
factionRight == 'Neutral'
and '[[File:Neutral_Charge_All.png||link=]]'
or format('[[File:%s_Charge_1_Right.png||link=]]', factionRight)
card.charge_right_2_wktxt =
factionRight == 'Neutral'
and '[[File:Neutral_Charge_All.png||link=]]'
or format('[[File:%s_Charge_2_Right.png||link=]]', factionRight)
card.charge_right_3_wktxt
= factionRight == 'Neutral'
and '[[File:Neutral_Charge_All.png||link=]]'
or format('[[File:%s_Charge_3_Right.png||link=]]', factionRight)
card.full_name = display_name
card.display_name = display_name:gsub(' %(Lost Souls%)', ''):gsub(' %(Twilight%)', ''):gsub(' %(Superpig%)', '')
local dataorbs = {}
for k,v in ipairs(data.orbs or {}) do dataorbs[k] = v end
card.orbs = dataorbs
card.data_cost_attr = format('["%s"]', concat(data.power_cost, '","'))
card.power_cost_wktxt = type(data.power_cost) == 'table'
and data.power_cost[cardupgrade + 1]
or data.power_cost
local actualChargeRule = (promo
and { data.charges or 4, 0, 0, 0 }
or (type(data.charges) == table
and data.charges
or (charge_rules[data.charges or 4]) or charge_rules[4])
)
local actualCurrentCharge
for i=0, applied_charges do
actualCurrentCharge = (actualCurrentCharge or 0) + actualChargeRule[i+1] or 0
end
card.charges_wktxt = actualCurrentCharge
card.data_charges_attr = format('["%s"]', concat(actualChargeRule or {}, '","'))
card.squadsize = data.squadsize
card.class = data.class
card.weapon_type = data.weapon_type
card.weapon_type_wktxt = (data.weapon_type and data.type ~= 'Spell')
and format('[[File:Card_Icon_%s_Unit.png||link=]]', data.weapon_type) or ''
card.counter = data.counter
card.counter_wktxt = (data.weapon_type and data.weapon_type ~= 'Special' and data.type ~= 'Spell' and check_size[data.counter or 'Nope'])
and format('[[File:Card_Icon_Unit_Size_%s.png|38px|link=]]', data.counter) or ''
card.data_damage_attr = format('["%s"]', concat(data.damage, '","'))
card.damage_wktxt = type(data.damage) == 'table' and data.damage[cardupgrade + 1] or data.damage
card.unit_size = check_size[data.size or 'Nope'] and data.size or nil
card.unit_size_wktxt = check_size[data.size or 'Nope'] and format('[[File:Card_Icon_Unit_Size_%s.png|38px|link=]]', data.size) or nil
card.data_health_attr = format('["%s"]', concat(data.health, '","'))
card.health_wktxt = type(data.health) == 'table' and data.health[cardupgrade + 1] or data.health
card.edition = data.edition
card.rarity = data.rarity
card.abilities_node = data.abilities_done
if not card.abilities_node then
local abilities_node = mw.html.create()
local ab_count = 0
for k, v in ipairs(data.abilities or {}) do
if ab_count < 4 and not v.hide_on_card then
ab_count = ab_count + 1
local abil = mw.html.create('div')
local avail = v.upgrade_availability
if avail then
local s = ''
local from
for k,v in ipairs(avail) do
if v and not from then from = k-1 end
if v then s = s .. ' cv-A' .. (k-1) end
end
abil:addClass('cv-upgradeparts' .. s)
if from > cardupgrade then
abil:cssText('display: none;')
end
end
if v['type'] then
abil:addClass(format('cv-abil cv-abil-%s%s', string.lower(v['type']), v['affinity_dependency'] and '-'..string.lower(aff) or ''))
else
abil:addClass('cv-abil-none')
end
abil:wikitext(v['name'])
if not promo then
local a = 0
for i = 1, 3 do
if (v.upgrade_text and tostring(v.upgrade_text[i] or ''):len() > 0) or (type(v.cost) == 'table' and v.cost[i] ~= v.cost[i+1] or false) then
a = a + 1
end
if a ~= 0 then
abil:tag('span'):addClass(format('cv-upgradeparts cv-abil-upgrade-%s cv-A%s', a, i)):css(
'display',
(i == cardupgrade and '' or 'none')
)
end
end
end
abil:allDone()
abilities_node:node(abil)
end
end
card.abilities_node = abilities_node
end
return card.build()
end
function p.count(frame)
local args = getArgs(frame)
local i = 0
local list = get.list()
if args[1] ~= '' and args[2] ~= '' and args[1] ~= 'cardtype' then
for _,k in ipairs(list) do
if get[args[1]](k) == args[2] then
i = i + 1
end
end
else
if (args[1] == 'cardtype' and args[2] == 'cards') or args[1] == nil or args[1] == '' then
for _,k in ipairs(list) do
if not k:find '(Promo)' then i = i + 1 end
end
elseif (args[1] == 'cardtype' and args[2] == 'promos') or args[1] == nil or args[1] == '' then
for _,k in ipairs(list) do
if k:find '(Promo)' then i = i + 1 end
end
end
end
return i
end
function p.custom_card(frame)
local args = getArgs(frame)
local name = args.name or args[1] or ''
local link = args.link or ''
if args.orbs then
args.orbs = mw.text.split(args.orbs, '%s*,%s*')
for k,v in ipairs(args.orbs or {}) do
args.orbs[k] = v:gsub('^%l', string.upper)
end
end
local res = args.orbs and get.factions(name, args.orbs) or {}
local factionLR = res[1] and (res[1] ~= res[2] and res[1] .. res[2] or res[1]) or 'Blank'
local factionLeft = res[1]
local factionRight = res[2]
if args.type then args.type = args.type:gsub('^%l', string.upper) end
if args.edition then
args.edition = args.edition:gsub('^%l', string.upper)
if args.edition == 'Lost souls' then args.edition = 'Lost Souls' end
end
if args.rarity then
args.rarity = args.rarity:gsub('^%l', string.upper)
if args.rarity == 'Ultra rare' then args.rarity = 'Ultra Rare' end
end
if args.weapon_type then
args.weapon_type = args.weapon_type:gsub('^%l', string.upper)
end
if string.lower(args.affinity or 'none') == 'none' then
args.affinity = nil
end
if args.affinity then
args.affinity = args.affinity:gsub('^%l', string.upper)
end
if args.counter then
args.counter = string.upper(args.counter)
end
if args.size then
args.size = string.upper(args.size)
end
local promo_txt, promo_class
if type(args.upgrade) == 'string' then
if args.upgrade:lower() == 'promo' then
args.promo = true
args.cardupgrade = 3
args.applied_charges = 3
promo_txt = format('[[File:Promo_Icon_%s.png||link=]]', factionLeft)
end
if args.upgrade:lower() == 'starter' then
args.starter_card = true
promo_class = 'cv-upgradeparts cv-A0'
promo_txt = format('[[File:Starter_Icon_%s.png||link=]]', factionLeft)
end
if args.upgrade:lower() == 'temp'
or args.upgrade:lower() == 'temporary'
or args.upgrade:lower() == 'tome' then
args.temporary_card = true
args.cardupgrade = 3
args.applied_charges = 3
promo_txt = format('[[File:Temporary_Icon_%s.png||link=]]', factionLeft)
end
else
args.cardupgrade = args.upgrade
end
local abilities_done = mw.html.create()
for i = 1, 5 do
local abil = mw.html.create('div')
if args['ability_'..i..'_type'] and string.lower(args['ability_'..i..'_type']) ~= 'none' then
abil:addClass(format('cv-abil cv-abil-%s%s',
string.lower(args['ability_'..i..'_type']),
(args['ability_'..i..'_affinity'] == true or string.lower(args['ability_'..i..'_affinity'] or '') == 'true') and ('-'..args.affinity) or ''))
end
abil:wikitext(args['ability_'..i..'_name'] or '')
if tonumber(args['ability_'..i..'_upgrade'])
and tonumber(args['ability_'..i..'_upgrade']) > 0
and tonumber(args['ability_'..i..'_upgrade']) <= 3 then
abil:wikitext(format('[[File:Card_Icon_Upgrade_Status_0%s.png||link=]]', args['ability_'..i..'_upgrade']))
end
abil:allDone()
abilities_done:node(abil)
end
abilities_done:allDone()
local check_size = {
S = true,
M = true,
L = true,
XL = true,
}
return CardClass{
scaling = args.displayscaling or args.scaling,
affinity = args.affinity,
factionLR = factionLR,
factionLeft = factionLeft,
factionRight = factionRight,
display_name = name,
artwork_wktxt = format('[[File:%s||link=|320px]]', args.artwork),
spell_background_wktxt = args.type == 'Spell' and format('[[File:Spell_Card_Overlay_%s.png||link=]]', factionLR) or nil,
cardupgrade = args.cardupgrade,
applied_charges = args.applied_charges,
upgrade_left_1_wktxt = format('[[File:%s_Upgrade_1_Left.png||link=]]', factionLeft),
upgrade_left_2_wktxt = format('[[File:%s_Upgrade_2_Left.png||link=]]', factionLeft),
upgrade_left_3_wktxt = format('[[File:%s_Upgrade_3_Left.png||link=]]', factionLeft),
charge_left_1_wktxt = factionLeft == 'Neutral' and '[[File:Neutral_Charge_All.png||link=]]' or format('[[File:%s_Charge_1_Left.png||link=]]', factionLeft),
charge_left_2_wktxt = factionLeft == 'Neutral' and '[[File:Neutral_Charge_All.png||link=]]' or format('[[File:%s_Charge_2_Left.png||link=]]', factionLeft),
charge_left_3_wktxt = factionLeft == 'Neutral' and '[[File:Neutral_Charge_All.png||link=]]' or format('[[File:%s_Charge_3_Left.png||link=]]', factionLeft),
upgrade_right_1_wktxt = format('[[File:%s_Upgrade_1_Right.png||link=]]', factionRight),
upgrade_right_2_wktxt = format('[[File:%s_Upgrade_%s_Right.png||link=]]', factionRight, factionRight == 'Neutral' and '1' or '2'),
upgrade_right_3_wktxt = format('[[File:%s_Upgrade_%s_Right.png||link=]]', factionRight, factionRight == 'Neutral' and '1' or '3'),
charge_right_1_wktxt = factionRight == 'Neutral' and '[[File:Neutral_Charge_All.png||link=]]' or format('[[File:%s_Charge_1_Right.png||link=]]', factionRight),
charge_right_2_wktxt = factionRight == 'Neutral' and '[[File:Neutral_Charge_All.png||link=]]' or format('[[File:%s_Charge_2_Right.png||link=]]', factionRight),
charge_right_3_wktxt = factionRight == 'Neutral' and '[[File:Neutral_Charge_All.png||link=]]' or format('[[File:%s_Charge_3_Right.png||link=]]', factionRight),
promo_icon_wktxt = promo_txt,
promo_icon_class = promo_class,
orbs = args.orbs or {},
power_cost_wktxt = args.power_cost,
charges_wktxt = args.charges,
unit_size_wktxt = check_size[args.size or 'Nope'] and format('[[File:Card_Icon_Unit_Size_%s.png||link=]]', args.size) or nil,
squadsize = args.squadsize,
class = args.class,
damage_wktxt = args.damage,
weapon_type_wktxt = (args.weapon_type and args.type ~= 'Spell') and format(
'[[File:Card_Icon_%s%s.png||link=]]',
args.weapon_type,
(check_size[args.counter or 'Nope'] and args.weapon_type ~= 'Special') and format('_Unit_Countering_Size_%s', args.counter) or (args.weapon_type ~= 'Special' and '_Unit' or ''),
link
) or ((not args.weapon_type and check_size[args.counter or 'Nope'] and args.type ~= 'Spell') and format('<span style="padding-left: 14px;">[[File:Card_Icon_Unit_Size_%s.png||link=]]</span>', args.counter)),
health_wktxt = args.health,
edition = args.edition,
rarity = args.rarity,
notooltip = true,
abilities_node = abilities_done,
}.build()
end
--- returns a list of cards formatted as a deck display
---@param frame table mw.frame object
---@return string deck as mw.html
---@public
function p.deck(frame)
local args = getArgs(frame)
local res = mw.html.create('div'):cssText('display:flex;flex-wrap:wrap;')
if args.maxperrow then
res:cssText(
format(
'max-width:100%%;width:calc(%spx * %s);',
args.icononly and 82 * (tonumber(args.scaling) or tonumber(args.displayscaling) or 1) or 370 * (tonumber(args.scaling) or tonumber(args.displayscaling) or 0.23),
args.maxperrow
)
)
end
for i = 1, 20 do
local t = mw.text.split(args[i] or '', ';', true)
if t[1] ~= '' then
if args.icononly then
res:node(
p.icon{
t[1],
size = format('%spx', (args.scaling or args.displayscaling or 1) * 80),
icononly = true,
nolink = args.nolink == true and true or false,
}
)
else
res:node(
p.card{
t[1],
cardupgrade = tonumber(t[2] or 0),
applied_charges = tonumber(t[3] or 0),
scaling = args.scaling or args.displayscaling or '0.23',
nolink = args.nolink == true and true or false,
}
)
end
end
end
return res
end
function p.for_each(frame)
local args = getArgs(frame)
local list = get.list()
local result
if args[1] == 'list_of_card_ids' then
result = mw.html.create()
for k,v in ipairs(list) do
local id = get.card_id(v) or 0
local ci = p.icon{v}
local id0 = tostring(id)
local id1 = string.format("1%06d", id)
local id2 = string.format("2%06d", id)
local id3 = string.format("3%06d", id)
result:tag('tr'):addClass('search-item'):attr('data-search', v..id0)
:tag('td'):node(ci):done()
:tag('td'):wikitext(id0):done()
:tag('td'):wikitext(id1):done()
:tag('td'):wikitext(id2):done()
:tag('td'):wikitext(id3):done()
:done()
end
elseif args[1] == 'list_of_card_upgrade_drop_locations' then
result = mw.html.create()
for k,v in ipairs(list) do
local ci = p.icon{v}
local drops = get.upgrade_locations(v)
local ed = get.edition(v)
local ra = get.rarity(v)
local raso = 0
if ra == 'Common' then raso = 1 elseif ra == 'Uncommon' then raso = 2 elseif ra == 'Rare' then raso = 3 elseif ra == 'Ultra Rare' then raso = 4 end
if drops then
local d1 = drops[1] or ''
local d2 = drops[2] or ''
local d3 = drops[3] or ''
local dd1 = drops[1] and format('[[File:%s_Minimap.jpg|20px|link=%s]] [[%s]]', d1, d1, d1) or ''
local dd2 = drops[2] and format('[[File:%s_Minimap.jpg|20px|link=%s]] [[%s]]', d2, d2, d2) or ''
local dd3 = drops[3] and format('[[File:%s_Minimap.jpg|20px|link=%s]] [[%s]]', d3, d3, d3) or ''
local search = v..d1
if d2 ~= d1 then search = search..d2 end
if d3 ~= d2 and d3 ~= d1 then search = search..d3 end
result:tag('tr'):addClass('search-item'):attr('data-search', search)
:tag('td'):node(ci):done()
:tag('td'):attr('data-sort-value', raso):attr('title', ra):wikitext(format('[[File:Edition Icon %s %s.png|x22px|link=]]', ed, ra)):done()
:tag('td'):wikitext(dd1):done()
:tag('td'):wikitext(dd2):done()
:tag('td'):wikitext(dd3):done()
:done()
end
end
elseif args[1] == 'list_of_booster_pack_contents' then
result = mw.html.create()
local counter = { [1] = 0, [2] = 0, [3] = 0, [4] = 0, [5] = 0, [6] = 0, [7] = 0, [8] = 0, [9] = 0, [10] = 0, [11] = 0 }
for k,v in ipairs(list) do
local name = v:gsub(' %(Fire%)', ''):gsub(' %(Frost%)', ''):gsub(' %(Nature%)', ''):gsub(' %(Shadow%)', '')
local ci = p.icon{[1] = v, ['hide_affinity'] = true}
local packs = get.boosters(v)
local p0,p1,p2,p3,p4,p5,p6,p7,p8,p9,p10 = 'X','X','X','X','X','X','X','X','X','X','X'
local c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10 = 'nay','nay','nay','nay','nay','nay','nay','nay','nay','nay','nay'
local search = name
if packs[1] then
p0 = '✔'
c0 = 'yea'
counter[1] = counter[1] + 1
else
search = search..'None'
end
for _,pack in ipairs(packs) do
search = search .. pack
if pack == 'Fire' then
p1 = '✔'
c1 = 'yea'
counter[2] = counter[2] + 1
elseif pack == 'Frost' then
p2 = '✔'
c2 = 'yea'
counter[3] = counter[3] + 1
elseif pack == 'Nature' then
p3 = '✔'
c3 = 'yea'
counter[4] = counter[4] + 1
elseif pack == 'Shadow' then
p4 = '✔'
c4 = 'yea'
counter[5] = counter[5] + 1
elseif pack == 'Amii' then
p5 = '✔'
c5 = 'yea'
counter[6] = counter[6] + 1
elseif pack == 'Bandits' then
p6 = '✔'
c6 = 'yea'
counter[7] = counter[7] + 1
elseif pack == 'Fire/Frost' then
p7 = '✔'
c7 = 'yea'
counter[8] = counter[8] + 1
elseif pack == 'Lost Souls' then
p8 = '✔'
c8 = 'yea'
counter[9] = counter[9] + 1
elseif pack == 'Stonekin' then
p9 = '✔'
c9 = 'yea'
counter[10] = counter[10] + 1
elseif pack == 'Twilight' then
p10 = '✔'
c10 = 'yea'
counter[11] = counter[11] + 1
end
end
result:tag('tr'):addClass('search-item'):attr('data-search', search)
:tag('td'):node(ci):done()
:tag('td'):addClass(c0):wikitext(p0):done()
:tag('td'):addClass(c1):wikitext(p1):done()
:tag('td'):addClass(c2):wikitext(p2):done()
:tag('td'):addClass(c3):wikitext(p3):done()
:tag('td'):addClass(c4):wikitext(p4):done()
:tag('td'):addClass(c5):wikitext(p5):done()
:tag('td'):addClass(c6):wikitext(p6):done()
:tag('td'):addClass(c7):wikitext(p7):done()
:tag('td'):addClass(c8):wikitext(p8):done()
:tag('td'):addClass(c9):wikitext(p9):done()
:tag('td'):addClass(c10):wikitext(p10):done()
:done()
end
result = mw.html.create():tag('tr'):addClass('tr-force-show')
:tag('th'):cssText('width: 30%; text-align:left; background-color: #092949'):wikitext('Card Name'):done()
:tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:General Booster Pack HD.png|40px|link=]]'):attr('title', 'General Booster Pack (Card Pool: '..counter[1]..')'):done()
:tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Fire Booster Pack HD.png|40px|link=]]'):attr('title', 'Fire Booster Pack (Card Pool: '..counter[2]..')'):done()
:tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Frost Booster Pack HD.png|40px|link=]]'):attr('title', 'Frost Booster Pack (Card Pool: '..counter[3]..')'):done()
:tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Nature Booster Pack HD.png|40px|link=]]'):attr('title', 'Nature Booster Pack (Card Pool: '..counter[4]..')'):done()
:tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Shadow Booster Pack HD.png|40px|link=]]'):attr('title', 'Shadow Booster Pack (Card Pool: '..counter[5]..')'):done()
:tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Amii Booster Pack HD.png|40px|link=]]'):attr('title', 'Amii Booster Pack (Card Pool: '..counter[6]..')'):done()
:tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Bandits Booster Pack HD.png|40px|link=]]'):attr('title', 'Bandits Booster Pack (Card Pool: '..counter[7]..')'):done()
:tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Fire Frost Booster Pack HD.png|40px|link=]]'):attr('title', 'Fire Frost Booster Pack (Card Pool: '..counter[8]..')'):done()
:tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Lost Souls Booster Pack HD.png|40px|link=]]'):attr('title', 'Lost Souls Booster Pack (Card Pool: '..counter[9]..')'):done()
:tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Stonekin Booster Pack HD.png|40px|link=]]'):attr('title', 'Stonekin Booster Pack (Card Pool: '..counter[10]..')'):done()
:tag('th'):cssText('width: 6%; background-color: #092949; padding: 0 6px; text-align: center'):wikitext('[[File:Twilight Booster Pack HD.png|40px|link=]]'):attr('title', 'Twilight Booster Pack (Card Pool: '..counter[11]..')'):done()
:done():node(result:done()):done()
end
return result
end
--- returns values from Card/data for a card
---@param frame table mw.frame object
---@return string value from card
---@public
function p.get(frame)
local args = getArgs(frame)
local cardname = (args[2]:find('affini')) and args[1] or get.verified_name(args[1])
local val = args[2]
local returntype = args[3]
-- 'return' one of: array, count, 'index' (eg 1).
-- nil returns default (tables as array (wikitext-string separated by ';'), single value as single value)
if not get[val] then
return format('No getter for %s', val)
end
-- if not get['card'](cardname) then return format('Card %s not found (fn 'get')', cardname) end
--if not get[val](cardname, cardtype) then return format('Value %s not found for %s (%s)', val, cardname, get[val](cardname, cardtype)) end
local returnval = cardname == 'list' and get.list() or get[val](cardname)
if returnval == nil then
return format('Card %s or value %s not found (fn "get")', cardname, val)
end
if returntype == 'count' then
local i = 0
for _ in pairs(returnval or {}) do
i = i + 1
end
return i
elseif returntype == 'array' then
if not type(returnval) == 'table' then
return format('Value %s not an array (lua table)', val)
end
return concat(returnval, '; ')
elseif type(returntype) == 'number' and returntype == math.floor(returntype) and returntype < 10 then
return returnval[tonumber(returntype)]
else
-- Something's not workin' here
if type(returnval) == 'table' then
return concat(returnval, '; ')
elseif type(returnval) == 'string' or type(returnval) == 'number' or type(returnval) == 'boolean' then
return returnval
else
return 'Something went wrong. Check: card, value, return and Module:Card/data'
end
end
end
--- check if card has value
---@param frame table mw.frame object
---@return boolean true if card/data contains value for card; else nothing
---@public
function p.has(frame)
local args = getArgs(frame)
if has[args[2]] and has[args[2]](args[1]) then
return true
end
local cardname = args[2]:find('affini') and args[1] or get.verified_name(args[1])
if get[args[2]] and get[args[2]](cardname) then
return true
end
end
--- returns the content for Template:Card_icon
---@param frame table mw.frame object
---@return string icon_text or icon as mw.html
---@public
function p.icon(frame)
local args = getArgs(frame)
local n, v = string.find(args[1], ' (', 1, true)
local name, _ = (n == nil and args[1] or string.sub(args[1], 1, (n or 0) - 1)), nil
local var, _ = string.gsub(string.sub(args[1], (v or 0) + 1), '%)', '')
local ran, val_or_err = pcall(get.verified_name, format('%s%s', name, var == 'Twilight' and ' (Twilight)' or var == 'Lost Souls' and ' (Lost Souls)' or var == 'Superpig' and ' (Superpig)' or ''))
if not ran then
return format('<span style="cursor:help; border-bottom:1px dotted; color: red;" title="Error: Card "%s" not found">Error</span>', name or '')
end
local firstfile = ''
if var == 'Promo' then
firstfile = '_(Promo)'
elseif var == 'Twilight' then
firstfile = '_(Twilight)'
elseif var == 'Lost Souls' then
firstfile = '_(Lost_Souls)'
elseif var == 'Superpig' then
firstfile = '_(Superpig)'
end
local linkdest = args.nolink == true and '' or (name == 'Mo' and 'Mo#Card' or (var ~= 'Promo' and format('%s%s', name, firstfile) or name))
local size = math.floor(string.gsub(args.size or '20px', 'px', '') + 0.5)
local aff = false
if not args['hide_affinity'] and (var == 'Fire' or var == 'Frost' or var == 'Nature' or var == 'Shadow') then
aff = true
end
local linktext = name
if args[2] ~= nil and args[2] ~= '' then
linktext = args[2]
elseif var ~= name then
linktext = format('%s (%s)', linktext, var)
end
local span = mw.html.create('span'):addClass('card-icon custom-tooltip'):attr('data-tt-type', 'card'):attr('data-1', args[1])
local span_icon = mw.html.create('span'):wikitext(format('[[File:%s%s_Card_Icon.png|%spx|border|link=%s]]', name, firstfile, size, linkdest))
if aff then
span_icon:tag('span'):wikitext(format('[[File:Affinity_Orb_%s.png|%spx|link=%s]]', var, math.floor(size * 0.4 + 0.5), linkdest))
end
span:node(span_icon:allDone())
if not args.icononly then
span:wikitext(format(' [[%s|%s]]', linkdest, linktext))
end
return span:done()
end
function p.infobox(frame)
local args = getArgs(frame)
local vname, _, _ = get.verified_name(args[1])
return frame:expandTemplate{
title = 'Infobox card',
args = {
name = args[1],
artwork = format('[[File:%s_Card_Artwork.png|link=]]', args[1]),
card_type = get.type(vname) or nil,
faction = get.faction(vname) == 'Neutral' and 'None (Neutral / Legendary)' or get.faction(vname),
class = get.class(vname) or nil,
has_normal = has.normal(args[1]) or nil,
has_promo = has.promo(args[1]) or nil,
affinity1 = has.affinities(args[1]) and get.affinity_variants(args[1])[1] or nil,
affinity2 = has.affinities(args[1]) and get.affinity_variants(args[1])[2] or nil,
power_cost = type(get.power_cost(vname)) == 'table' and frame:expandTemplate{title = 'pu', args={get.power_cost(vname)[1], get.power_cost(vname)[2], get.power_cost(vname)[3], get.power_cost(vname)[4]}} or get.power_cost(vname),
orbs = get.orbs(vname) and concat(get.orbs(vname), ', ') or nil,
charges = has.nonpromo(vname) and frame:expandTemplate{title = 'pc', args={get.charges(vname)}} or get.charges(vname),
squadsize = get.squadsize(vname),
damage_bonus = get.counter(vname),
damage = type(get.damage(vname)) == 'table' and frame:expandTemplate{title = 'pu', args={get.damage(vname)[1], get.damage(vname)[2], get.damage(vname)[3], get.damage(vname)[4]}} or get.damage(vname),
size = get.size(vname),
gender = get.gender(vname),
booster = concat(get.boosters(vname), ', '),
card_id = get.card_id(args[1]),
card_id_fire = get.card_id(args[1]..' (Fire)'),
card_id_frost= get.card_id(args[1]..' (Frost)'),
card_id_nature= get.card_id(args[1]..' (Nature)'),
card_id_shadow= get.card_id(args[1]..' (Shadow)'),
card_id_promo= get.card_id(args[1]..' (Promo)'),
movement_speed = get.type(vname) == 'Unit' and (type(get.movement_speed(vname)) == 'table' and frame:expandTemplate{title = 'pu', args={get.movement_speed(vname)[1], get.movement_speed(vname)[2], get.movement_speed(vname)[3], get.movement_speed(vname)[4]}} or get.movement_speed(vname)) or nil,
construction_time = get.type(vname) == 'Building' and (type(get.construction_time(vname)) == 'table' and frame:expandTemplate{title = 'pu', args={get.construction_time(vname)[1], get.construction_time(vname)[2], get.construction_time(vname)[3], get.construction_time(vname)[4]}} or get.construction_time(vname)) or nil,
health = type(get.health(vname)) == 'table' and frame:expandTemplate{title = 'pu', args={get.health(vname)[1], get.health(vname)[2], get.health(vname)[3], get.health(vname)[4]}} or get.health(vname),
edition = get.edition(vname),
rarity = get.rarity(vname)
}
}
end
--- returns a filtered list of cards
---@param frame table mw.frame object
---@return string list of cards as mw.html
---@public
function p.list(frame)
local args = getArgs(frame)
local list = get.list()
local cardcount = 0
local div = args.ci == true and mw.html.create() or mw.html.create('div'):addClass('list-of-cards'..(args.filter and ' collapsed' or '')):attr('id', args.filter and 'card-grid' or ''):css{
['display'] = 'flex',
['flex-wrap'] = 'wrap',
['justify-content'] = 'center',
['overflow'] = 'hidden',
['max-height'] = args.filter and '500px' or nil,
['margin'] = '0 -1px',
}
if args[1] ~= '' and args[2] ~= '' and args[1] ~= 'cardtype' then
for i,k in ipairs(list) do
if get[args[1]](k) == args[2] then
cardcount = cardcount + 1
if args.ci == true then
div:wikitext('\n* '):node(p.icon{k})
else
div:node(p.card{k, filter=args.filter, scaling=0.5487})
end
end
end
else
if (args[1] == 'cardtype' and args[2] == 'all') or args[1] == nil or args[1] == '' then
for _,k in ipairs(list) do
cardcount = cardcount + 1
div:node(p.card{k, filter=args.filter, scaling=0.5487})
end
elseif (args[1] == 'cardtype' and args[2] == 'cards') or args[1] == nil or args[1] == '' then
for _,k in ipairs(list) do
if not k:find '(Promo)' then
cardcount = cardcount + 1
div:node(p.card{k, filter=args.filter, scaling=0.5487})
end
end
elseif (args[1] == 'cardtype' and args[2] == 'promos') or args[1] == nil or args[1] == '' then
for _,k in ipairs(list) do
if k:find '(Promo)' then
cardcount = cardcount + 1
div:node(p.card{k, filter=args.filter, scaling=0.5487})
end
end
end
end
if args.filter then
local filterContainer = mw.html.create('div'):attr('id', 'grid-filter-container'):cssText('background-color:#060e1f;padding:0.5rem')
local arg1 = tostring(args[1] or ''):lower()
local arg2 = tostring(args[2] or ''):lower()
filterContainer:addClass('hide-'..arg1)
if arg1 == 'faction' then
if arg2 == 'fire' then
filterContainer:addClass('hide-frost hide-nature hide-shadow')
elseif arg2 == 'frost' then
filterContainer:addClass('hide-fire hide-nature hide-shadow')
elseif arg2 == 'nature' then
filterContainer:addClass('hide-fire hide-frost hide-shadow')
elseif arg2 == 'shadow' then
filterContainer:addClass('hide-fire hide-frost hide-nature')
elseif arg2 == 'neutral' or arg2 == 'legendary' then
filterContainer:addClass('hide-fire hide-frost hide-nature hide-shadow')
elseif arg2 == 'amii' then
filterContainer:addClass('hide-fire hide-frost')
elseif arg2 == 'bandits' then
filterContainer:addClass('hide-nature hide-shadow')
elseif arg2 == 'lost souls' then
filterContainer:addClass('hide-fire hide-nature')
elseif arg2 == 'stonekin' then
filterContainer:addClass('hide-fire hide-shadow')
elseif arg2 == 'twilight' then
filterContainer:addClass('hide-frost hide-shadow')
end
end
div:attr('data-card-count', tostring(cardcount))
:tag('div')
:attr('id', 'grid-matches')
:attr('title', 'If applicable, this count includes affinity and promo variants.')
:wikitext((cardcount)..' matching cards')
:allDone()
return filterContainer
:tag('div'):attr('id', 'grid-filter-buttons')
:tag('div'):attr('id', 'grid-filter-orbs-wrapper')
:tag('div'):cssText('font-size: 15px; font-weight: 700'):wikitext('Orbs'):done()
:tag('div'):attr('id', 'grid-filter-orbs'):cssText('display: flex'):done()
:done()
:tag('div'):attr('id', 'grid-filter-orbsamount-wrapper')
:tag('div'):cssText('font-size: 15px; font-weight: 700'):wikitext('Number of Orbs'):done()
:tag('div'):attr('id', 'grid-filter-orbsamount'):cssText('display: flex'):done()
:done()
:tag('div'):attr('id', 'grid-filter-type-wrapper')
:tag('div'):cssText('font-size: 15px; font-weight: 700'):wikitext('Type'):done()
:tag('div'):attr('id', 'grid-filter-type'):cssText('display: flex'):done()
:done()
:tag('div'):attr('id', 'grid-filter-rarity-wrapper')
:tag('div'):cssText('font-size: 15px; font-weight: 700'):wikitext('Rarity'):done()
:tag('div'):attr('id', 'grid-filter-rarity'):cssText('display: flex'):done()
:done()
:done()
:tag('div'):attr('id', 'grid-filter-dropdowns')
:tag('div'):attr('id', 'grid-filter-search'):attr('data-placeholder', 'Search...'):done()
:tag('div'):attr('id', 'grid-filter-affinities'):done()
:tag('div'):attr('id', 'grid-filter-edition'):done()
:tag('div'):attr('id', 'grid-filter-faction'):done()
:tag('div'):attr('id', 'grid-filter-counter'):done()
:tag('div'):attr('id', 'grid-filter-size'):done()
:tag('div'):attr('id', 'grid-filter-weapontype'):done()
:tag('div'):attr('id', 'grid-filter-special'):done()
:tag('div'):attr('id', 'grid-filter-sort'):done()
:tag('div'):attr('id', 'grid-filter-reset'):done()
:done()
:node(div)
:tag('div'):attr('id', 'grid-collapse')
:allDone()
else
return div:done()
end
end
function p.map_drops(frame)
local args = getArgs(frame)
local res = get.map_drops(args[1], args[2])
if args[3] == 'list' then
local res2 = mw.html.create('ul')
for i=1, #res do
res2:tag('li'):node(p.icon{res[i]}):done()
end
return res2
elseif args[3] == 'count' then
return #res
else
return concat(res, ';')
end
end
function p.navigation(frame)
local list = get.list()
local cardcount = 0
local previous_card
local height = '230px'
if frame:getParent()['args'] and frame:getParent()['args']['mainpage'] then
height = '400px'
end
local grid = mw.html.create('div'):attr('id', 'card-grid'):css{['max-height'] = height}:addClass('lazyimg-wrapper collapsed')
for k,v in ipairs(list) do
cardcount = k
local name, _ = v:gsub(' %(Fire%)', ''):gsub(' %(Frost%)', ''):gsub(' %(Nature%)', ''):gsub(' %(Shadow%)', ''):gsub(' %(Promo%)', ''):gsub(' %(Superpig%)', '')
if name ~= previous_card then
local data_orbs = get.orbs(v)
local orbs = { data_orbs[1], data_orbs[2], data_orbs[3], data_orbs[4] }
local non_legendary = (function() for _,v in ipairs(orbs) do if v and v~='Neutral' then return true end end end)()
local affinities = get.affinity_variants(name) or {}
if affinities[1] then
affinities[#affinities+1] = 'All'
else
affinities[1] = 'None'
end
local cost = get.power_cost(v)
local faction = get.faction(v)
local faction = faction == 'Neutral' and 'Legendary' or faction
grid:tag('span')
:addClass('grid-icon custom-tooltip')
:attr('data-tt-type', 'card')
:attr('data-1', name)
:attr('data-search', name)
:attr('data-rarity', get.rarity(v))
:attr('data-cost', type(cost) == 'table' and cost[1] or cost or 0)
:attr('data-edition', get.edition(v))
:attr('data-faction', faction)
:attr('data-counter', get.counter(v))
:attr('data-weapontype', get.weapon_type(v))
:attr('data-special', (has.promo(name) and 'Promo' or '') ..','.. (has.starter_card(name) and 'Starter' or '')..','..(has.normal(name) and 'Normal' or '')..','..(non_legendary and 'Non-Legendary' or ''))
:attr('data-orbs', concat(orbs, ','))
:attr('data-orbsamount', #orbs)
:attr('data-affinities', concat(affinities, ','))
:attr('data-size', get.size(v))
:attr('data-type', get.type(v))
:wikitext(format('[[File:%s_Card_Icon.png|56px|alt=%s|link=%s]]', name, name, name))
:done()
end
previous_card = name
end
grid:attr('data-card-count', tostring(cardcount))
:tag('div')
:attr('id', 'grid-matches')
:attr('title', 'If applicable, this count includes affinity and promo variants.')
:wikitext((cardcount - 1)..' matching cards')-- minus QueekQueek (Superpig)
:allDone()
return mw.html.create('div'):attr('id', 'grid-filter-container')
:tag('div'):attr('id', 'grid-filter-buttons')
:tag('div')
:tag('div'):cssText('font-size: 15px; font-weight: 700'):wikitext('Orbs'):done()
:tag('div'):attr('id', 'grid-filter-orbs'):cssText('display: flex'):done()
:done()
:tag('div')
:tag('div'):cssText('font-size: 15px; font-weight: 700'):wikitext('Number of Orbs'):done()
:tag('div'):attr('id', 'grid-filter-orbsamount'):cssText('display: flex'):done()
:done()
:tag('div')
:tag('div'):cssText('font-size: 15px; font-weight: 700'):wikitext('Type'):done()
:tag('div'):attr('id', 'grid-filter-type'):cssText('display: flex'):done()
:done()
:tag('div')
:tag('div'):cssText('font-size: 15px; font-weight: 700'):wikitext('Rarity'):done()
:tag('div'):attr('id', 'grid-filter-rarity'):cssText('display: flex'):done()
:done()
:done()
:tag('div'):attr('id', 'grid-filter-dropdowns')
:tag('div'):attr('id', 'grid-filter-search'):attr('data-placeholder', 'Search...'):done()
:tag('div'):attr('id', 'grid-filter-affinities'):done()
:tag('div'):attr('id', 'grid-filter-edition'):done()
:tag('div'):attr('id', 'grid-filter-faction'):done()
:tag('div'):attr('id', 'grid-filter-counter'):done()
:tag('div'):attr('id', 'grid-filter-size'):done()
:tag('div'):attr('id', 'grid-filter-weapontype'):done()
:tag('div'):attr('id', 'grid-filter-special'):done()
:tag('div'):attr('id', 'grid-filter-sort'):done()
:tag('div'):attr('id', 'grid-filter-reset'):done()
:done()
:node(grid)
:tag('div'):attr('id', 'grid-collapse')
:allDone()
end
function p.progression_charges(frame)
local args = getArgs(frame)
if not args.index and not args[1] then return 'Missing max charge value' end
local rule = chargeRules(tonumber(args.index or args[1]))
if not rule then return 'Value '..(args.index or args[1])..' not found in ruleset' end
return frame:expandTemplate{title = 'p', args = {
[1] = rule[1],
[2] = 'No extra charges applied',
[3] = rule[1] + rule[2],
[4] = '1 extra charge applied',
[5] = rule[1] + rule[2] + rule[3],
[6] = '2 extra charges applied',
[7] = rule[1] + rule[2] + rule[3] + rule[4],
[8] = '3 extra charges applied',
texttip = 'true'
}}
end
function p.upgrade(frame)
local args = getArgs(frame)
local upgrade = args.upgrade or args.cardupgrade or 0
if upgrade == 0 or upgrade > 3 then return 'upgrade needs to be 1, 2 or 3' end
local name = args.name or args[1] or 'Name missing'
local display_name, aff, promo = verifyName(args.name or args[1] or 'Name missing')
local res = get.orbs(name) and get.factions(name, get.orbs(name)) or nil
local factionLR = res and (res[1] ~= res[2] and res[1] .. res[2] or res[1]) or 'Blank'
local factionLeft = res and res[1] or nil
local factionRight = res and res[2] or nil
local description = mw.html.create('div')
local general = get.general_upgrade_text(name)
if general and (general[upgrade] or '') ~= '' then
description:tag('div'):cssText('margin-left:5px;margin-right:10px;line-height:25px;white-space:pre-line'):wikitext(general[upgrade]):done()
end
local abilities = get.abilities(name)
local has_autocast = false
for _,v in ipairs(abilities) do
if v.type == 'Autocast' then has_autocast = true end
end
local cost, dmg, hp = get.power_cost(name), get.damage(name), get.health(name)
if type(cost) == 'table' and cost[upgrade] ~= cost[upgrade+1] then
description:tag('div'):cssText('margin-left:5px;margin-right:10px;line-height:25px'):wikitext((cost[upgrade+1] > cost[upgrade] and '+' or '-') .. math.abs(cost[upgrade+1] - cost[upgrade]) .. ' power cost'):done()
end
if not has_autocast and type(dmg) == 'table' and dmg[upgrade] ~= dmg[upgrade+1] then
local s = get.squadsize(name) or 1
local u = s ~= 1 and (tostring(math.abs(dmg[upgrade+1] - dmg[upgrade]) / s) .. 'x' .. tostring(s)) or math.abs(dmg[upgrade+1] - dmg[upgrade])
description:tag('div'):cssText('margin-left:5px;margin-right:10px;line-height:25px'):wikitext('Damage ' .. (dmg[upgrade+1] > dmg[upgrade] and '+' or '-') .. u):done()
end
if type(hp) == 'table' and hp[upgrade] ~= hp[upgrade+1] then
local s = get.squadsize(name) or 1
local u = s ~= 1 and (tostring(math.abs(hp[upgrade+1] - hp[upgrade]) / s) .. 'x' .. tostring(s)) or math.abs(hp[upgrade+1] - hp[upgrade])
description:tag('div'):cssText('margin-left:5px;margin-right:10px;line-height:25px'):wikitext('Lifepoints ' .. (hp[upgrade+1] > hp[upgrade] and '+' or '-') .. u):done()
end
for _,v in ipairs(abilities) do
local from, to = 0, 9
local at = v.upgrade_availability or {}
if at[4] then from = 3 end
if at[3] then from = 2 end
if at[2] then from = 1 end
if at[3] and not at[4] then to = 3 end
if at[2] and not at[3] then to = 2 end
if at[1] and not at[2] then to = 1 end
local learned = from > 0 and upgrade == from
local unlearned = upgrade == to
local cost_change
if not learned and not unlearned and type(v.cost) == 'table' then
if v.cost[upgrade] ~= v.cost[upgrade+1] then
cost_change = (v.cost[upgrade+1] < v.cost[upgrade] and '-' or '+') .. math.abs(v.cost[upgrade+1] - v.cost[upgrade])
end
end
if (v.upgrade_text and (v.upgrade_text[upgrade] or '') ~= '') or learned or unlearned or cost_change then
local abil = mw.html.create('div'):cssText('line-height:25px')
local upgrade_count = 0
local cost = v.cost
if type(v.upgrade_text) == 'table' or type(cost) == 'table' then
if upgrade >= 1 and ((type(v.upgrade_text) == 'table' and (v.upgrade_text[1] or '') ~= '') or (type(cost) == 'table' and cost[1] ~= cost[2])) then
upgrade_count = upgrade_count + 1
end
if upgrade >= 2 and ((type(v.upgrade_text) == 'table' and (v.upgrade_text[2] or '') ~= '') or (type(cost) == 'table' and cost[2] ~= cost[3])) then
upgrade_count = upgrade_count + 1
end
if upgrade >= 3 and ((type(v.upgrade_text) == 'table' and (v.upgrade_text[3] or '') ~= '') or (type(cost) == 'table' and cost[3] ~= cost[4])) then
upgrade_count = upgrade_count + 1
end
end
if v.type then
abil:addClass(format('cv-abil cv-abil-%s%s', string.lower(v.type), v.affinity_dependency and '-'..string.lower(aff) or ''))
else
abil:addClass('cv-abil-none')
end
abil:wikitext(v.name)
if from < upgrade and not (learned or unlearned) then
abil:tag('span')
:cssText('margin-top:3px')
:addClass(format('cv-upgradeparts cv-abil-upgrade-%s', upgrade_count))
:done()
end
description:node(abil:done())
if learned or unlearned then
description:tag('div'):cssText('margin-left:5px;margin-right:10px;line-height:25px'):wikitext((learned and '+' or '-')..v.name):done()
end
if cost_change then
description:tag('div'):cssText('margin-left:5px;margin-right:10px;line-height:25px'):wikitext(cost_change .. ' power cost'):done()
end
if v.upgrade_text and (v.upgrade_text[upgrade] or '') ~= '' then
description:tag('div'):cssText('margin-left:5px;margin-right:10px;line-height:25px;white-space:pre-line'):wikitext(v.upgrade_text[upgrade]):done()
end
end
end
return CardClass{
is_upgrade = true,
scaling = args.scaling or args.displayscaling or nil,
--TODO: notooltip = args.notooltip or false,
notooltip = true,
link = (args.nolink or link == '') and nil or display_name,
full_name = display_name,
display_name = display_name:gsub(' %(Lost Souls%)', ''):gsub(' %(Twilight%)', ''):gsub(' %(Superpig%)', ''),
artwork_wktxt = format('[[File:%s_Card_Artwork.png||link=]]', display_name),
factionLR = factionLR,
factionLeft = factionLeft,
factionRight = factionRight,
affinity = aff,
abilities_node = description:allDone(),
cardupgrade = upgrade,
upgrade_left_1_wktxt = format('[[File:%s_Upgrade_1_Left.png||link=]]', factionLeft),
upgrade_left_2_wktxt = format('[[File:%s_Upgrade_2_Left.png||link=]]', factionLeft),
upgrade_left_3_wktxt = format('[[File:%s_Upgrade_3_Left.png||link=]]', factionLeft),
upgrade_right_1_wktxt = format('[[File:%s_Upgrade_1_Right.png||link=]]', factionRight),
upgrade_right_2_wktxt = format('[[File:%s_Upgrade_%s_Right.png||link=]]', factionRight, factionRight == 'Neutral' and '1' or '2'),
upgrade_right_3_wktxt = format('[[File:%s_Upgrade_%s_Right.png||link=]]', factionRight, factionRight == 'Neutral' and '1' or '3'),
}.build()
end
return p