Module:CharacterSkill

From Granblue Fantasy Wiki
Jump to navigation Jump to search

Documentation for this module may be created at Module:CharacterSkill/doc

local p = {}
local getArgs = require('Module:Arguments').getArgs

local function stripRefTags(wikitext)
  local w = wikitext:gsub("<ref%s[^>]*/>", "")
  w = w:gsub("<ref[^>]*>.-</ref>", "")
  return w
end

local function findArg(needle, haystack)
  local val = haystack:match('|'..needle:gsub("[%[%]%-+*.?%%()]", "%%%0")..'%s*=(.-)\n|')
  return val and mw.text.trim(val) or ''
end

function p.renderSkill(frame)
  local args = getArgs(frame)
  return p._renderSkill(frame, args)
end

function p._renderSkill(frame, args)
  -- 1. Parse arguments
  local characterName = args['page'] or args[1] or false
  local skillIndex = args['no'] or args[2] or false

  assert(characterName, 'Parameter 1 (Character Name) missing')
  assert(skillIndex, 'Parameter 2 (Skill Index) missing')

  -- Show alternative version/icon of the skill in the same slot?
  -- e.g. Cagliostro (Summer) SK1
  local alternativeSkillIndex = tonumber(args['alt']) or (args['alt'] == "true" and 2 or 1)
  
  -- Show in 2 lines and bigger icon?
  local largeFormat = args['large'] == "true"
  
  -- Show character name and icon instead of skill?
  local showCharacter = args['char'] == "true"
  
  local hideIcon = args['icon'] == "false"
  local hideText = args['icononly'] == "true"
  local hideTooltip = args['tooltip'] == "false"
  
  assert(not (hideIcon and hideText), 'icon=false cannot be used with icononly=true')
  -- Not sure about preventing this combination.
  -- assert(not (showCharacter and hideTooltip), 'char=true cannot be used with tooltip=false')

  -- 2. Find skill
  local title = mw.title.new(characterName)
  local rawPage = title:getContent()
  
  local iconArg = 'a'..skillIndex..'_icon'
  local nameArg = 'a'..skillIndex..'_name'
  local effdescArg = 'a'..skillIndex..'_effdesc'
  local skillIcon = findArg(iconArg, rawPage)
  assert(skillIcon ~= '', 'Skill icon not found')
  local skillName = findArg(nameArg, rawPage)
  assert(skillName ~= '', 'Skill name not found')
  local effdesc = findArg(effdescArg, rawPage)
  assert(effdesc ~= '', 'Skill effect description not found')
  
  -- 3. Render into HTML
  local iconSize = largeFormat and '50px' or '25px'
  
  local altSkillName = mw.text.split(skillName, '/', true)[alternativeSkillIndex]
  skillName = not altSkillName and skillName or altSkillName
  skillName = mw.text.trim(skillName)
  
  local altSkillIcon = mw.text.split(skillIcon, ',', true)[alternativeSkillIndex]
  skillIcon = not altSkillIcon and skillIcon or altSkillIcon

  -- 3.1. Icon
  local icon = {''}
  if not hideIcon then
    local fileName = showCharacter and characterName .. ' square.jpg' or skillIcon
    table.insert(icon, '[[File:' .. fileName .. '|' .. iconSize .. '|' .. 'link=' .. characterName .. ']]')
    
    if largeFormat then
      table.insert(icon, '<br />')
    end
    
    if not hideText then
      table.insert(icon, '&nbsp;')
    end
  end
  icon = table.concat(icon)
  
  if hideText and hideTooltip then
    return icon
  end
  
  -- 3.2. Tooltip text
  local name = showCharacter and characterName or skillName
  local tt = not hideText and '[[' .. characterName .. '|' .. name .. ']]' or ''
  
  -- 3.3. Tooltip content
  local tc = frame:preprocess(stripRefTags(effdesc))
  
  -- 3.4. Wrapping elements
  local res = {''}
  
  if not hideText then
    table.insert(res, '<span class="image_link">')
    table.insert(res, icon)
  end

  if not hideTooltip then
    table.insert(res, '<span class="tooltip">' .. (hideText and icon or tt) .. '<span class="tooltiptext">')
    if showCharacter then
      -- Skill icon and name at top of tooltip
      table.insert(res, '[[File:' .. skillIcon .. '| 25px | link= ]]&nbsp;' .. skillName .. '<span class="hr"></span>')
    end
    table.insert(res, tc .. '</span></span>')
  else
    table.insert(res, tt)
  end

  if not hideText then
    table.insert(res, '</span>')
  end

  return table.concat(res)
end

function p.testRender()
  local frame = mw.getCurrentFrame()
  frame.args.page = 'Threo'
  frame.args.no = '1'
  frame.args.alt = 'true'
  -- frame.args.tooltip = 'false'
  -- frame.args.icononly = 'true'
  return p.renderSkill(frame)
end

return p