Module:Battles

From Granblue Fantasy Wiki
Jump to navigation Jump to search

This module implements {{BattlePhase}} and {{BattleEnemy}}.


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

-- Renders
function p.renderTemplate(frame)
	local result = {}
	-- prefix
	local prefix = 'phase'
	if frame.args.prefix ~= nil then
		prefix = frame.args.prefix
	end
	local mainTemplate = frame.args.mainTemplate
	local phaseTemplate = frame.args.phaseTemplate
	local edit_title = frame.args.edit_title
	local edit_link = frame.args.edit_link
	
	local frameTemplate = frame
	-- if we have a parent assume we're included from a template
	if frame:getParent() ~= nil then
		frameTemplate = frame:getParent()
	end
	--local edit_title = ''
	--local edit_title_debug = ''
	--local titleFrame = frameTemplate
	--while (titleFrame ~= nil) do
	--	edit_title = edit_title .. '--' .. titleFrame:getTitle()
	--	titleFrame = titleFrame:getParent()
	--end
	--while (titleFrame ~= nil) and ((string.find(titleFrame:getTitle(), 'Template:') ~= nil) or (string.find(titleFrame:getTitle(), 'Module:') ~= nil)) do
	--	edit_title_debug = edit_title_debug .. '--' .. titleFrame:getTitle()
	--	titleFrame = titleFrame:getParent()
	--end
	--if titleFrame ~= nil then
	--	edit_title = titleFrame:getTitle()
	--end
	
	local hasDescNotes = false
	local phases = {}
	for i=1,9 do
		--local phaseKey = '%%%%'..prefix..i..'%%%%'
		local phaseText = ''
		local phase = frameTemplate.args[i]
		if (phase ~= nil) and (string.len(phase) > 0) then
			local temp = ''
			if (frame.args.dumpPhases ~= nil) and (frame.args.dumpPhases == 'yes') then
				table.insert(result, phase)
			end
			if pcall(function() temp = mw.text.jsonDecode(phase) end) then
				phase = {}
				phase.phase = '??'
				if temp.phase ~= nil then
					phase.phase = temp.phase
				end
				for j=1,9 do
					for k=1,9 do
						if (temp.enemies[j] ~= nil) and (temp.enemies[j][k] ~= nil) then
							for ix,key in pairs({'name','row','lvl','element','hp','ct','od','ca_desc','resist','icon_s','notes'}) do
								local enemy_count = 0
								if temp.enemies[j][k][key] ~= nil then
									local value = temp.enemies[j][k][key]
									enemy_count = enemy_count + 1
									if k == 1 then 
										phase['enemy'..j..'_'..key] = value
									end
									phase['enemy'..j..k..'_'..key] = value
									if ((key == 'ca_desc') or (key == 'notes')) and (value ~= nil) and (string.len(value) > 0) then
										hasDescNotes = true
									end
								end
								phase['enemy'..j..'_count'] = enemy_count
							end
						end
					end
				end
				
				phaseText = p.renderPhase(frame, phaseTemplate, phase, temp.enemies, frameTemplate.args)
			else
				mw.log('Failed to decode: ' .. phase)
				phaseText = ''
			end
		end
		
		phases[i] = phaseText
	end
	
	local args = {}
	--mw.log(frameTemplate.args[1])
	for key,value in pairs(frameTemplate.args) do
		args[key] = value
	end
	args['has_descnotes'] = tostring(hasDescNotes)
	args['edit_title'] = edit_title
	args['edit_link'] = edit_link
	--args['edit_title_debug'] = edit_title_debug
	local text = frame:expandTemplate{ title = mainTemplate, args = args }

	-- find parts we need to replace with phases
	local parts = {}
	for i=1,9 do
		local phaseKey = '%%%%'..prefix..i..'%%%%'
		local pos = string.find(text, phaseKey)
		if pos ~= nil then
			table.insert(parts, { phase = i, start = pos, len = string.len(phaseKey)-4 })
		end
	end

	-- split up the text into an array and insert phases
	local start_offset = 1
	for i=1,9 do
		local part_key = nil
		local offset = string.len(text)
		for key,part in pairs(parts) do
			if (part.start >= start_offset) and (part.start < offset) then
				part_key = key
				offset = part.start
			end
		end

		-- if we found a part replace it
		if part_key ~= nil then
			local part = parts[part_key]
			--mw.log('part ' .. part.phase .. ': ' .. part.start .. ',' .. part.len)
		
			-- add text between current position and start of part
			--mw.log('start_offset: '..start_offset..' to offset:'..offset)
			if offset > start_offset then
				local sub = string.sub(text, start_offset, offset-1)
				--mw.log('inserting: '..mw.text.jsonEncode(sub))
				table.insert(result, sub)
			end
			start_offset = offset + part.len
			-- add phase
			if phases[part.phase] ~= nil then
				local sub = phases[part.phase]
				--mw.log('inserting: '..mw.text.jsonEncode(sub))
				table.insert(result, phases[part.phase])
			end
		end
	end
	if start_offset < string.len(text) then
		local sub = string.sub(text, start_offset)
		--mw.log('appending: '..mw.text.jsonEncode(sub))
		table.insert(result, sub)
	end

	return table.concat(result,'')
