Mobius Final Fantasy Wiki
mNo edit summary
m (Moving has_cooldown to end of logic.)
Line 160: Line 160:
 
local show_breakpower = breakpower > 0
 
local show_breakpower = breakpower > 0
 
local show_critchance = critchance ~= ''
 
local show_critchance = critchance ~= ''
local show_cooldown = has_cooldown or support or (fast and critchance == '')
+
local show_cooldown = support or (fast and critchance == '') or has_cooldown
 
 
 
local columns = {}
 
local columns = {}

Revision as of 05:08, 7 June 2018

Tests

YesY All tests passed.

Name Expected Actual
YesY testFastSupportLevels
YesY testFastWarriorLevels
YesY testNormalSupportLevels
YesY testNormalWarriorLevels

local p = {}
local black = '★'
local white = '☆'
local multis = {1.0, 1.1, 1.2, 1.3, 1.4, 1.7, 2.0, 2.3, 2.6, 3.0}

local function round(n)
	return math.floor(n + 0.5)
end

local function count_stars(s)
	local total = tonumber(s)
	local _, black_count, white_count
	if total == nil then
		_, black_count = string.gsub(s, black, '')
		_, white_count = string.gsub(s, white, '')
		total = black_count + white_count * 10
	end
	return total
end

local function number_to_stars(n)
	local total = tonumber(n)
	local w_count = math.floor(total / 10)
	local b_count = total % 10
	return string.rep(white, w_count) .. string.rep(black, b_count)
end

local function jobtype_icon(s)
	local s = mw.ustring.lower(s)
	local fmt = '[[File:%s_Icon.png|link=|20px]]'
	if (s == 'warrior' or
		s == 'mage' or
		s == 'ranger' or
		s == 'monk') then
		return fmt:format(s)
	end
end

function p.ultimate(frame)
	local pframe = frame:getParent()
	local config = frame.args
	local args = pframe.args
	return p._ultimate(args)
end

function p._ultimate(args)
	local gauge = {160, 155, 150, 140, 135, 130, 125, 110, 100, 80}
	local name = args.name or ''
	local jobtype = args.jobtype or ''
	local info = args.description or ''
	local attack = string.match(args.attack or '', '(%d+)%%?') or ''
	local breakpower = string.match(args.breakpower or '', '(%d+)%%?') or ''
	local const_attack = (args.const_attack or '') == 'y'
	local const_breakpower = (args.const_breakpower or '') == 'y'
	local critchance = args.critchance or ''
	local extra = args.extra or ''
	
	if attack == '' then attack = 0 end
	if breakpower == '' then breakpower = 0 end
	
	local total = count_stars(critchance)
	local critstars = number_to_stars(total)
	
	local tbl = {}
	table.insert(tbl, {
		'Lv',
		'Ultimate Gauge',
		'Attack',
		'Break Power',
		'Crit Chance',
		})
	for level=1,10 do
		local m = multis[level]
		local row = {}
		table.insert(row, level)
		table.insert(row, gauge[level])
		if const_attack then
			table.insert(row, attack .. '%')
		else
			table.insert(row, (attack * m) .. '%')
		end
		if const_breakpower then
			table.insert(row, breakpower .. '%')
		else
			table.insert(row, (breakpower * m) .. '%')
		end
		table.insert(row, critstars .. ' (' .. tostring(total * 5) .. '%)')
		table.insert(tbl, row)
	end

	local html = mw.html.create('')
	html
		:wikitext(jobtype_icon(jobtype))
		:tag('b'):wikitext(name):done():newline()
		:wikitext(": ''\"" .. info .. "\"''"):newline()
	local wikitable = html:tag('table'):addClass('wikitable')
	for i,row in ipairs(tbl) do
		local tr = wikitable:tag('tr')
		local tagtype = i == 1 and 'th' or 'td'
		for j,col in ipairs(row) do
			tr
				:tag(tagtype)
				:wikitext(col)
				:done()
		end
		tr:done():newline()
	end
	wikitable:done():newline()
	if extra ~= '' then
		html:tag('b'):wikitext('Added Effects: '):done():newline():wikitext(extra)
	end
	return tostring(html)
