Difference between revisions of "Module:Adventurer"

From Dragalia Lost Wiki
Jump to navigation Jump to search
>Eave
m (fixing max stat tooltip arguments)
>Caledor92
 
(91 intermediate revisions by 3 users not shown)
Line 25: Line 25:
 
   })[1]
 
   })[1]
 
   if coability then
 
   if coability then
     coability = coability['Name']
+
     coability = coability['Id']
 +
  end
 +
  -- Chain CoAbility
 +
  local ccoability = getChainCoab({
 +
    where = string.format('Id="%s"', adv['ExAbility2Data1']),
 +
    groupBy = '_pageName',
 +
    limit = 1
 +
  })[1]
 +
  if ccoability then
 +
    ccoability = ccoability['Id']
 
   end
 
   end
 
   -- Abilities
 
   -- Abilities
   local abilityKeys = {'Abilities11', 'Abilities12', 'Abilities13', 'Abilities21', 'Abilities22', 'Abilities31', 'Abilities32'}
+
   local abilityKeys = {'Abilities11', 'Abilities12', 'Abilities13', 'Abilities21', 'Abilities22', 'Abilities23', 'Abilities31', 'Abilities32', 'Abilities33'}
 
   local abilities = {}
 
   local abilities = {}
 
   for i, key in ipairs(abilityKeys) do
 
   for i, key in ipairs(abilityKeys) do
Line 39: Line 48:
 
       })[1]
 
       })[1]
 
       if ability then
 
       if ability then
         abilities[key] = ability['Name']
+
         abilities[key] = ability['Id']
 
       end
 
       end
 
     end
 
     end
Line 46: Line 55:
 
   -- Precompute some template outputs
 
   -- Precompute some template outputs
 
   -- Portrait Image
 
   -- Portrait Image
   local portraitFileName = string.format('%s 0%s r0%s portrait.png', adv['Id'], adv['VariationId'], adv['Rarity'])
+
   local portraitFileName = string.format('%s 0%s r05 portrait.png', adv['Id'], adv['VariationId'])
 
   local portraitImage = mw.title.makeTitle('File', portraitFileName)
 
   local portraitImage = mw.title.makeTitle('File', portraitFileName)
 
   if (portraitImage.exists) then
 
   if (portraitImage.exists) then
Line 54: Line 63:
 
   end
 
   end
 
   -- Description
 
   -- Description
   local maxhp = adv['MaxHp'] + adv['PlusHp0'] + adv['PlusHp1'] + adv['PlusHp2'] + adv['PlusHp3'] + adv['PlusHp4'] + adv['McFullBonusHp5']
+
   local mcPlusHp = adv['PlusHp0'] + adv['PlusHp1'] + adv['PlusHp2'] + adv['PlusHp3'] + adv['PlusHp4']
   local maxatk = adv['MaxAtk'] + adv['PlusAtk0'] + adv['PlusAtk1'] + adv['PlusAtk2'] + adv['PlusAtk3'] + adv['PlusAtk4'] + adv['McFullBonusAtk5']
+
   local mcPlusAtk = adv['PlusAtk0'] + adv['PlusAtk1'] + adv['PlusAtk2'] + adv['PlusAtk3'] + adv['PlusAtk4']
 
   local description =
 
   local description =
       frame:expandTemplate{title='TermDescription', args={'Element', frame:expandTemplate{title='InlineIcon', args={'Icon Element', adv['ElementalType'], adv['ElementalType']}}}}..
+
       termDescription({'Element', inlineIconAndDesc({'Icon Element', adv['ElementalType']}, adv['ElementalType'])})..
       frame:expandTemplate{title='TermDescription', args={'Weapon', frame:expandTemplate{title='InlineIcon', args={'Icon Weapon', adv['WeaponType'], adv['WeaponType']}}}}..
+
       termDescription({'Weapon', inlineIconAndDesc({'Icon Weapon', adv['WeaponType']}, adv['WeaponType'])})..
       maxStatsTooltip('HP', adv['MaxHp'], maxhp)..
+
       maxStatsTooltip('HP', adv['MaxHp'], mcPlusHp, adv['McFullBonusHp5'])..
       maxStatsTooltip('Str', adv['MaxAtk'], maxatk)..
+
       maxStatsTooltip('Str', adv['MaxAtk'], mcPlusAtk, adv['McFullBonusAtk5'])..
       frame:expandTemplate{title='TermDescription', args={'Class', '[[File:Icon Type Row '..adv['CharaType']..'.png|105px|link=]]'}}..
