Module:Mermaid

From Portals of Phereon Wiki

Documentation for this module may be created at Module:Mermaid/doc

local p = {};
local cargo = mw.ext.cargo;
local utils = require( "Module:Utils" );

function p.spirits(frame)
	local temp_res = {};
	local temp_res2 = {};
	local results = cargo.query("spirit_evolution","name,element,image,fxskills,sizebonus,reqstr,reqhealth,reqtrait,reqmlvl,evinto",{
		where = 'element="' .. frame.args[1] .. '"';
	});
	for _, result in ipairs(results) do
		local header_req = {};
		if (result["reqstr"] ~= nil) then
			header_req[#header_req+1] = tostring(mw.html.create('span'):css('color','#cc0000'):wikitext("Str genes " .. result["reqstr"]));
		end
		if (result["reqhealth"] ~= nil) then
			header_req[#header_req+1] = tostring(mw.html.create('span'):css('color','#00AD00'):wikitext("Health genes " .. result["reqhealth"]));
		end
		if (result["reqmlvl"] ~= nil) then
			header_req[#header_req+1] = tostring(mw.html.create('span'):css('color','#CC9900'):wikitext("Max Level genes " .. result["reqmlvl"]));
		end
		if (result["reqtrait"] ~= nil) then
			header_req[#header_req+1] = tostring(mw.html.create('span'):css('color','#B800B8'):wikitext("Trait " .. result["reqlust"]));
		end
		local header_text = '';
		if #header_req > 0 then
			header_text = result["name"] .. ' Req. ' .. table.concat(header_req," ");
		else
			header_text = result["name"];
		end
		local fix_skills = {};
		if (result["fxskills"] ~= nil) then
			local fix_skills_parsed = utils.toNumberedTable(result["fxskills"],'/');
			for _, skill in ipairs(fix_skills_parsed) do
				fix_skills[#fix_skills+1] = '+ ';
				fix_skills[#fix_skills+1] = skill;
				fix_skills[#fix_skills+1] = '<br>';
			end
			fix_skills[#fix_skills] = nil;
		end
		local fix_size = {};
		if (result["sizebonus"] ~= nil) then
			fix_size[#fix_size+1] = '+ ';
			fix_size[#fix_size+1] = result["sizebonus"];
			fix_size[#fix_size+1] = ' Size';
		end
		local evolutions = cargo.query("spirit_evolution_part","evosource,evosize,evoelement,evotype,evoskills",{
			where = 'name="' .. result["name"] .. '"';
		});
		local evo_res = {};
		local evo_table = {};
		evo_table["n"] = 0;
		local evo_all_skills = {};
		for _, evolution in ipairs(evolutions) do
			if evolution["evoelement"] == nil or evolution["evoelement"] == result["element"] then
				if (evolution["evoskills"] ~= nil) then
					evo_all_skills[#evo_all_skills+1] = utils.toNumberedTable(evolution["evoskills"],'/');
				else
					evo_all_skills[#evo_all_skills+1] = {};
				end
			end
		end
		local found_common = true;
		local found_skill = false;
		local common_skills = {};
		if #evo_all_skills > 1 then
			for _, skill in pairs(evo_all_skills[1]) do
				found_common = true;
				for i, skills_cp in ipairs(evo_all_skills) do
					if i > 1 then
						found_skill = false;
						for _, skill_cp in pairs(skills_cp) do
							if skill == skill_cp then
								found_skill = true;
								break;
							end
						end
						if found_skill == false then
							found_common = false;
							break;
						end
					end
					if found_common == false then
						break;
					end
				end
				if found_common == true then
					fix_skills[#fix_skills+1] = '+ ';
					fix_skills[#fix_skills+1] = skill;
					fix_skills[#fix_skills+1] = '<br>';
					common_skills[#common_skills+1] = skill;
				end
			end
		end
		if #fix_skills > 2 then
			fix_skills[#fix_skills] = nil;
		end
		for _, evolution in ipairs(evolutions) do
			if evolution["evoelement"] == nil or evolution["evoelement"] == result["element"] then
				if evolution["evosource"] == nil then
					evo_res[#evo_res+1] = '<br>';
					evo_res[#evo_res+1] = string.upper(string.sub(evolution["evotype"],1,1)) .. string.sub(evolution["evotype"],2);
					evo_res[#evo_res+1] = ": ";
					if (evolution["evoskills"] ~= nil) then
						local evo_skills_parsed = utils.toNumberedTable(evolution["evoskills"],'/');
						for _, evo_skill in ipairs(evo_skills_parsed) do
							found_common = false;
							for _, common_skill in ipairs(common_skills) do
								if evo_skill == common_skill then
									found_common = true;
									break;
								end
							end
							if found_common == false then
								evo_res[#evo_res+1] = evo_skill;
								evo_res[#evo_res+1] = ", ";
							end
						end
					end
					if (evolution["evosize"] ~= nil) then
						evo_res[#evo_res+1] = evolution["evosize"];
						evo_res[#evo_res+1] = " size";
						evo_res[#evo_res+1] = ", ";
					end
					evo_res[#evo_res] = nil;
				else
					if evo_table[evolution["evosource"]] == nil then
						evo_table[evolution["evosource"]] = {};
						evo_table[evolution["evosource"]]["name"] = evolution["evosource"];
						evo_table[evolution["evosource"]]["text"] = {};
						evo_table["n"] = evo_table["n"] + 1;
					end
					local current_row = evo_table[evolution["evosource"]]["text"];
					current_row[#current_row+1] = string.upper(string.sub(evolution["evotype"],1,1)) .. string.sub(evolution["evotype"],2);
					current_row[#current_row+1] = ": ";
					if (evolution["evoskills"] ~= nil) then
						local evo_skills_parsed = utils.toNumberedTable(evolution["evoskills"],'/');
						for _, evo_skill in ipairs(evo_skills_parsed) do
							current_row[#current_row+1] = evo_skill;
							current_row[#current_row+1] = ", ";
						end
					end
					if (evolution["evosize"] ~= nil) then
						current_row[#current_row+1] = evolution["evosize"];
						current_row[#current_row+1] = " size";
						current_row[#current_row+1] = ", ";
					end
					current_row[#current_row] = nil;
					current_row[#current_row+1] = '<br>';
				end
			end
		end
		if #fix_size > 0 and #fix_skills > 0 then
			fix_size[#fix_size+1] = "<br>";
		end
		if #fix_size == 0 and #fix_skills == 0 and #evo_res > 0 then
			evo_res[1] = "";
		end
		local html_table = mw.html.create('table'):addClass('label-table')
			:tag('thead')
			:tag('tr')
			:tag('th'):attr('colspan', '3')
			:tag('div'):addClass('label-header'):wikitext(header_text):done():done():done():done()
			:tag('tbody')
			:tag('tr')
			:tag('td'):attr('rowspan', '0')
			:tag('img'):addClass('label-image')
			:attr('src', frame:callParserFunction{ name = 'filepath', args = result["image"],'72x72px' }):done():done()
			:tag('td'):attr('colspan', '2'):css('border','none'):done():done();

		local misc_text = table.concat(fix_size,"") .. table.concat(fix_skills,"") .. table.concat(evo_res,"");
		if #misc_text > 0 then
		    html_table = html_table:tag('tr')
		    :tag('td'):attr('colspan', '2')
		    :tag('span'):addClass('label-text'):wikitext(misc_text):done():done():done();
		end;
		if evo_table["n"] > 0 then
			evo_table["n"] = nil;
			for _, evo_type in pairs(evo_table) do
				evo_type["text"][#evo_type["text"]] = nil;
				local name = string.gsub(evo_type["name"], '/', '<br>');
				html_table = html_table:tag('tr')
				:tag('td'):tag('span'):addClass('label-text'):wikitext(name):done():done()
				:tag('td'):tag('span'):addClass('label-text'):wikitext(table.concat(evo_type["text"],"")):done():done():done();
			end
		end;
		local squashed_name = string.gsub(result["name"], '%s+', '');
		temp_res[#temp_res+1] = squashed_name;
		temp_res[#temp_res+1] = '[['
		temp_res[#temp_res+1] = tostring(html_table:allDone());
		temp_res[#temp_res+1] = ']]\n';
		if (result["evinto"] ~= nil) then
			temp_res[#temp_res+1] = squashed_name;
			temp_res[#temp_res+1] = ' --> ';
			temp_res[#temp_res+1] = string.gsub(string.gsub(result["evinto"], '%s+', ''), '/', ' & ');
			temp_res[#temp_res+1] = '\n';
		end
		temp_res2[#temp_res2+1] = 'click '
		temp_res2[#temp_res2+1] = squashed_name;
		temp_res2[#temp_res2+1] = ' "/wiki/';
		temp_res2[#temp_res2+1] = result["name"];
		temp_res2[#temp_res2+1] = '" "';
		temp_res2[#temp_res2+1] = squashed_name;
		temp_res2[#temp_res2+1] = '"\n';
	end
	local restbl = table.concat(temp_res,"");
	local result = string.gsub( string.gsub(string.gsub(restbl,'"',"'"), '%[%[', '%["'), '%]%]', '"%]') .. table.concat(temp_res2,"");
	
    return result;
end

function p.skillTree(frame)
	local imgSize = frame.args[4];
	local imgSizeParsed = {};
	for match in (imgSize..'x'):gmatch("(.-)x") do
    	imgSizeParsed[#imgSizeParsed+1] = match;
	end
	local nodeSize = 'width:'..imgSizeParsed[1]..'px;height:'..imgSizeParsed[2]..'px';
	local connection_w = math.floor(tonumber(imgSizeParsed[1])/2);
	local connection_h = math.floor(tonumber(imgSizeParsed[2])/2.5);
	local data = mw.title.makeTitle("",frame.args[3].."/load"):getContent();
	if (data == nil) then return ""; end
	data = string.gsub(string.gsub(data,'{{Documentation}}',''),'\\\"','"');
	local stat,decoded = pcall(mw.text.jsonDecode,data);
	if (stat == false) then return ""; end
	local tf_type_img = {
    	[0] = '',
    	[1] = '[[File:Icon StatIncrease.png|' .. imgSize .. 'px|link=]]',
    	[2] = '',
    	[3] = '[[File:Icon GeneIncrease.png|' .. imgSize .. 'px|link=]]',
    	[4] = '[[File:Icon Skill.png|' .. imgSize .. 'px|link=]]',
    	[5] = '[[File:Icon Passive.png|' .. imgSize .. 'px|link=]]',
    	[6] = '[[File:Icon Form.png|' .. imgSize .. 'px|link=]]',
    	[7] = '[[File:Icon Buff Part.png|' .. imgSize .. 'px|link=]]',
    	[8] = '[[File:Icon_Special.png|' .. imgSize .. 'px|link=]]',
    	[9] = '[[File:Icon Core.png|' .. imgSize .. 'px|link=]]',
    };
    local tf_type = {
    	[0] = '',
    	[1] = 'Stat increase',
    	[2] = '',
    	[3] = 'Gene increase',
    	[4] = 'Skill',
    	[5] = 'Passive',
    	[6] = 'Special form',
    	[7] = 'BodyPart',
    	[8] = 'Special',
    	[9] = 'Core',
    };
    local tf_species = {
    	[3] = 'Harpy',
    	[6] = 'Mermaid',
    	[8] = 'Centaur',
    	[10] = 'Lymean',
    	[11] = 'Succubus',
    	[12] = 'PlantGirl',
    	[18] = 'LavaGirl',
    	[31] = 'LizardGirl',
    	[46] = 'InsectGirl',
    	[78] = 'BeastGirl',
    	[105] = 'Shadow',
    	[174] = 'Tanid'
    };
	local unknw = function(tab, index) return 'Unknown' end;
    setmetatable(tf_type,{__index = unknw});
    setmetatable(tf_type_img,{__index = unknw});
    setmetatable(tf_species,{__index = unknw});
    local tf_node = '[[File:Node.png|' .. imgSize .. 'px|link=]]';
    local tf_connection_parent_h = 'width:' .. connection_w-14 .. 'px;height:' .. connection_h-14 .. 'px';
    local tf_connection_parent_v = 'height:' .. connection_h-7 .. 'px;margin-top:-1px;text-align:center';
    local tf_connection_img_h = 'width:' .. connection_w .. 'px;height:' .. connection_h .. 'px;' .. 'margin-left:-7px;' .. 'margin-top:-' .. (connection_h-14)/2 .. 'px;';
    local tf_connection_img_v = 'width:' .. connection_w .. 'px;height:' .. connection_h .. 'px;' .. 'margin-top:-3px;' .. 'display:inline-block';
    local tf_connection = ''; --'[[File:Connection empty.png|' .. connection_w .. 'x' .. connection_h .. 'px|link=]]';
    local tf_connection_a = ''; --'[[File:Connection full.png|' .. connection_w .. 'x' .. connection_h .. 'px|link=]]';
    local tf_count = '[[File:EmptyBall.png|10x10px|link=]]';
    local html_table = mw.html.create('table'):addClass('label-table label-table-'..frame.args[2]):attr('data-species-primary',frame.args[2]);
	local html_rows = {
		[0] = mw.html.create('tr'):addClass('label-row'):tag('td'):done(),
		[1] = mw.html.create('tr'):addClass('label-row'):tag('td'):done(),
		[2] = mw.html.create('tr'):addClass('label-row'):tag('td'):done(),
		[3] = mw.html.create('tr'):addClass('label-row'):tag('td'):done(),
		[4] = mw.html.create('tr'):addClass('label-row'):tag('td')
				:tag('div'):cssText(tf_connection_parent_h)
				:tag('div'):cssText(tf_connection_img_h):addClass('label-connection-h-a'):wikitext(tf_connection_a):done():done():done(),
		[5] = mw.html.create('tr'):addClass('label-row'):tag('td'):done(),
		[6] = mw.html.create('tr'):addClass('label-row'):tag('td'):done(),
		[7] = mw.html.create('tr'):addClass('label-row'):tag('td'):done(),
		[8] = mw.html.create('tr'):addClass('label-row'):tag('td'):done(),
	}
	local header_width = 'width:' .. imgSizeParsed[1] .. 'px';
	for i, result in ipairs(decoded[frame.args[2]]) do
		local current_row = ((i-1) - (math.floor((i-1)/5))*5)*2;
		local image = tf_type_img[result["type"]];
		local name = string.gsub(result["name"],'%f[^%l](%u)','<wbr>%1');
		local html_node = mw.html.create('td'):tag('div'):addClass('label-node'):cssText(nodeSize)
			:attr('data-cost-primary',result["costPrimary"]):attr('data-species-primary',frame.args[2])
			:attr('data-name',name):attr('data-type-id',result["type"]):attr('data-type-name',tf_type[result["type"]])
			:tag('span'):addClass('label-header'):wikitext(name):cssText(header_width):done()
			:tag('span'):addClass('label-image'):wikitext(image):done()
			--:tag('span'):addClass('label-image-background'):wikitext(tf_node):done()
		    :tag('span'):addClass('label-primary label-primary-'..frame.args[2]):wikitext(result["costPrimary"]):done();
		for i = 1, result["count"] do
			html_node
			:tag('span'):addClass('label-count-' .. i):wikitext(tf_count):done():attr('data-count',i);
			if (i == 2) then
				html_node
				:tag('span'):addClass('label-plus'):wikitext('+'):done()
				:tag('span'):addClass('label-minus'):wikitext('-'):done();
			end
		end
		if (result["costSecondary"] ~= nil and result["speciesSecondary"] ~= nil) then
			html_node
			:tag('span'):addClass('label-secondary label-secondary-'.. tf_species[result["speciesSecondary"]]):wikitext(result["costSecondary"]):done()
			:attr('data-cost-secondary',result["costSecondary"]):attr('data-species-secondary',tf_species[result["speciesSecondary"]]);
		end
		html_rows[current_row]:node(html_node:allDone());
		if (result["connectionRight"] == true) then
			html_rows[current_row]:tag('td')
										:tag('div'):cssText(tf_connection_parent_h)
										:tag('div'):cssText(tf_connection_img_h):addClass('label-connection-h'):wikitext(tf_connection):done():done():done();
		else
			html_rows[current_row]:tag('td'):done();
		end
		if (result["connectionBottom"] == true) then
			html_rows[current_row+1]:tag('td')
										:tag('div'):cssText(tf_connection_parent_v)
										:tag('span'):cssText(tf_connection_img_v):addClass('label-connection-v'):wikitext(tf_connection):done():done():done()
										:tag('td'):done();
				
		else
			if (current_row ~= 8) then
				html_rows[current_row+1]:tag('td')
											:tag('div'):cssText(tf_connection_parent_v)
											:tag('div'):cssText(tf_connection_img_v):addClass('label-connection-v'):done():done():done()
											:tag('td'):done();
			end
		end
	end
	html_table:node(html_rows[0])
	:node(html_rows[1])
	:node(html_rows[2])
	:node(html_rows[3])
	:node(html_rows[4])
	:node(html_rows[5])
	:node(html_rows[6])
	:node(html_rows[7])
	:node(html_rows[8]):allDone();
	local result = tostring(html_table);
	return result;
end

return p