end

function p._main(args)
	local args = args
	local rarity = args.rarity or ''
	local attack = args.attack or ''
	local breakpower = args.breakpower or ''
	local critchance = args.critchance or ''
	local const_attack = (args.const_attack or '') == 'y'
	local const_breakpower = (args.const_breakpower or '') == 'y'
	local has_cooldown = (args.has_cooldown or '') == 'y'
	if rarity == '' then
		mw.log('ability stat: "rarity" argument is null or empty')
		return ''
	end
	local cooldowns = {8, 7, 6, 5, 4, 3, 2, 2, 1, 1}
	
	local fast = false
	local rarities = {}
	for a,b in string.gmatch(rarity, '(-?%d+)(%+?)') do
		a = tonumber(a)
		if a < 1 or 5 < a then
			error("Rarity outside the range of 1~5: "..a..b)
		elseif b == '+' then
			fast = true
		end
		table.insert(rarities, a)
	end
	table.sort(rarities)
	if attack == '' then
		attack = 0
	else
		attack = tonumber(attack)
	end
	if breakpower == '' then
		breakpower = 0
	else
		breakpower = tonumber(breakpower)
	end
	if critchance ~= '' then
		local total = count_stars(critchance)
		critchance = number_to_stars(total)
	end
	-- If attack is 0, then it's a support ability.
	-- If break is 0, then it's a support ability.
	local support = attack == 0 or breakpower == 0
	local show_attack = attack > 0
	local show_breakpower = breakpower > 0
	local show_critchance = critchance ~= ''
	local show_cooldown = support or (fast and critchance == '') or has_cooldown
	
	local columns = {}
	local rows = {}
	local level
	local m, c -- y = mx + c
	if support then
		m = 1
		c = 1
	else
		m = 2
		c = 0
	end
	local levels = {}
	if fast then
		for i, rarity in ipairs(rarities) do
			table.insert(levels, rarity * m + c)
		end
	else
		for level=1, rarities[#rarities] * m + c do
			table.insert(levels, level)
		end
	end
	table.insert(columns, 'ALv.')
	if show_attack then table.insert(columns, 'Attack') end
	if show_breakpower then table.insert(columns, 'Break Power') end
	if show_critchance then table.insert(columns, 'Crit Chance') end
	if show_cooldown then table.insert(columns, 'Cooldown') end
	for i,level in ipairs(levels) do
		local row = {}
		local m = multis[level]
		table.insert(row, level)
		if show_attack then
			if const_attack then
				table.insert(row, attack)
			else
				table.insert(row, round(attack * m))
			end
		end
		if show_breakpower then
			if const_breakpower then
				table.insert(row, breakpower)
			else
				table.insert(row, round(breakpower * m))
			end
		end
		if show_critchance then
			table.insert(row, critchance)
		end
		if show_cooldown then
			local cooldown = cooldowns[level]
			table.insert(row, cooldown)
		end
		table.insert(rows, row)
	end

	local wikitable, tr
	
	wikitable = mw.html.create('table'):addClass('wikitable'):newline()
	tr = mw.html.create('tr')
	for i,th in ipairs(columns) do
		tr:tag('th'):wikitext(th)
	end
	wikitable:node(tr):newline()
	for i,row in ipairs(rows) do
		tr = mw.html.create('tr')
		for j,td in ipairs(row) do
			tr:tag('td'):wikitext(td)
		end
		wikitable:node(tr):newline()
	end
	return tostring(wikitable)
end

function p.main(frame)
	local pframe = frame:getParent()
	local config = frame.args
	local args = pframe.args
	return p._main(args)
end

return p