Module:Status

From Granblue Fantasy Wiki
Jump to: navigation, search

local p = {}

function p.fetchStatus(name)
	local data = mw.loadData('Module:StatusList')
	--local buffs = data.buffs
	--local debuffs = data.debuffs
	
	-- 'groups', 'categories', 
	local fields = { 'wiki_name', 'wiki_detail', 'wiki_comment', 'name', 'detail', 'status', 'icon', 'category', 'page' }
	local result = {}
	local fetch_name = name
	repeat
		while data.aliases[fetch_name] ~= nil do
			fetch_name = data.aliases[fetch_name]
		end
		local status = data.buffs[fetch_name]
		if status == nil then
			status = data.debuffs[fetch_name]
		end
		if status == nil then
			status = data.effects[fetch_name]
		end

		if status == nil then
			return nil
		end

		for ix,field in pairs(fields) do
			if (result[field] == nil) and (status[field] ~= nil) then
				result[field] = status[field]
			end
		end
		
		result.ref = status.name
		
		if status.link ~= nil then
			fetch_name = status.link
		end
	until (status == nil) or (status.link == nil)
	
	return result
end

function p.format(frame)
	local result = {}
	
	local name = nil
	if frame.args.name ~= nil then
		name = frame.args.name
	elseif frame.args[1] ~= nil then
		name = frame.args[1]
	end
	if name == nil then
		error('Status name missing')
	end
	
	local amount = ''
	if frame.args.amount ~= nil then
		amount = frame.args.amount
	end
	
	local time = ''
	if frame.args.time ~= nil then
		time = frame.args.time
	elseif frame.args[2] ~= nil then
		time = frame.args[2]
	end
	
	-- reconstruct a status 
	local status = p.fetchStatus(name)
	if status == nil then
		return 'not found'
	end
	status.fetch_name = name
	status.only_icon = frame.args.only_icon
	if (frame.args.time ~= nil) and (string.len(frame.args.time) > 0) then
		status.time = frame.args.time
	end
	if (frame.args.amount ~= nil) and (string.len(frame.args.amount) > 0) then
		status.amount = frame.args.amount
	end
	if (frame.args.probability ~= nil) and (string.len(frame.args.probability) > 0) then
		status.probability = frame.args.probability
	end
	if (frame.args.accuracy ~= nil) and (string.len(frame.args.accuracy) > 0) then
		status.accuracy = frame.args.accuracy
	end
	if (frame.args.accuracy ~= nil) and (string.len(frame.args.accuracy) > 0) then
		status.accuracy = frame.args.accuracy
	end
	if (frame.args.stacking ~= nil) and (string.len(frame.args.stacking) > 0) then
		status.stacking = frame.args.stacking
	end
	if (frame.args.multiplier ~= nil) and (string.len(frame.args.multiplier) > 0) then
		status.multiplier = frame.args.multiplier
	end
	status.comment = frame.args.comment
	if frame.args.hide ~= nil then
		if status.hide ~= nil then
			status.hide = ',' .. status.hide .. ',' .. frame.args.hide .. ','
		else
			status.hide = ',' .. frame.args.hide .. ','
		end
	elseif status.hide ~= nil then
		status.hide = ',' .. status.hide .. ','
	end
	
	status.wiki_name = p.formatAmount(status.wiki_name, frame.args.amount, frame.args.probability)
	status.wiki_detail = p.formatAmount(p.formatTime(status.wiki_detail, frame.args.time), frame.args.amount)
	status.wiki_comment = p.formatAmount(p.formatTime(status.wiki_comment, frame.args.time), frame.args.amount)
	
	return frame:expandTemplate{ title = frame.args.template, args = status }
end

function p.formatAmount(text, amount, probability)
	if (text == nil) then
		return nil
	end
	
	local si,ei = string.find(text, '%a%', 1, true)
	if si == nil then
		return text
	end

	local unit = string.sub(amount, -1)
	local result = ''
	if (unit == '%') then
		if (probability ~= nil) and (string.len(probability) > 0) then
			result = probability .. ' / ' .. amount
		else
			result = amount
		end
	end

	if si > 1 then
		result = string.sub(text, 1, si-1) .. result
	end
	if ei < string.len(text) then
		result = result .. string.sub(text, ei+1)
	end
	
	return result 
end

function p.formatTime(text, time)
	if (text == nil) then
		return nil
	end
	
	local si,ei = string.find(text, '%t%', 1, true)
	if si == nil then
		return text
	end
	
	if (time == nil) then
		time = ''
	end

	local unit = string.sub(time, -1)
	local result = ''
	if (unit == 'T') then
		local s = string.sub(time, 1, -2)
		if (s == '0') then
			result = '0 turns'
		elseif (s == '1') then
			result = '1 turn'
		else
			result = s .. ' turns'
		end
	elseif (unit == 's') then
		local s = string.sub(time, 1, -2)
		result = s .. ' seconds'
	elseif (unit == 'm') then
		local s = string.sub(time, 1, -2)
		if (s == '1') then
			result = '1 minute'
		else
			result = s .. ' minutes'
		end
	elseif (unit == 'h') then
		local s = string.sub(time, 1, -2)
		if (s == '1') then
			result = '1 hour'
		else
			result = s .. ' hourss'
		end
	else
		result = time
	end

	if si > 1 then
		result = string.sub(text, 1, si-1) .. result
	end
	if ei < string.len(text) then
		result = result .. string.sub(text, ei+1)
	end
	
	return result 
end

function p.test()
	local frame = mw.getCurrentFrame()
	frame.args.template = 'Status/Simple'
	frame.args.name = 'ATK Boosted'
	frame.args.time = '180s'
	frame.args.amount = '70%'
	frame.args.probability = ''
	return p.format(frame)
end

function p.test2()
	local frame = mw.getCurrentFrame()
	frame.args.template = 'Status/Simple'
	frame.args.name = '90% Cut'
	return p.format(frame)
end

function p.test3()
	local frame = mw.getCurrentFrame()
	frame.args.template = 'Status/Simple'
	frame.args.name = 'Critical Hit Rate Boosted'
	frame.args.time = '180s'
	frame.args.amount = '70%'
	frame.args.probability = '90%'
	return p.format(frame)
end

return p