end

function p.renderPhase(frame, template, phase, enemies, context)
	return frame:expandTemplate{ title = template, args = phase }
end

-- Enemy details as a JSON string for passing data between templates
function p.jsonEnemy(frame)
	if frame:getParent() ~= nil then
		frame = frame:getParent()
	end
	local result = {}
	local params = {'name','row','lvl','element','hp','ct','od','ca_desc','resist','notes'}
	for key,value in pairs(params) do
		if frame.args[value] ~= nil then
			result[value] = frame.args[value]
		end
	end
	return mw.text.jsonEncode(result)
end

function p.jsonEnemy2(frame)
	local args = getArgs(frame, {
		trim = true,
		removeBlanks = true,
	})
	return p._jsonEnemy2(args)
end

function p.jsonEnemy3(frame)
	local args = getArgs(frame, {
		trim = true,
		removeBlanks = true,
	})
	return p._jsonEnemy3(args)
end

function p.format_int(number)

  local i, j, minus, int, fraction = tostring(number):find('([-]?)(%d+)([.]?%d*)')

  -- reverse the int-string and append a comma to all blocks of 3 digits
  int = int:reverse():gsub("(%d%d%d)", "%1,")

  -- reverse the int-string back remove an optional comma and put the 
  -- optional minus and fractional part back
  return minus .. int:reverse():gsub("^,", "") .. fraction
end

function p._jsonEnemy2(args)
	local result = {}

	if args['id'] ~= nil then
		local qf = 'id,name,lvl,element,hp,ct,od,rare,icon_s'
		local qa = { limit = 1, where = 'id='..args['id'] }
		for _, row in ipairs(mw.ext.cargo.query('enemies', qf, qa)) do
			for key, value in pairs(row) do
				result[key] = value
			end
			result['hp'] = p.format_int(result['hp'])
			result['od'] = (result['od'] == '1') and 'yes' or 'no'
			result['rare'] = (result['rare'] == '1') and 'yes' or 'no'
		end
	end

	-- allow overriding values
	local params = {'name','row','lvl','element','hp','ct','od','ca_desc','resist','notes'}
	for key,value in pairs(params) do
		if args[value] ~= nil then
			result[value] = args[value]
		end
	end

	return mw.text.jsonEncode(result)
end

