Difference between revisions of "Module:Status"

From Granblue Fantasy Wiki
Jump to: navigation, search
(Convert template Status, Status/Simple and Tt template calls to lua code)
(Missing space for critical / armor Strength)
 
(11 intermediate revisions by 2 users not shown)
Line 48: Line 48:
 
removeBlanks = true,
 
removeBlanks = true,
 
})
 
})
 +
return p._format2(args)
 
end
 
end
  
Line 74: Line 75:
 
status.icon = p.checkParam(status.icon)
 
status.icon = p.checkParam(status.icon)
 
status.category = p.checkParam(status.category)
 
status.category = p.checkParam(status.category)
 +
status.ref = p.checkParam(status.ref)
  
status.wiki_name = p.formatAmount(status.wiki_name, status.amount or '', status.probability or '')
+
status.wiki_name = p.checkParam(p.formatAmount(status.wiki_name, status.amount or '', status.probability or ''))
status.wiki_detail = p.formatAmount(p.formatTime(status.wiki_detail, status.time or ''), status.amount or '')
+
status.wiki_detail = p.checkParam(p.formatAmount(p.formatTime(status.wiki_detail, status.time or ''), status.amount or ''))
status.wiki_comment = p.formatAmount(p.formatTime(status.wiki_comment, status.time or ''), status.amount or '')
+
status.wiki_comment = p.checkParam(p.formatAmount(p.formatTime(status.wiki_comment, status.time or ''), status.amount or ''))
 
 
 
if args['template'] or false then
 
if args['template'] or false then
Line 91: Line 93:
 
end
 
end
 
 
if status.wiki_detail and (status.wiki_detail ~= '') then
+
table.insert(status_detail, status.wiki_detail or status.detail or '')
table.insert(status_detail, status.wiki_detail)
 
else
 
table.insert(status_detail, status.detail or '')
 
end
 
 
table.insert(status_detail, '<br />')
 
table.insert(status_detail, '<br />')
 
 
Line 101: Line 99:
 
if string.find(status_name, 'Critical', 1, true) then
 
if string.find(status_name, 'Critical', 1, true) then
 
table.insert(status_detail,  
 
table.insert(status_detail,  
'<hr /><strong>Strength</strong>:' ..
+
'<hr /><strong>Strength</strong>: ' ..
 
    status.probability .. ' chance of dealing ' .. (status.amount or '??') .. ' more damage.')
 
    status.probability .. ' chance of dealing ' .. (status.amount or '??') .. ' more damage.')
 
end
 
end
 
if string.find(status_name, 'Armored', 1, true) then
 
if string.find(status_name, 'Armored', 1, true) then
 
table.insert(status_detail,  
 
table.insert(status_detail,  
'<hr /><strong>Strength</strong>:' ..
+
'<hr /><strong>Strength</strong>: ' ..
    status.probability .. ' chance of dealing ' .. (status.amount or '??') .. ' less damage.')
+
    status.probability .. ' chance of taking ' .. (status.amount or '??') .. ' less damage.')
 
end
 
end
 
elseif status.amount and (string.find(status.hide, ',amount,', 1, true) == nil) then
 
elseif status.amount and (string.find(status.hide, ',amount,', 1, true) == nil) then
Line 129: Line 127:
 
elseif status.multiplier == 's' then
 
elseif status.multiplier == 's' then
 
table.insert(status_detail, '[[Damage Formula/Detailed Damage Formula#Seraphic boost|Seraphic]]')
 
table.insert(status_detail, '[[Damage Formula/Detailed Damage Formula#Seraphic boost|Seraphic]]')
 +
elseif status.multiplier == 'add' then
 +
table.insert(status_detail, 'Additive')
 +
elseif status.multiplier == 'mul' then
 +
table.insert(status_detail, 'Multiplicative')
 
else  
 
else  
 
table.insert(status_detail, '?')
 
table.insert(status_detail, '?')
Line 135: Line 137:
 
 
 
if status.accuracy then
 
if status.accuracy then
table.insert(status_detail, '<hr />[[Debuff Resistance|Base Accuracy]]: ' .. accuracy)
+
table.insert(status_detail, '<hr />[[Debuff Resistance|Base Accuracy]]: ' .. status.accuracy)
 
end
 
end
 
 
Line 185: Line 187:
 
end
 
end
 
 
if status.wiki_comment and (status.wiki_comment ~= '') and (string.find(status.wiki_comment, ',wiki_comment,', 1, true) == nil) then
+
if status.wiki_comment and (string.find(status.hide, ',wiki_comment,', 1, true) == nil) then
table.insert(status_detail, '<hr />aa' .. status.wiki_comment)
+
table.insert(status_detail, '<hr />' .. status.wiki_comment)
 
end
 
end
 
 
Line 207: Line 209:
 
 
 
local status_label = {}
 
local status_label = {}
local status_link = status.page or ('Status Effects#' .. status.ref)
+
local status_link = status.page or ('Status Effects#' .. (status.ref or status.fetch_name or status_name))
 
 
 