+
       termDescription({'Class', '[[File:Icon Type Row '..adv['CharaType']..'.png|105px|link=]]'})..
       frame:expandTemplate{title='TermDescription', args={'Base Rarity', '[[File:Icon Rarity Row '..adv['Rarity']..'.png|75px|link=]]'}}..
+
       termDescription({'Base Rarity', '[[File:Icon Rarity Row '..adv['Rarity']..'.png|75px|link=]]'})..
       frame:expandTemplate{title='TermDescription', args={'Obtained From', adv['Obtain']}}
+
       termDescription({'Obtained From', adv['Obtain']})
 
   -- Skills
 
   -- Skills
 
   local skill1tooltip = frame:expandTemplate{title='SkillTooltip', args={adv['Skill1Name']}}
 
   local skill1tooltip = frame:expandTemplate{title='SkillTooltip', args={adv['Skill1Name']}}
  mw.log(skill1tooltip)
+
   local skill2tooltip = adv['Skill2Name'] == '' and '' or
   local skill2tooltip = ''
+
      ', '..frame:expandTemplate{title='SkillTooltip', args={adv['Skill2Name']}}
  if (adv['Skill2Name'] ~= '') then
 
    skill2tooltip = frame:expandTemplate{title='SkillTooltip', args={adv['Skill2Name']}}
 
  end
 
 
   -- CoAbility
 
   -- CoAbility
   local coability = frame:expandTemplate{title='Icon', args={'CoAbility', coability, size='24px'}}..
+
   local exData = {}
                    frame:expandTemplate{title='CoAbilityTooltip', args={adv['ExAbilityData1'], adv['ExAbilityData2'], adv['ExAbilityData3'], adv['ExAbilityData4'], adv['ExAbilityData5']}}
+
  for i = 1,5 do exData[i] = adv['ExAbilityData'..i] end
 +
  local coability = frame:expandTemplate{title='CoAbilityIconTooltip', args=exData}
 +
  -- ChainCoAbility
 +
  local exData2 = {}
 +
  for i = 1,5 do exData2[i] = adv['ExAbility2Data'..i] end
 +
  local ccoability = ', '..frame:expandTemplate{title='ChainCoAbilityIconTooltip', args=exData2}
 +
 
 
   -- Abilities
 
   -- Abilities
 
   local ability1 = abilityIconTooltip({abilities['Abilities11'], abilities['Abilities12'], abilities['Abilities13']})
 
   local ability1 = abilityIconTooltip({abilities['Abilities11'], abilities['Abilities12'], abilities['Abilities13']})
 
   local ability2 = abilities['Abilities21'] == '0' and '' or
 
   local ability2 = abilities['Abilities21'] == '0' and '' or
       ', '..abilityIconTooltip({abilities['Abilities21'], abilities['Abilities22']})
+
       ', '..abilityIconTooltip({abilities['Abilities21'], abilities['Abilities22'], abilities['Abilities23']})
 
   local ability3 = abilities['Abilities31'] == '0' and '' or
 
   local ability3 = abilities['Abilities31'] == '0' and '' or
       ', '..abilityIconTooltip({abilities['Abilities31'], abilities['Abilities32']})
+
       ', '..abilityIconTooltip({abilities['Abilities31'], abilities['Abilities32'], abilities['Abilities33']})
  
 
   -- Format the content
 
   -- Format the content
   local card = mw.html.create('div')
+
   local card = mw.html.create('div'):addClass('panel'):css('display','inline-block')
    :addClass('panel')
+
     :tag('div'):addClass('panel-heading')
    :css('display','inline-block')
 
     :tag('div')
 
      :addClass('panel-heading')
 
 
       :wikitext('[['..name..']]')
 
       :wikitext('[['..name..']]')
 
       :done()
 
       :done()
     :tag('div')
+
     :tag('div'):addClass('panel-body'):cssText('display:flex;flex-wrap:wrap;justify-content:center;')
      :addClass('panel-body')
 
      :cssText('display:flex;flex-wrap:wrap;justify-content:center;')
 
 
       :tag('div')
 
       :tag('div')
 
         :wikitext(portraitImage)
 
         :wikitext(portraitImage)
 
         :done()
 
         :done()
       :tag('div')
