Module:Adventurer

From Dragalia Lost Wiki
Revision as of 19:49, 8 April 2020 by >Eave (return -1 instead of 0 for max utility functions, to make sure they can't be matched by empty inputs)
Jump to navigation Jump to search
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 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>