Module:ClassSkill

From Granblue Fantasy Wiki
Jump to navigation Jump to search

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

local p = {}
local util = require('Module:Util')
local getArgs = require('Module:Arguments').getArgs
local cargo = mw.ext.cargo

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

function findArg(needle, haystack)
	local pattern = '|'..needle
	
	local startIndex = haystack:find(pattern, 0, true)
	if startIndex == nil then
		return ''
	end
	startIndex = startIndex + pattern:len()
	
	local endIndex = haystack:find('\n|', startIndex, true)
	endIndex = endIndex - 1
	
	local result = haystack:sub(startIndex,endIndex)
	result = mw.text.trim(result)
	result = result:sub(2) -- Remove `=` character at the beginning

	return mw.text.trim(result)
end

function p.renderClassSkill(frame)
  local args = getArgs(frame)
  return p._renderClassSkill(frame, args)
end

function p._renderClassSkill(frame, args)
  -- 1. Parse arguments
  local skillName = args['skill'] or args[1] or false

  assert(skillName, 'Parameter 1 (Skill Name) 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"
  local customSize = args['size']

  -- Show class name and icon instead of skill?
  local showClass = args['showclass'] == "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 fields = "ix,icon,class,name,description,master_icon"
  local cargoArgs = {
  	where = 'name="' .. skillName .. '"'
  }
  
  local results = mw.ext.cargo.query('class_skill', fields, cargoArgs)
  local class, skillIcon, masterIcon, tooltip, ix
  if #results ~= 0 then
  	-- mw.logObject(results)
    results = results[1]
    class = results.class
    skillIcon = results.icon
    masterIcon = results.master_icon
    tooltip = util.string.remove_ref(results.description)
    ix = results.ix
  else
  	-- Testcase - Assassin Retaliation Reprise cargo entry
	local classSkillList = mw.loadData('Module:ClassSkillList')
	local classPair = classSkillList[skillName]
	assert(classPair, "Class skill of that name does not exist, check the spelling")
	class = classPair[1]
	ix = classPair[2]

	local title = mw.title.new(class)
	local rawPage = title:getContent()

	skillIcon = findArg(ix .. '_icon', rawPage)
	masterIcon = findArg(ix .. '_master_icon', rawPage)
	tooltip = stripRefTags(findArg(ix .. '_desc', rawPage))
  end

  local anchor = ''
  if string.find(ix, 'umex') then
  	anchor = '#Ultimate_Mastery_Skills'
  elseif string.find(ix, 'ex') then
  	anchor = '#Extended_Mastery_Skills'
  else
  	anchor = '#Base_Skills'
  end
  local link = class .. anchor
  
  -- 3. Render into HTML
  local iconSize = largeFormat and '50px' or customSize and customSize .. 'px' or '25px'

  local altSkillName = mw.text.split(skillName, '/', true)[alternativeSkillIndex]
  skillName = not altSkillName and skillName or altSkillName
  skillName = mw.text.trim(skillName)
  
  local altSkillIcon = alternativeSkillIndex == 2 and masterIcon or mw.text.split(skillIcon, ',', true)[alternativeSkillIndex]
  skillIcon = not altSkillIcon and skillIcon or altSkillIcon

  -- 3.1. Icon
  local icon = {''}
  if not hideIcon then
    table.insert(icon, '[[File:' .. skillIcon .. '|' .. iconSize .. '|' .. 'link=' .. link .. ']]')
    
    if largeFormat and not (hideText) 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 = showClass and class or skillName
  local tt = not hideText and '[[' .. link .. '|' .. name .. ']]' or ''
  
  -- 3.3. Tooltip content
  local tc = frame:preprocess(tooltip)
  
  -- 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 showClass then
      -- Skill icon and name at top of tooltip
      table.insert(res, '[[File:' .. skillIcon .. '| ' .. iconSize .. ' | link=' .. class .. ']]&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.getClassSkill1(frame)
  local args = getArgs(frame)
  return p._getClassSkill1(frame, args)
end

function p._getClassSkill1(frame, args)
  local className = args['className'] or args[1] or false
  assert (className, "Parameter 1 (Class Name) is not set")
  local fields = "ix,class,name"
  local cargoArgs = {
  	where = 'ix="s1" and class="' .. className  .. '"',
  	limit=1
  }
  local results = mw.ext.cargo.query('class_skill', fields, cargoArgs)
  local skillName = results[1].name or false
  assert(skillName, "Skill could not be found, check the class's spelling")
  if (args['tooltip']) then
  	args['skill'] = skillName
  	return p._renderClassSkill(frame, args)
  end
  return results[1].name
end


function p.testRender()
	local frame = mw.getCurrentFrame()
	frame.args.template = 'Template:ClassSkill/Template'
	frame.args.skillName = "Fuma Shuriken"
	frame.args.additionalArgs = ''
	return p.renderClassSkill(frame)
end

return p