+
       :tag('div'):cssText('display:flex;flex-direction:column')
        :cssText('display:flex;flex-direction:column')
 
 
         :tag('div')
 
         :tag('div')
 
           :wikitext(description)
 
           :wikitext(description)
 
           :done()
 
           :done()
         :tag('hr')
+
         :tag('hr'):cssText('margin:1em')
          :cssText('margin:1em')
 
 
           :done()
 
           :done()
         :tag('div')
+
         :tag('div'):cssText('width:360px')
           :tag('div')
+
           :tag('div'):cssText('display:inline-block')
            :cssText('width:360px')
 
 
             :wikitext("'''Skills''': ")
 
             :wikitext("'''Skills''': ")
             :tag('div')
+
             :wikitext(skill1tooltip..skill2tooltip)
              :cssText('display:inline-block')
+
            :done()
              :wikitext(skill1tooltip..skill2tooltip)
+
          :tag('div'):cssText('display:inline-block')
              :done()
+
            :wikitext("'''Co-Abilities''': ")
 +
            :wikitext(coability..ccoability)
 +
            :done()
 +
          :tag('div'):cssText('display:inline-block')
 +
            :wikitext("'''Abilities''': ")
 +
            :wikitext(ability1..ability2..ability3)
 
             :done()
 
             :done()
            :tag('div')
 
              :cssText('width:360px')
 
              :wikitext("'''Co-Ability''': ")
 
              :tag('div')
 
                :cssText('display:inline-block')
 
                :wikitext(coability)
 
                :done()
 
              :done()
 
            :tag('div')
 
              :cssText('width:360px')
 
              :wikitext("'''Abilities''': ")
 
              :tag('div')
 
                :cssText('display:inline-block')
 
                :wikitext(ability1..ability2..ability3)
 
                :done()
 
 
     :allDone()
 
     :allDone()
 
   return tostring(card)
 
   return tostring(card)
 +
end
 +
 +
 +
-- The effective max level of an adventurer, at a given rarity (optional),
 +
-- with a given number of Mana Circle nodes unlocked.
 +