function p._jsonEnemy3(args)
	local result = {}

	if args['id'] ~= nil then
		local qf = 'id,name,lvl,element,hp,ct,od,rare,icon_s'
		-- ,status_notes,status1,status2,status3,status4,status5,status6,status7,status8,status9
		-- ,status1_label,status2_label,status3_label,status4_label,status5_label,status6_label,status7_label,status8_label,status9_label
		local qa = { limit = 1, where = 'id='..args['id'] }
		for _, row in ipairs(mw.ext.cargo.query('enemies', qf, qa)) do
			for key, value in pairs(row) do
				result[key] = value
			end
			if (tonumber(result['ct']) > 50) then
				result['ct'] = '0'
			end
			result['hp'] = p.format_int(result['hp'])
			result['od'] = (result['od'] == '1') and 'yes' or 'no'
			result['rare'] = (result['rare'] == '1') and 'yes' or 'no'
		end
	end

	-- allow overriding values
	local params = {
		'name','row','lvl','element','hp','ct','od','ca_desc','resist','notes'
	}
	for ix = 1, 9 do 
		table.insert(params, 'label'..ix)
		table.insert(params, 'status'..ix)
		table.insert(params, 'notes'..ix)
		table.insert(params, 'ca_desc'..ix)
		table.insert(params, 'resist'..ix)
	end
	for key,value in pairs(params) do
		if args[value] ~= nil then
			result[value] = args[value]
		end
	end
	
	-- trim etc
	result = getArgs(result, {
		trim = true,
		removeBlanks = false,
	})
    -- propagate status between modes
	result = p._copyStatus(result)
	result.phases = {}
	result.has_phases = false
	for ix = 1, 9 do
		if ((result['label'..ix] or '') ~= '') or ((result['status'..ix] or '') ~= '') then
			local phase = {}
			phase.label = result['label'..ix] or ''
			phase.status = result['status'..ix] or ''
			phase.notes = result['notes'..ix] or ''
			phase.ca_desc = result['ca_desc'..ix] or ''
			phase.resist = result['resist'..ix] or ''
			phase.icon_s = result['icon_s'..ix] or result.icon_s

			phase.status.element = phase.status.element or result.element
			phase.status.ct = phase.status.ct or tonumber(result.ct)

			result.has_phases = true
			table.insert(result.phases, phase)
		end
	end
	
	local temp = {}
	for _, v in ipairs({'id','name','row','lvl','element','hp','ct','od','ca_desc','resist','notes','phases'}) do
		if result[v] ~= nil then
			temp[v] = result[v]
		end
	end
	result = temp

	return mw.text.jsonEncode(result)
end

function p._copyStatus(params)
	if (params.status1 or '') == '' then return params end
	
	local known_debuffs = {
		'DEF Down', 'ATK Down', 'Gravity', 'Delay', 'Lethal Hit', 'Poison', 'Burn', 'Putrefied', 'Blind', 'Charm', 'Zombified', 'Sleep', 'Paralyzed', 'Stone'
	}
	local known_keys = {
		'atk', 'aoe', 'hp', 'element', 'ct',
		'def', 'fire', 'water', 'earth', 'wind', 'light', 'dark'
	}
	for _, v in ipairs(known_debuffs) do table.insert(known_keys, v) end

	local status = {}
	local force_keys = {'def', 'DEF Down', 'ATK Down', 'Gravity', 'Delay', 'Lethal Hit', 'Poison', 'Burn', 'Putrefied', 'Blind', 'Charm', 'Zombified', 'Sleep', 'Paralyzed', 'Stone'}
	for _, v in ipairs(force_keys) do status[v] = '?' end
	status['hp'] = 100
	status['aoe'] = 'NO'
	for ix = 1, 9 do
		if params['status'..ix] ~= nil then
			status = p._splitStatus(params['status'..ix], status)
			params['status'..ix] = status
		end
	end

	return params
end

function p._splitStatus(status, copy)
	local result = {}
	for k, v in pairs(copy) do result[k] = v end

	for _, v in ipairs(mw.text.split(status, ';', true)) do
		local temp = mw.text.split(v, '=', true)
		local key, value = unpack(temp)
		if (value == nil) then value = '?' end
		if (value ~= '?') then
			if (key == 'hp') or (key == 'ct') or (key == 'atk') or (key == 'def') then value = tonumber(value) end
		end
		result[key] = value
	end

	return result