if status.category then
 
if status.category then
Line 430: Line 432:
 
frame.args.probability = '90%'
 
frame.args.probability = '90%'
 
return p.format(frame)
 
return p.format(frame)
 +
end
 +
 +
function p.test4()
 +
local frame = mw.getCurrentFrame()
 +
frame.args.name = 'Critical Hit Rate Boosted'
 +
frame.args.time = '180s'
 +
frame.args.amount = '70%'
 +
frame.args.probability = '90%'
 +
return p.format2(frame)
 +
end
 +
 +
function p.test5()
 +
return p._format2({
 +
name = 'Counters on DMG',
 +
a = '100%',
 +
t = '3T',
 +
c = 'Counter attacks grant 4% charge bar per hit (includes Recklessness Incarnate).',
 +
hide = 'wiki_comment',
 +
})
 
end
 
end
  
 
return p
 
return p

Latest revision as of 23:20, 21 August 2019


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

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.format2(frame)
	local args = getArgs(frame, {
		trim = true,
		removeBlanks = true,
	})
	return p._format2(args)
end

function p._format2(args)
	-- format2 is a conversion of the templates Status, Status/Simple and Tt to lua code
	local name = args[1] or args['name'] or false
	assert(name, 'Status param 1 or name missing.');
	local only_icon = (args[2] == 'icon') or (args[3] == 'icon') or false

	local status = p.fetchStatus(name)
	if status == nil then
		return p._formatOld(name, args)
	end

	status.fetch_name = name
	
	status.time = args['t'] or args['time'] or p.checkParam(status.time) or nil
	status.amount = args['a'] or args['amount'] or p.checkParam(status.amount) or nil
	status.probability = args['p'] or args['probability'] or p.checkParam(status.probability) or nil
	status.accuracy = args['acc'] or args['accuracy'] or p.checkParam(status.accuracy) or nil
	status.stacking = args['s'] or args['stacking'] or p.checkParam(status.stacking) or nil
	status.multiplier = args['m'] or args['multiplier'] or p.checkParam(status.multiplier) or nil
	status.comment = args['c'] or args['comment'] or nil
	status.hide = ',' .. (status.hide or '') .. ',' .. (args['hide'] or '') .. ','
	status.page = p.checkParam(status.page)
	status.icon = p.checkParam(status.icon)
	status.category = p.checkParam(status.category)
	status.ref = p.checkParam(status.ref)

	status.wiki_name = p.checkParam(p.formatAmount(status.wiki_name, status.amount or '', status.probability or ''))
	status.wiki_detail = p.checkParam(p.formatAmount(p.formatTime(status.wiki_detail, status.time or ''), status.amount or ''))
	status.wiki_comment = p.checkParam(p.formatAmount(p.formatTime(status.wiki_comment, status.time or ''), status.amount or ''))
	
	if args['template'] or false then
		local frame = mw.getCurrentFrame()
		return frame:expandTemplate{ title = args['template'], args = status }
	else
		-- this is Template:Status/Simple converted to lua
		local status_name = status.wiki_name or status.name or status.fetch_name
		local status_detail = {}
		
		if only_icon then
			table.insert(status_detail, status_name .. '<hr />')
		end
		
		table.insert(status_detail, status.wiki_detail or status.detail or '')
		table.insert(status_detail, '<br />')
		
		if status.probability then
			if string.find(status_name, 'Critical', 1, true) then
				table.insert(status_detail, 
					'<hr /><strong>Strength</strong>: ' ..
				    status.probability .. ' chance of dealing ' .. (status.amount or '??') .. ' more damage.')
			end
			if string.find(status_name, 'Armored', 1, true) then
				table.insert(status_detail, 
					'<hr /><strong>Strength</strong>: ' ..
				    status.probability .. ' chance of taking ' .. (status.amount or '??') .. ' less damage.')
			end
		elseif status.amount and (string.find(status.hide, ',amount,', 1, true) == nil) then
			table.insert(status_detail, '<hr /><strong>Strength</strong>: ' .. status.amount)
		end
		
		if status.multiplier then
			table.insert(status_detail, '<hr /><strong>Multiplier</strong>: ')
			if status.multiplier == 'n' then
				table.insert(status_detail, 'Normal')
			elseif status.multiplier == 'm' then
				table.insert(status_detail, 'Omega')
			elseif status.multiplier == 'ex' then
				table.insert(status_detail, 'Ex')
			elseif status.multiplier == 'unk' then
				table.insert(status_detail, 'Ex ([[Ranko Kanzaki Summon|Mysterious]])')
			elseif status.multiplier == 'el' then
				table.insert(status_detail, 'Elemental')
			elseif status.multiplier == 'u' then
				table.insert(status_detail, 'Unique')
			elseif status.multiplier == 's' then
				table.insert(status_detail, '[[Damage Formula/Detailed Damage Formula#Seraphic boost|Seraphic]]')
			elseif status.multiplier == 'add' then
				table.insert(status_detail, 'Additive')
			elseif status.multiplier == 'mul' then
				table.insert(status_detail, 'Multiplicative')
			else 
				table.insert(status_detail, '?')
			end
		end
	
		if status.accuracy then
			table.insert(status_detail, '<hr />[[Debuff Resistance|Base Accuracy]]: ' .. status.accuracy)
		end
		
		local half_turn = false
		if status.time then
			table.insert(status_detail, '<hr /><strong>Duration</strong>: ')
			if tonumber(string.sub(status.time, -2, -2)) ~= nil then
				local unit = string.sub(status.time, -1, -1)
				if (unit == 'T') or (unit == 't') then
					table.insert(status_detail, string.sub(status.time, 0, -2) .. ' turns')
					if (string.sub(status.time, -3, -2) == '.5') then
						half_turn = true
					end
				elseif (unit == 'S') or (unit == 's') then
					table.insert(status_detail, string.sub(status.time, 0, -2) .. ' seconds')
				elseif (unit == 'M') or (unit == 'm') then
					table.insert(status_detail, string.sub(status.time, 0, -2) .. ' minutes')
				else
					table.insert(status_detail, status.time)
				end
			else
				table.insert(status_detail, status.time)
			end
		end
	
		if status.stacking then
			table.insert(status_detail, '<hr /><strong>Stacking</strong>: ')
			if status.stacking == 's' then
				table.insert(status_detail, 'Single')
			elseif status.stacking == 'd' then
				table.insert(status_detail, 'Dual')
			elseif status.stacking == 'ca' then
				table.insert(status_detail, 'Charge Attack')
			elseif status.stacking == 'smn' then
				table.insert(status_detail, 'Summon')
			elseif status.stacking == 'cs' then
				table.insert(status_detail, 'Charge Attack / Summon')
			elseif status.stacking == 'st' then
				table.insert(status_detail, 'Single Target')
			elseif status.stacking == 'tw' then
				table.insert(status_detail, 'Teamwide')
			else
				table.insert(status_detail, status.stacking)
			end
		end
	
		if status.comment then
			table.insert(status_detail, '<hr />' .. status.comment)
		end
		
		if status.wiki_comment and (string.find(status.hide, ',wiki_comment,', 1, true) == nil) then
			table.insert(status_detail, '<hr />' .. status.wiki_comment)
		end
	
		if half_turn then
			if string.sub(status.time, 0, -1) == '0.5' then
				table.insert(status_detail, '<hr />[[Half_Turns|Applied during the attack phase and lasts until the turn ends.]]<br />')
			else
				table.insert(status_detail, '<hr />[[Half_Turns|Applied during the attack phase.]]<br />On the next turn, it\'ll have ')
				if string.match(status.time, '%d.%d-%d.%d[tT]') == nil then
					table.insert(status_detail, string.sub(status.time, 0, -4))
				else
					local time_parts = mw.text.split(status.time, '-', true)
					table.insert(status_detail,  string.sub(time_parts[1], 0, -3) .. '-' .. string.sub(time_parts[2], 0, -4))
				end
				table.insert(status_detail, ' turns remaining.')
			end
		end
	
		status_detail = table.concat(status_detail)
		
		local status_label = {}
		local status_link = status.page or ('Status Effects#' .. (status.ref or status.fetch_name or status_name))
		
		if status.category then
			table.insert(status_label, '[[Category:' .. status.category .. ']]')
		end
		if status.icon then
			table.insert(status_label, '[[File:' ..status.icon .. '|25px|link=' .. status_link .. ']]')
		end
		if not only_icon then
			table.insert(status_label, '[[' .. status_link .. '|' .. status_name .. ']]')
		end
		status_label = table.concat(status_label)
		
		-- Format like tt template call {{tt|status_label|status_detail|line=false}}
		
		local result = '<span class="tooltip" style="border-bottom: 0;">' .. status_label ..
			'<span class="tooltiptext">' .. status_detail .. '</span></span>'
		
		if status.icon then
			return '<span class="image_link">' .. result .. '</span>'
		else
			return result
		end
	end
end

function p._formatOld(name, args)
	icon_name = (args[2] or name) .. '.png'
	return '<span class="image_link">' ..
	       '[[File:Status ' .. icon_name .. '|link=Status Effects|25px]]' .. 
	       '[[Status Effects|'.. name .. ']]' ..
	       '</span>[[Category:Old Status System]]'
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.checkParam(text)
	if text and (text == '') then
		return nil
	end
	return text
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

function p.test4()
	local frame = mw.getCurrentFrame()
	frame.args.name = 'Critical Hit Rate Boosted'
	frame.args.time = '180s'
	frame.args.amount = '70%'
	frame.args.probability = '90%'
	return p.format2(frame)
end

function p.test5()
	return p._format2({
		name = 'Counters on DMG',
		a = '100%',
		t = '3T',
		c = 'Counter attacks grant 4% charge bar per hit (includes Recklessness Incarnate).',
		hide = 'wiki_comment',
	})
end

return p