-- Usage: {{#invoke:Adventurer|effectiveMaxLevel|<name>|<mcNodes>|rarity}}
 +
-- Ex: {{#invoke:Adventurer|effectiveMaxLevel|Euden|64}}
 +
--  or {{#invoke:Adventurer|effectiveMaxLevel|name=Euden|nodes=0|rarity=5}}
 +
function p.effectiveMaxLevel(frame)
 +
  local nodes = tonumber(frame.args[2] or frame.args['nodes'] or 0)
 +
  local rarity = frame.args[3] or frame.args['rarity']
 +
 +
  if not rarity then
 +
    local name = mw.text.trim(frame.args[1] or frame.args['name'])
 +
    local adv = cargo.query('Adventurers', 'Rarity', {
 +
      where = 'FullName="'..name..'"',
 +
      groupBy = '_pageName',
 +
      limit = 1
 +
    })[1]
 +
    rarity = adv['Rarity']
 +
  end
 +
 +
  if rarity == '3' then
 +
    return 60
 +
  elseif rarity == '4' then
 +
    return 70
 +
  elseif rarity == '5' then
 +
    if nodes > 64 then
 +
      return 100
 +
    elseif nodes > 59 then
 +
      return 95
 +
    elseif nodes > 54 then
 +
      return 90
 +
    elseif nodes > 50 then
 +
      return 85
 +
    else
 +
      return 80
 +
    end
 +
  end
 +
  return -1
 +
end
 +
 +
 +
-- The effective max mana circle nodes unlockable for an adventurer,
 +
-- at a given rarity (optional), depending on whether the mana spiral is
 +
-- unlocked or not.
 +
-- Usage: {{#invoke:Adventurer|effectiveMaxMcNodes|<name>|rarity|unlocked}}
 +
-- Ex: {{#invoke:Adventurer|effectiveMaxMcNodes|Euden|4}}
 +
--  or {{#invoke:Adventurer|effectiveMaxMcNodes|name=Euden|rarity=5}}
 +
--  or {{#invoke:Adventurer|effectiveMaxMcNodes|Euden|unlocked=1}}
 +
function p.effectiveMaxMcNodes(frame)
 +
  local rarity = frame.args[2] or frame.args['rarity']
 +
  local spiralUnlocked = (frame.args[3] or frame.args['unlocked']) == '1'
 +
 +
  if not rarity and not spiralUnlocked then
 +
    local name = mw.text.trim(frame.args[1] or frame.args['name'])
 +
    local adv = cargo.query('Adventurers', 'Rarity', {
 +
      where = 'FullName="'..name..'"',
 +
      groupBy = '_pageName',
 +
      limit = 1
 +
    })[1]
 +
    rarity = adv['Rarity']
 +
  end
 +
 +
  if spiralUnlocked then
 +
    return 70
 +
  elseif rarity == '3' then
 +
    return 30
 +
  elseif rarity == '4' then
 +
    return 40
 +
  elseif rarity == '5' then
 +
    return 50
 +
  end
 +
  return -1
 +
end
 +
 +
 +
-- Common templating functions
 +
 +
function termDescription(args)
 +
  local frame = mw.getCurrentFrame()
 +
  return frame:expandTemplate{title='TermDescription', args=args}
 +
end
 +
 +
function inlineIconAndDesc(args, desc)
 +
  local frame = mw.getCurrentFrame()
 +
  return string.format('%s %s', frame:expandTemplate{title='InlineIcon', args=args}, desc)
 
end
 
end
  
 
function abilityIconTooltip(abilities)
 
function abilityIconTooltip(abilities)
 
   local frame = mw.getCurrentFrame()
 
   local frame = mw.getCurrentFrame()
   return frame:expandTemplate{title='Icon', args = {'Ability', abilities[1], size='24px'}}..
+
   return frame:expandTemplate{title='AbilityIconTooltip', args=abilities}
        frame:expandTemplate{title='AbilityTooltip', args=abilities}
 
 
end
 
end
  
function maxStatsTooltip(statType, max, maxWithMaxMc)
+
function maxStatsTooltip(statType, max, mcPlus, mcFullBonus)
 
   local frame = mw.getCurrentFrame()
 
   local frame = mw.getCurrentFrame()
 +
  local total = max + mcPlus + mcFullBonus
 
   return frame:expandTemplate{title='TermDescriptionTooltip', args={
 
   return frame:expandTemplate{title='TermDescriptionTooltip', args={
       frame:expandTemplate{title='Tooltip', args={'Total Max '..statType, '5★ Max '..statType..' with All Mana Circle Nodes and Bonus'}},
+
       frame:expandTemplate{title='Tooltip', args={
       string.format('%s (%s)', max, maxWithMaxMc), 'Total (5★ Max + Mana Circle Node Stats + Mana Circle Bonus)}}'}}
+
          'Total Max '..statType, '5★ Max '..statType..' with All Mana Circle Nodes and Bonus'}},
 +
       string.format('%s (%s + %s + %s)', total, max, mcPlus, mcFullBonus),
 +
      'Total (5★ Max + Mana Circle Node Stats + Mana Circle Bonus)'}}
 
end
 
end
 +
 +
-- Common querying functions
  
 
function getAdventurers(queryArgs)
 
function getAdventurers(queryArgs)
 
   local tables = 'Adventurers'
 
   local tables = 'Adventurers'
   local queryFields = 'Id,VariationId,CharaType,Rarity,ElementalType,WeaponType,MinHp3,MinHp4,MinHp5,MaxHp,PlusHp0,PlusHp1,PlusHp2,PlusHp3,PlusHp4,McFullBonusHp5,MinAtk3,MinAtk4,MinAtk5,MaxAtk,PlusAtk0,PlusAtk1,PlusAtk2,PlusAtk3,PlusAtk4,McFullBonusAtk5,Obtain,ExAbilityData1,ExAbilityData2,ExAbilityData3,ExAbilityData4,ExAbilityData5,Skill1Name,Skill2Name,Abilities11,Abilities12,Abilities13,Abilities21,Abilities22,Abilities31,Abilities32'
+
   local queryFields = 'Id,VariationId,CharaType,Rarity,ElementalType,WeaponType,MinHp3,MinHp4,MinHp5,MaxHp,PlusHp0,PlusHp1,PlusHp2,PlusHp3,PlusHp4,McFullBonusHp5,MinAtk3,MinAtk4,MinAtk5,MaxAtk,PlusAtk0,PlusAtk1,PlusAtk2,PlusAtk3,PlusAtk4,McFullBonusAtk5,Obtain,ExAbilityData1,ExAbilityData2,ExAbilityData3,ExAbilityData4,ExAbilityData5,ExAbility2Data1,ExAbility2Data2,ExAbility2Data3,ExAbility2Data4,ExAbility2Data5,Skill1Name,Skill2Name,Abilities11,Abilities12,Abilities13,Abilities21,Abilities22,Abilities23,Abilities31,Abilities32,Abilities33'
 
   return cargo.query(tables, queryFields, queryArgs)
 
   return cargo.query(tables, queryFields, queryArgs)
 
end
 
end
Line 152: Line 237:
 
function getCoabilities(queryArgs)
 
function getCoabilities(queryArgs)
 
   local tables = 'CoAbilities'
 
   local tables = 'CoAbilities'
   local queryFields = 'Name'
+
   local queryFields = 'Id'
 +
  return cargo.query(tables, queryFields, queryArgs)
 +
end
 +
 
 +
function getChainCoab(queryArgs)
 +
  local tables = 'ChainCoAbilities'
 +
  local queryFields = 'Id'
 
   return cargo.query(tables, queryFields, queryArgs)
 
   return cargo.query(tables, queryFields, queryArgs)
 
end
 
end
Line 158: Line 249:
 
function getAbilities(queryArgs)
 
function getAbilities(queryArgs)
 
   local tables = 'Abilities'
 
   local tables = 'Abilities'
   local queryFields = 'Name'
+
   local queryFields = 'Id'
 
   return cargo.query(tables, queryFields, queryArgs)
 
   return cargo.query(tables, queryFields, queryArgs)
 
end
 
end

Latest revision as of 10:24, 20 July 2020

50px Documentation

Usage

This module is intended to back the rendering of more complicated Adventurer data-related templates. Currently it only supports the Template:Character info card template.

Example

Generally, this module should be called via the regular wikitext templates instead of directly. But here is example syntax for calling the functions from wikitext:

{{#invoke:Adventurer|infoCard|The Prince}}

Lua error: Error: Table Adventurers not found..

{{#invoke:Adventurer|infoCard|Name=Edward}}

Lua error: Error: Table Adventurers not found..


-- <includeonly> (prevents literal interpretation of links or categories within the module code)
-- Lua Templating for Adventurer related info.
local p = {}
local cargo = mw.ext.cargo

-- Usage: {{#invoke:Adventurer|infoCard|<name>}} or {{#invoke:Adventurer|infoCard|Name=<name>}}
-- Ex: {{#invoke:Adventurer|infoCard|Euden}} or {{#invoke:Adventurer|infoCard|Name=Elisanne}}
function p.infoCard(frame)
  local name = frame.args[1] or frame.args['Name']

  -- Query adventurer data
  local adv = getAdventurers({
    where = '_pageName="'..name..'"',
    groupBy = '_pageName',
    limit = 1
  })[1]
  if adv == nil then
    return ''
  end
  -- CoAbility
  local coability = getCoabilities({
    where = string.format('Id="%s"', adv['ExAbilityData1']),
    groupBy = '_pageName',
    limit = 1
  })[1]
  if coability then
    coability = coability['Id']
  end
  -- Chain CoAbility
  local ccoability = getChainCoab({
    where = string.format('Id="%s"', adv['ExAbility2Data1']),
    groupBy = '_pageName',
    limit = 1
  })[1]
  if ccoability then
    ccoability = ccoability['Id']
  end
  -- Abilities
  local abilityKeys = {'Abilities11', 'Abilities12', 'Abilities13', 'Abilities21', 'Abilities22', 'Abilities23', 'Abilities31', 'Abilities32', 'Abilities33'}
  local abilities = {}
  for i, key in ipairs(abilityKeys) do
    abilities[key] = '0'
    if adv[key] and adv[key] ~= '0' then
      local ability = getAbilities({
        where = string.format('Id="%s"', adv[key]),
        groupBy = '_pageName',
        limit = 1
      })[1]
      if ability then
        abilities[key] = ability['Id']
      end
    end
  end

  -- Precompute some template outputs
  -- Portrait Image
  local portraitFileName = string.format('%s 0%s r05 portrait.png', adv['Id'], adv['VariationId'])
  local portraitImage = mw.title.makeTitle('File', portraitFileName)
  if (portraitImage.exists) then
    portraitImage = string.format('[[File:%s|300px|link=%s]]', portraitFileName, name)
  else
    portraitImage = string.format('[[File:Unknown.png|300px|link=%s]]', name)
  end
  -- Description
  local mcPlusHp = adv['PlusHp0'] + adv['PlusHp1'] + adv['PlusHp2'] + adv['PlusHp3'] + adv['PlusHp4']
  local mcPlusAtk = adv['PlusAtk0'] + adv['PlusAtk1'] + adv['PlusAtk2'] + adv['PlusAtk3'] + adv['PlusAtk4']
  local description =
      termDescription({'Element', inlineIconAndDesc({'Icon Element', adv['ElementalType']}, adv['ElementalType'])})..
      termDescription({'Weapon', inlineIconAndDesc({'Icon Weapon', adv['WeaponType']}, adv['WeaponType'])})..
      maxStatsTooltip('HP', adv['MaxHp'], mcPlusHp, adv['McFullBonusHp5'])..
      maxStatsTooltip('Str', adv['MaxAtk'], mcPlusAtk, adv['McFullBonusAtk5'])..
      termDescription({'Class', '[[File:Icon Type Row '..adv['CharaType']..'.png|105px|link=]]'})..
      termDescription({'Base Rarity', '[[File:Icon Rarity Row '..adv['Rarity']..'.png|75px|link=]]'})..
      termDescription({'Obtained From', adv['Obtain']})
  -- Skills
  local skill1tooltip = frame:expandTemplate{title='SkillTooltip', args={adv['Skill1Name']}}
  local skill2tooltip = adv['Skill2Name'] == '' and '' or
      ', '..frame:expandTemplate{title='SkillTooltip', args={adv['Skill2Name']}}
  -- CoAbility
  local exData = {}
  for i = 1,5 do exData[i] = adv['ExAbilityData'..i] end
  local coability = frame:expandTemplate{title='CoAbilityIconTooltip', args=exData}
  -- ChainCoAbility
  local exData2 = {}
  for i = 1,5 do exData2[i] = adv['ExAbility2Data'..i] end
  local ccoability = ', '..frame:expandTemplate{title='ChainCoAbilityIconTooltip', args=exData2}

  -- Abilities
  local ability1 = abilityIconTooltip({abilities['Abilities11'], abilities['Abilities12'], abilities['Abilities13']})
  local ability2 = abilities['Abilities21'] == '0' and '' or
      ', '..abilityIconTooltip({abilities['Abilities21'], abilities['Abilities22'], abilities['Abilities23']})
  local ability3 = abilities['Abilities31'] == '0' and '' or
      ', '..abilityIconTooltip({abilities['Abilities31'], abilities['Abilities32'], abilities['Abilities33']})

  -- Format the content
  local card = mw.html.create('div'):addClass('panel'):css('display','inline-block')
    :tag('div'):addClass('panel-heading')
      :wikitext('[['..name..']]')
      :done()
    :tag('div'):addClass('panel-body'):cssText('display:flex;flex-wrap:wrap;justify-content:center;')
      :tag('div')
        :wikitext(portraitImage)
        :done()
      :tag('div'):cssText('display:flex;flex-direction:column')
        :tag('div')
          :wikitext(description)
          :done()
        :tag('hr'):cssText('margin:1em')
          :done()
        :tag('div'):cssText('width:360px')
          :tag('div'):cssText('display:inline-block')
            :wikitext("'''Skills''': ")
            :wikitext(skill1tooltip..skill2tooltip)
            :done()
          :tag('div'):cssText('display:inline-block')
            :wikitext("'''Co-Abilities''': ")
            :wikitext(coability..ccoability)
            :done()
          :tag('div'):cssText('display:inline-block')
            :wikitext("'''Abilities''': ")
            :wikitext(ability1..ability2..ability3)
            :done()
    :allDone()
  return tostring(card)
end


-- The effective max level of an adventurer, at a given rarity (optional),
-- with a given number of Mana Circle nodes unlocked.
-- Usage: {{#invoke:Adventurer|effectiveMaxLevel|<name>|<mcNodes>|rarity}}
-- Ex: {{#invoke:Adventurer|effectiveMaxLevel|Euden|64}}
--  or {{#invoke:Adventurer|effectiveMaxLevel|name=Euden|nodes=0|rarity=5}}
function p.effectiveMaxLevel(frame)
  local nodes = tonumber(frame.args[2] or frame.args['nodes'] or 0)
  local rarity = frame.args[3] or frame.args['rarity']

  if not rarity then
    local name = mw.text.trim(frame.args[1] or frame.args['name'])
    local adv = cargo.query('Adventurers', 'Rarity', {
      where = 'FullName="'..name..'"',
      groupBy = '_pageName',
      limit = 1
    })[1]
    rarity = adv['Rarity']
  end

  if rarity == '3' then
    return 60
  elseif rarity == '4' then
    return 70
  elseif rarity == '5' then
    if nodes > 64 then
      return 100
    elseif nodes > 59 then
      return 95
    elseif nodes > 54 then
      return 90
    elseif nodes > 50 then
      return 85
    else
      return 80
    end
  end
  return -1
end


-- The effective max mana circle nodes unlockable for an adventurer,
-- at a given rarity (optional), depending on whether the mana spiral is
-- unlocked or not.
-- Usage: {{#invoke:Adventurer|effectiveMaxMcNodes|<name>|rarity|unlocked}}
-- Ex: {{#invoke:Adventurer|effectiveMaxMcNodes|Euden|4}}
--  or {{#invoke:Adventurer|effectiveMaxMcNodes|name=Euden|rarity=5}}
--  or {{#invoke:Adventurer|effectiveMaxMcNodes|Euden|unlocked=1}}
function p.effectiveMaxMcNodes(frame)
  local rarity = frame.args[2] or frame.args['rarity']
  local spiralUnlocked = (frame.args[3] or frame.args['unlocked']) == '1'

  if not rarity and not spiralUnlocked then
    local name = mw.text.trim(frame.args[1] or frame.args['name'])
    local adv = cargo.query('Adventurers', 'Rarity', {
      where = 'FullName="'..name..'"',
      groupBy = '_pageName',
      limit = 1
    })[1]
    rarity = adv['Rarity']
  end

  if spiralUnlocked then
    return 70
  elseif rarity == '3' then
    return 30
  elseif rarity == '4' then
    return 40
  elseif rarity == '5' then
    return 50
  end
  return -1
end


-- Common templating functions

function termDescription(args)
  local frame = mw.getCurrentFrame()
  return frame:expandTemplate{title='TermDescription', args=args}
end

function inlineIconAndDesc(args, desc)
  local frame = mw.getCurrentFrame()
  return string.format('%s %s', frame:expandTemplate{title='InlineIcon', args=args}, desc)
end

function abilityIconTooltip(abilities)
  local frame = mw.getCurrentFrame()
  return frame:expandTemplate{title='AbilityIconTooltip', args=abilities}
end

function maxStatsTooltip(statType, max, mcPlus, mcFullBonus)
  local frame = mw.getCurrentFrame()
  local total = max + mcPlus + mcFullBonus
  return frame:expandTemplate{title='TermDescriptionTooltip', args={
      frame:expandTemplate{title='Tooltip', args={
          'Total Max '..statType, '5★ Max '..statType..' with All Mana Circle Nodes and Bonus'}},
      string.format('%s (%s + %s + %s)', total, max, mcPlus, mcFullBonus),
      'Total (5★ Max + Mana Circle Node Stats + Mana Circle Bonus)'}}
end

-- Common querying functions

function getAdventurers(queryArgs)
  local tables = 'Adventurers'
  local queryFields = 'Id,VariationId,CharaType,Rarity,ElementalType,WeaponType,MinHp3,MinHp4,MinHp5,MaxHp,PlusHp0,PlusHp1,PlusHp2,PlusHp3,PlusHp4,McFullBonusHp5,MinAtk3,MinAtk4,MinAtk5,MaxAtk,PlusAtk0,PlusAtk1,PlusAtk2,PlusAtk3,PlusAtk4,McFullBonusAtk5,Obtain,ExAbilityData1,ExAbilityData2,ExAbilityData3,ExAbilityData4,ExAbilityData5,ExAbility2Data1,ExAbility2Data2,ExAbility2Data3,ExAbility2Data4,ExAbility2Data5,Skill1Name,Skill2Name,Abilities11,Abilities12,Abilities13,Abilities21,Abilities22,Abilities23,Abilities31,Abilities32,Abilities33'
  return cargo.query(tables, queryFields, queryArgs)
end

function getCoabilities(queryArgs)
  local tables = 'CoAbilities'
  local queryFields = 'Id'
  return cargo.query(tables, queryFields, queryArgs)
end

function getChainCoab(queryArgs)
  local tables = 'ChainCoAbilities'
  local queryFields = 'Id'
  return cargo.query(tables, queryFields, queryArgs)
end

function getAbilities(queryArgs)
  local tables = 'Abilities'
  local queryFields = 'Id'
  return cargo.query(tables, queryFields, queryArgs)
end

return p
--</includeonly>