end

-- Phase details as a JSON string for passing data between templates
function p.jsonPhase(frame)
	if frame:getParent() ~= nil then
		frame = frame:getParent()
	end
	return mw.text.jsonEncode(p.parsePhase(frame))
end

function p.parsePhase(frame)
	local result = {}
	
	local phase = '???'
	if frame.args.name ~= nil then
		phase = frame.args.name
	elseif frame.args.phase ~= nil then
		phase = frame.args.phase
	end
	
	for ix,name in pairs {'label','label1','label2','label3'} do
		if frame.args[name] ~= nil then
			result[name] = frame.args[name]
		end
	end
	if (result.label1 ~= nil) and (result.label == nil) then
		result.label = result.label1
	elseif (result.label ~= nil) and (result.label1 == nil) then
		result.label1 = result.label
	end

	-- Find unindexed enemies
	for i=1,9 do
		if frame.args[i] ~= nil then
			local enemy = mw.text.jsonDecode(frame.args[i])
			for key,value in pairs(enemy) do
				frame.args['enemy'..i..'_'..key] = value
			end
		end
	end
	
	-- Parse out all enemies and assign them a row
	local rows = {}
	local current_row = 0
	for i=1,9 do
		local key_name    = 'enemy' .. i .. '_name'
		local key_icon    = 'enemy' .. i .. '_icon'
		local key_icon_s  = 'enemy' .. i .. '_icon_s'
		local key_row     = 'enemy' .. i .. '_row'
		local key_lvl     = 'enemy' .. i .. '_lvl'
		local key_element = 'enemy' .. i .. '_element'
		local key_hp      = 'enemy' .. i .. '_hp'
		local key_ct      = 'enemy' .. i .. '_ct'
		local key_od      = 'enemy' .. i .. '_od'
		local key_resist  = 'enemy' .. i .. '_resist'
		local key_ca_desc = 'enemy' .. i .. '_ca_desc'
		local key_notes   = 'enemy' .. i .. '_notes'

		if frame.args[key_name] ~= nil then
			local name = frame.args[key_name]
			
			local row = 0
			if frame.args[key_row] ~= nil then
				row = tonumber(frame.args[key_row])
			else
				current_row = current_row + 1
				row = current_row
			end

			local icon = ''
			if frame.args[key_icon] ~= nil then
				icon = frame.args[key_icon]
			end

			local icon_s = ''
			if frame.args[key_icon_s] ~= nil then
				icon_s = frame.args[key_icon_s]
			end
			
			local lvl = '??'
			if frame.args[key_lvl] ~= nil then
				lvl = frame.args[key_lvl]
			end
			
			local element = 'Unknown'
			if frame.args[key_element] ~= nil then
				element = string.lower(frame.args[key_element])
			end
			
			local hp = '???'
			if frame.args[key_hp] ~= nil then
				hp = frame.args[key_hp]
			end
			
			local ct = -1
			if frame.args[key_ct] ~= nil then
				ct = tonumber(frame.args[key_ct])
			end
			
			local od = false
			if frame.args[key_od] ~= nil then
				od = string.lower(frame.args[key_od])
				od = ((od == 'yes') or (od == 'true') or (od == 'y'))
			end
			
			local resist = ''
			if frame.args[key_resist] ~= nil then
				resist = frame.args[key_resist]
			end
			
			local ca_desc = ''
			if frame.args[key_ca_desc] ~= nil then
				ca_desc = frame.args[key_ca_desc]
			end
			
			local notes = ''
			if frame.args[key_notes] ~= nil then
				notes = frame.args[key_notes]
			end

			table.insert(rows, { row=row, name=name, icon=icon, icon_s=icon_s, lvl=lvl, element=element, hp=hp, ct=ct, od=od, resist=resist, ca_desc=ca_desc, notes=notes })
		end
	end

	local enemies = {}
	for ix,value in pairs(rows) do
		if enemies[value.row] == nil then
			enemies[value.row] = {}
		end
		table.insert(enemies[value.row], value)
	end
	
	result.phase = phase
	result.enemies = enemies
	
	return result
