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 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)
	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.renderSkill(frame)
	mw.log('render start: ' .. os.clock())
	local template = frame.args.template
	local skillName = frame.args.skillName
	local noicon = frame.args.noicon

	mw.log('load precached list:' .. os.clock())
	local classSkillList = mw.loadData('Module:ClassSkillList')
	local classPair = classSkillList[skillName]
	local className = classPair[1]
	local skillIndex = classPair[2]

	mw.log('load data: ' .. os.clock())
	local title = mw.title.new(className)
	local rawPage = title:getContent()
	
	mw.log('find args:' .. os.clock())
	local icon = findArg(skillIndex..'_icon', rawPage)
	local name = findArg(skillIndex..'_name', rawPage)
	local desc = findArg(skillIndex..'_desc', rawPage)

	mw.log('expandTemplate:' .. os.clock())
	local args = {}
	local anchor = 'Skills'
	if skillIndex:sub(1,2) == 'ex' then
		anchor = 'Extended_Mastery_Skills'
	end
	args['link'] = className..'#'..anchor
	args['name'] = name
	args['icon'] = icon
	args['desc'] = frame:preprocess(stripRefTags(desc))
	args['noicon'] = noicon

	mw.log('done: ' .. os.clock())
	return frame:expandTemplate{ title = template, args = args }
end

function p.cargoRenderSkill(frame)
	local skillName = frame.args.skillName
	local escapedSkillName = skillName:gsub("'", "\\'")
	local alternativeSkillIndex = tonumber(frame.args.alt) or 1
	local additionalArgs = frame.args.additionalArgs

	local cargoTables = "class_skill"
	local cargoFields = "icon,description,class,ex"
	local cargoArgs = {
		where = "class_skill.name='" .. escapedSkillName .. "'",
		limit = 1,
	}
	local result = cargo.query(cargoTables, cargoFields, cargoArgs)[1]

	-- If no result, fallback to non-cargo method
	if result == nil then
		return p.renderSkill(frame)
	end

	local altSkillName = mw.text.split(skillName, '/', true)[alternativeSkillIndex]
	skillName = altSkillName or skillName
	skillName = mw.text.trim(skillName)

	local altSkillIcon = mw.text.split(result.icon, ',', true)[alternativeSkillIndex]
	result.icon = altSkillIcon or result.icon

	local anchor = result.ex == "1" and "Extended_Mastery_Skills" or "Skills"
	local templateArgs = {
		name = skillName,
		link = result.class .. '#' .. anchor,
		icon = result.icon,
		desc = util.string.remove_ref(result.description),
	}
	
	-- Pass `frame.args.additionalArgs` to `args`
	if additionalArgs ~= nil then
		for arg in (additionalArgs):gmatch('[^;]+') do
			local i = arg:find('=')
			templateArgs[arg:sub(0, i-1)] = arg:sub(i+1)
		end
	end

	return frame:expandTemplate{
		title = frame.args.template,
		args = templateArgs
	}
end

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

return p