end

function p.testParsePhase()
	frame = mw.getCurrentFrame()
	frame.args.phase = 'Wave 1'
	frame.args.enemy1_name = 'mob1'
	frame.args.enemy1_lvl = '123'
	frame.args.enemy1_element = 'DaRk'
	frame.args.enemy1_hp = '123,456,789'
	frame.args.enemy1_ct = '3'
	frame.args.enemy1_od = 'yes'
	frame.args.enemy1_icon_s = 'test.png'
	frame.args.enemy1_ca_desc = [[* Bonggg...]]
	frame.args.enemy1_notes = [[Does not attack in bell form except for charge attacks.]]
	frame.args.enemy2_name = 'mob2'
	frame.args[3] = mw.text.jsonEncode({name='mob3',lvl=222,element='wind'})
	
	return p.jsonPhase(frame)
end

function p.testRender()
	frame = mw.getCurrentFrame()
	
	frame.args.mainTemplate = 'BattleEventQuest/Table'
	frame.args.phaseTemplate = 'BattlePhase/Raid'
	frame.args['header'] = 'Nightmare'
	frame.args.name = 'Level 70 Maddie-Blast Form'
	frame.args.image = 'EventQuest Platinum Sky (Nightmare).jpg'
	frame.args.cost = '0 AP'
	frame.args.unlock = 'Randomly appears after hosting Very Hard or Extreme.'
	frame.args.loot_clear = '{{Itm|Blue Sky Crystal,1}}'
	frame.args.loot_honor = '25000'
	frame.args.loot_token = '24'
	frame.args.loot_loyalty = '100'
	frame.args.loot_wood = '{{ItmLst|Gold Badge$nolink}}'
	frame.args.loot_silver = '{{ItmLst|angel|Mechanic\'s Spanner$nolink}}'
	frame.args.loot_gold = ''
	--frame.args[1] = '{"enemies":[[{"od":true,"row":1,"ct":2,"ca_desc":"* Bonggg...\n: Plain damage to all allies and inflict Status AttackDown.pngAttack DOWN for 2 turns. (1st form only?)\n* Decemvir N\n: Damage to one ally and inflict Status Death.pngCounting Down for 5 turns.\n* Let Go OD\n: Damage to all allies and inflict Status Confused.pngIntoxicated for 1 turn.\n* Purify Mind TR\n: 108-hit damage to random allies. (2nd form only)","lvl":"30","hp":"???","element":"earth","name":"Joya","notes":"* Does not attack in bell form except for charge attacks.\n* If ally has Status Sleep.pngSleep\n: Casts Purify Mind.\n* 75% HP Trigger\n: Transforms\n* 25% HP Trigger\n: True Power\n: Base diamonds reduced to ◇.\n* Status Confused.pngIntoxicated\n: Ally randomly attacks an ally or enemy with plain damage. If Intoxicated is not removed after 1 turn, ally gains Status Sleep.pngSleep for 2 to 4 turns. If an Intoxicated ally is hit, debuff is removed.\n* Status Death.pngCounting Down\n: Take 100% of max HP in plain damage when count reaches 0."}]],"phase":"Boss"}'
	frame.args[1] = '{"phase":"Wave 1","enemies":[[{"notes":"","ca_desc":"","hp":"20,000","element":"earth","resist":"","od":false,"name":"Raga","lvl":"10","ct":2,"icon_s":"","row":1,"icon":""}],[{"notes":"","ca_desc":"","hp":"33,000","element":"earth","resist":"","od":false,"name":"Dvesha","lvl":"10","ct":3,"icon_s":"","row":2,"icon":""}]]}'

	return p.renderTemplate(frame)
end

function p.testRender2()
	frame = mw.getCurrentFrame()
	
	local testArgs = {}
	frame.args.mainTemplate = 'BattleFreeQuest/Row'
	frame.args.phaseTemplate = 'BattlePhase/Quest'
	frame.args.stages = 3
	frame.args.name = 'I Challenge You!'
	frame.args.jpname = '若き騎士達からの挑戦'
	frame.args.cost = '25 AP'
	frame.args.element = 'dark'
	frame.args.notes = '{{SR}} only'
	frame.args.loot_clear = '{{Itm|Crystal,50}}'
	frame.args.loot_side = '{{ItmLst|Spring Water Jug,2-2}}'
	frame.args.loot_wood = '{{ItmLst|Normal Weapon,0-1|Falcon Feather,2-3}}'
	frame.args.loot_silver = '{{ItmLst|Spring Water Jug,3-8|Vermilion Stone,2-3}}'
	frame.args.loot_gold = ''
	frame.args[1] = '{"enemies":[[{"od":false,"row":1,"ct":2,"ca_desc":"","lvl":"32","hp":"120,000","element":"light","name":"Light Warrior","notes":""},{"od":false,"row":1,"ct":1,"ca_desc":"","lvl":"32","hp":"75,000","element":"light","name":"Prism Fly","notes":""},{"od":false,"row":1,"ct":2,"ca_desc":"","lvl":"32","hp":"80,000","element":"light","name":"Sabrewolf","notes":""}],[{"od":false,"row":2,"ct":2,"ca_desc":"","lvl":"32","hp":"120,000","element":"light","name":"Goblin Knight","notes":""},{"od":false,"row":2,"ct":3,"ca_desc":"","lvl":"32","hp":"100,000","element":"light","name":"Mid Golem","notes":""}]],"label1":"1 of","phase":"Wave 1A","label":"1 of","label2":"1 of"}'
	frame.args[2] = '{"enemies":[[{"od":false,"row":1,"ct":2,"ca_desc":"","lvl":"32","hp":"80,000","element":"light","name":"Sabrewolf","notes":""},{"od":false,"row":1,"ct":2,"ca_desc":"","lvl":"32","hp":"120,000","element":"light","name":"Goblin Knight","notes":""}],[{"od":false,"row":2,"ct":2,"ca_desc":"","lvl":"32","hp":"120,000","element":"light","name":"Light Warrior","notes":""}]],"label1":"1 of","phase":"Wave 2A","label":"1 of","label2":"1 of"}'
	frame.args[3] = '{"enemies":[[{"od":true,"row":1,"ct":3,"ca_desc":"","lvl":"32","hp":"400,000","element":"light","name":"Tooty","notes":""}]],"phase":"Boss A"}'
	frame.args[4] = ''
	frame.args[5] = '{"enemies":[[{"od":false,"row":1,"ct":1,"ca_desc":"","lvl":"32","hp":"6,000","element":"light","name":"Wandering Goldslime","notes":""}]],"phase":"Wave 2B"}'
	frame.args[6] = '{"enemies":[[{"od":false,"row":1,"ct":3,"ca_desc":"","lvl":"32","hp":"380,000","element":"light","name":"Mantis Overlord","notes":""}]],"phase":"Boss B"}'
	testArgs.mainTemplate = 'BattleFreeQuest/Row'
	testArgs.phaseTemplate = 'BattlePhase/Quest'
	testArgs.stages = 3
	testArgs.name = 'I Challenge You!'
	testArgs.jpname = '若き騎士達からの挑戦'
	testArgs.cost = '25 AP'
	testArgs.element = 'dark'
	testArgs.notes = '{{SR}} only'
	testArgs.loot_clear = '{{Itm|Crystal,50}}'
	testArgs.loot_side = '{{ItmLst|Spring Water Jug,2-2}}'
	testArgs.loot_wood = '{{ItmLst|Normal Weapon,0-1|Falcon Feather,2-3}}'
	testArgs.loot_silver = '{{ItmLst|Spring Water Jug,3-8|Vermilion Stone,2-3}}'
	testArgs.loot_gold = ''
	testArgs[1] = '{"enemies":[[{"od":false,"row":1,"ct":2,"ca_desc":"","lvl":"32","hp":"120,000","element":"light","name":"Light Warrior","notes":""},{"od":false,"row":1,"ct":1,"ca_desc":"","lvl":"32","hp":"75,000","element":"light","name":"Prism Fly","notes":""},{"od":false,"row":1,"ct":2,"ca_desc":"","lvl":"32","hp":"80,000","element":"light","name":"Sabrewolf","notes":""}],[{"od":false,"row":2,"ct":2,"ca_desc":"","lvl":"32","hp":"120,000","element":"light","name":"Goblin Knight","notes":""},{"od":false,"row":2,"ct":3,"ca_desc":"","lvl":"32","hp":"100,000","element":"light","name":"Mid Golem","notes":""}]],"label1":"1 of","phase":"Wave 1A","label":"1 of","label2":"1 of"}'
	testArgs[2] = '{"enemies":[[{"od":false,"row":1,"ct":2,"ca_desc":"","lvl":"32","hp":"80,000","element":"light","name":"Sabrewolf","notes":""},{"od":false,"row":1,"ct":2,"ca_desc":"","lvl":"32","hp":"120,000","element":"light","name":"Goblin Knight","notes":""}],[{"od":false,"row":2,"ct":2,"ca_desc":"","lvl":"32","hp":"120,000","element":"light","name":"Light Warrior","notes":""}]],"label1":"1 of","phase":"Wave 2A","label":"1 of","label2":"1 of"}'
	testArgs[3] = '{"enemies":[[{"od":true,"row":1,"ct":3,"ca_desc":"","lvl":"32","hp":"400,000","element":"light","name":"Tooty","notes":""}]],"phase":"Boss A"}'
	testArgs[4] = ''
	testArgs[5] = '{"enemies":[[{"od":false,"row":1,"ct":1,"ca_desc":"","lvl":"32","hp":"6,000","element":"light","name":"Wandering Goldslime","notes":""}]],"phase":"Wave 2B"}'
	testArgs[6] = '{"enemies":[[{"od":false,"row":1,"ct":3,"ca_desc":"","lvl":"32","hp":"380,000","element":"light","name":"Mantis Overlord","notes":""}]],"phase":"Boss B"}'
	
	return p.renderTemplate(frame, testArgs)
end

function p.testEnemy()
	return p._jsonEnemy2({id = '1009020'})
end

function p.testEnemy3()
	return p._jsonEnemy3({
		id = '6064406',
		label1 = '100%',
		label2 = '50%',
		label3 = '25%',
		status1 = 'hp=100;def=15;atk=62000;aoe=yes;fire=90;water=0;earth=50;wind=50;light=50;dark=50;DEF Down=OK;ATK Down=OK;Gravity=OK;Delay=OK;Lethal Hit=RESIST;Poison=OK;Burn=RESIST;Putrefied=OK;Blind=RESIST;Charm=OK;Zombified=OK;Sleep=OK;Paralyzed=OK;Petrified=RESIST',
		status2 = 'hp=50;atk=88000',
		status3 = 'hp=25;def=14;atk=120000;Blind=OK;Petrified=OK',
		status4 = 'hp=0;BROKEN1;BROKEN2 TEST',
		notes1 = 'notes no 1',
		notes2 = 'notes no 2',
		notes3 = 'notes no 3',
		ca_desc1 = 'ca_desc 1',
		ca_desc2 = 'ca_desc 2',
		ca_desc3 = 'ca_desc 3'
	})	
end

return p