Dead by Daylight Wiki
Advertisement
Wersja do druku nie jest już wspierana i może powodować błędy w wyświetlaniu. Zaktualizuj swoje zakładki i zamiast funkcji strony do druku użyj domyślnej funkcji drukowania w swojej przeglądarce.

local p = {}
local utils = require("Module:Utils")
local data = require("Module:Datatable" .. utils.lang())
local perksData = require("Module:Datatable/Perks" .. utils.lang()) --mw.loadData
local str = require("Module:Strings")
local frame = mw.getCurrentFrame()


local perks = perksData.perks
local perkDescription = perksData.perkDescription
local perkStrings = perksData.perkStrings
local units = perksData.units
local unitMapper = perksData.unitMapper

local strings = {
	-- #patch# => latest patch
	-- "#lpatch#" => latest patch
	ptbHeader = "Ten opis jest oparty na zmianach przedstawionych w nadchodzącej Aktualizacji: #patch#",
	
	descNotFound = "Nie można pobrać opisu Umiejętności lub nie można go wyświetlić.",
	perkValuesNotFound = "Nie można pobrać poziomów wartości Umiejętności.",
	unitNotFound = "Nie można pobrać jednostki miary dla poziomów wartości Umiejętności.",
	notUniquePerk = "Nie można podać nazwy postaci, ponieważ jest to Umiejętność Generalna, która nie jest przypisana do żadnej konkretnej Postaci.",
	dlcNotFound = i(bclr(6, "Nie można pobrać połączonego DLC, dlatego nie można wyświetlić powiązanych Umiejętności." .. cstr.contact)),
	charNotFound = i(bclr(6, "Nie można odzyskać połączonej Postaci, dlatego nie można wyświetlić powiązanych z nią Umiejętności." .. cstr.contact)),
	perkNotFound = i(bclr(6, "Nie można pobrać Umiejętności, dlatego nie można wyświetlić jego szczegółów." .. cstr.contact)),
	all = 'Wszystkie', --used in Perk Table for common perks of Survivrros and Killers
	icon = "Ikona",
	cost = "Koszt",
	bpLink = "Punkty Krwi",
	shardsLink = "Błyszczące Odłamki",
	name = "Nazwa",
	desc = "Opis",
	character = "Postać",
	killers = "Zabójcy",
	survivors = "Ocalali",
	belongs = "Ta Umiejętność należy do",
	noChar = "Brak dostępnej połączonej Postaci, nie można wyświetlić jej Umiejętności.",
	noLevel = "Brakujący Poziom do odzyskania nazwy Umiejętności.",
	perkByLvlNotFound = "Nie istnieje żaden Umiejętność na tym Poziomie.",
	noPerk = "Nie można znaleść Umiejętności.",
	availableToAll = "dostępna dla wszystkich",
	belongingTo = "należąca do",
	
	perks = "Umiejętność",
	uniquePerks = "Unikalna Umiejętność", --article on Perks Page
	prestige = "Prestiż",
	
	-- [[Perks#Unique Perks|Prestige]] the associated Character to '''Prestige 1, 2, 3''' respectively to unlock '''{{clr|2|Tier I}}, {{clr|3|Tier II}}, {{clr|4|Tier III}}''' of '''{{PAGENAME}}''' for all other Characters.
	prestigeText1 = "żeby zdobyć odpowiednio",
	prestigeText2 = "by odblokować",
	prestigeText3 = "Umiejętności",
	prestigeText4 = "dla wszystkich pozostałych Postaci",
	tier = "Poziom",
}

local perkBPCosts = {
	[2] = 2500, --1st level
	[3] = 3250, --2nd level
	[4] = 4000  --3rd level
}

function getMaxPerkId()
	result = 0
	for _, perk in ipairs(perks) do
		if result < perk.id then result = perk.id end
	end
	return result
end

function p.getNextFreePerkId()
	return getMaxPerkId() + 1
end

function p.isGeneralPerk(perk)
	return perk.character == nil
end

function getUnusedPerksCount()
	local result = 0
	
	for _, perk in ipairs(perks) do
		if perk.unused then result = result + 1 end
	end

	return result
end

function p.getRetiredPerksCount()
	local result = 0
	
	for _, perk in ipairs(perks) do
		if perk.retired then result = result + 1 end
	end

	return result
end

function getCommonPerksCount()
	local result = 0
	
	for _, perk in ipairs(perks) do
		if perk.character == nil and perk.unused ~= true then result = result + 1 end
	end
	
	return result
end

function p.getCountPerksByType(pType)
	pType = utils.resolveParameter(pType)
	local result = 0
	
	for _, perk in ipairs(perks) do
		if perk.charType == pType and perk.unused ~= true then result = result + 1 end
	end
	--mw.log(result)
	return result
end

function p.getCountPerksByCategory(cat, charType)
	local category = utils.resolveParameter(cat)
	local charType = charType or utils.resolveParameter(cat, 2, true)
	
	return #getPerksByCategory(category, charType)
end

local _unusedPerksCount = getUnusedPerksCount()
local _commonPerksCount = getCommonPerksCount()
local _uniquePerksCount = perksData.count - _unusedPerksCount - _commonPerksCount
local _nonUniquePerksCount = _unusedPerksCount + _commonPerksCount

p._nonUniquePerksCount = _nonUniquePerksCount
p._allPerksCount = perksData.count

function p.getPerksCount() --active in game
	return _uniquePerksCount + _commonPerksCount
end

function ResolveIntParam(param) --TODO remove, shouldn't be used anymore
	if type(param) == "table" and param.args[1] ~= nil then
		return tonumber(param.args[1])
	else
		return param
	end
end

function getUnitById(id)
	--mw.log(id)
	for _,unit in ipairs(units) do
		if unit.id == id then return unit.value end
	end
	return unitNotFound
end

--Function that actually returns string that will replace the placeholder
function pl(id, tripplet)
	tripplet = tonumber(tripplet)
	for _,perk in ipairs(perks) do
		if perk.id == id then
			local index = 1 + ((tripplet - 1) * 3) --tripplet is an offset, +1 is indexing from 1 in LUA, * 3 is because every values are grouped by 3 values/tiers
			local unit = getUnitById(perk.units[tripplet]) --If unit is empty, then don't apply bold function
			return bclr(2, perk.values[index]) .. "/" .. bclr(3, perk.values[index + 1]) .. "/" .. bclr(4, perk.values[index + 2]) .. space .. ((unit ~= cstr.empty and b(unit)) or cstr.empty) --Units, Tripplet is an index in 'units' list
		end
	end
	return b(strings.perkValuesNotFound)
end

function wrapPtb(perkDesc, perk)
	if perkDesc.desc ~= nil then
		local processedString = processPtbString(strings.ptbHeader, perk)
		--mw.log(ptb(perkDesc.desc, processedString, perk.patch))
		perkDesc.desc = ptb(perkDesc.desc, processedString, perk.patch)
	end
	return perkDesc
end

function processPtbString(ptbString, perk)
	local patchSub = "#patch#"
	local latestPatchSub = "#lpatch#"
	
	local ptbString = ptbString:gsub(patchSub, (perk and perk.patch) or cstr.empty):gsub(latestPatchSub, data.latestPatch.patch)
	
	return ptbString
end

--Function replaces "#pl(x)" string with tripplet value of according number in brackets
function subValues(perkDesc)
	local regexString = "#pl%((%d)%)" -- looking and extracting number from "#pl(x)"
	if perkDesc.desc ~= nil then
		for m in perkDesc.desc:gmatch(regexString) do --TODO the first index shouldn't be hardcoded due to history log (if the description will be copied, then it won't be the first)
			local currentRegexString = "#pl%(" .. tonumber(m) .. "%)" --you need to replace ONLY CURRENT INDEX, otherwise you'll get replaced all #pl(x) at once when going through the first time (i.e. the first tripplet will replace all #pl() in text
			perkDesc.desc = perkDesc.desc:gsub(currentRegexString, pl(perkDesc.id, tonumber(m)))
			--mw.log(perkDesc.desc)
		end
	end
	--mw.log("PL: " .. pl)
	return perkDesc --result
end

function subNames(perkDesc)
	local regexString = "#pn"
	if perkDesc.desc ~= nil then
		for m in perkDesc.desc:gmatch(regexString) do --TODO the first index shouldn't be hardcoded due to history log (if the description will be copied, then it won't be the first)
			perkDesc.desc = perkDesc.desc:gsub(regexString, "''".. p.getPerkById(perkDesc.id).name .. "''")
		end
	end
	return perkDesc
end

function prependRetire(perkDesc)
	if perkDesc.desc ~= nil then
		perkDesc.desc = perkStrings.retiredPerk .. pg .. perkDesc.desc
	end
	return perkDesc
end

function prependRawDesc(perkDesc)
	if perkDesc.desc ~= nil then
		perkDesc.desc = 
			'<div class = "switchArea"></div>' ..
			'<div class = "rawPerkDesc" style="display:none;">' .. dnl .. reparseRawDesc(mw.text.nowiki(perkDesc.desc)) .. dnl .. '</div>' ..
			'<div class = "formattedPerkDesc">' .. perkDesc.desc .. '</div>'
	end
	return perkDesc
end

function removeIconLinks(text, raw)
	local regex
	if raw then
		regex = '( ?%&%#91;%&%#91;' .. cstr.file .. '.-%&%#93;%&%#93;)' --"( %[%[" .. cstr.file .. ".-%]%])" --&#91; &#93; --iconLinks/images
	else
		regex = '( ?%[%[' .. cstr.file .. '.-%]%])' --"( [[" .. cstr.file .. ".-]])" --iconLinks/images
	end
	for m in text:gmatch(regex) do
		text = text:gsub(regex, cstr.empty)--cstr.empty)
	end
	return text
end

function removeLinks(text, raw)
	local regStart, regEnd
	if raw then
		regStart = '%&%#91;%&%#91;'
		regEnd = '%&%#93;%&%#93;'
	else
		regStart = '%[%['
		regEnd = '%]%]'
	end
	local regex = regStart .. '(.-)' .. regEnd --simple links
	for m in text:gmatch(regex) do
		local currentRegex = regStart .. m .. regEnd
		text = text:gsub(currentRegex, m)--cstr.empty)
	end
	return text
end

function reparseRawDesc(text)
	--IconLink removal
	text = removeIconLinks(text, true)

	--[[Link]]
	text = removeLinks(text, true)
	
	--line carriage conversion to to <br>
	regex = '%&%#10;'
	if text:gmatch(regex) then
		text = text:gsub(regex, br)
	end

	--quotes:
	regex = '\n([^\n]-clr9[^\n]-&#39;)$'
	if text:gmatch(regex) then
		text = text:gsub(regex, cstr.empty)
	end	
	
	regex = '\n'
	if text:gmatch(regex) then
		text = text:gsub(regex, brnl)
	end
	
	--encoded <br>
	regex = '&#60;br&#62;'
	if text:gmatch(regex) then
		text = text:gsub(regex, br)
	end
	
	--last <br> removal
	regex = "<br>$"
	if text:gmatch(regex) then
		text = text:gsub(regex, cstr.empty)
	end
	
	--mw.log(text)
	return text
end

function p.getPerkById(id)
	for _, perk in ipairs(perks) do
		if perk.id == id then
			return perk
		end
	end
end

function p.getPerkByName(name)
	name = utils.resolveParameter(name)
	for _, perk in ipairs(perks) do
		if perk.techName == name or perk.name == name then
			return perk
		end
	end
end

function p.getPerksByNames(...)
	nameList = utils.resolveParameter(..., 0)
	perkList = {}
	for _, name in ipairs(nameList) do
		perkList[#perkList + 1] = p.getPerkByName(name)
	end
	return perkList
end

function p.getPerkDescription(perk)
	perk = utils.resolveParameter(perk)
	if perkDescription[perk.id].id == perk.id then
		local perkDesc = perkDescription[perk.id]
		return processPerkDescription(perkDesc, perk) 
	end
	for i, perkDesc in ipairs(perkDescription) do
		if perkDesc.id == perk.id then
			return processPerkDescription(perkDesc, perk)
		end
	end
	return strings.descNotFound .. ((perk and perk.name and colon .. space .. perk.name) or cstr.empty)
end

function processPerkDescription(perkDesc, perk)
	local PD = {desc = perkDesc.desc[1][1], id = perkDesc.id}
	PD = subValues(PD) --pl(#) => Perk # trio Values
	PD = subNames(PD) -- #pn => Perk Name
	if perk.retired then PD = prependRetire(PD) end
	PD = wrapPtb(PD, perk)
	PD = prependRawDesc(PD)
	
	--mw.log(PD.desc)
	return PD.desc
end

function p.getPerkDescriptionById(id)
	id = tonumber(utils.resolveParameter(id))
	return p.getPerkDescription(p.getPerkById(id))
end

function p.getPerkDescriptionByName(name)
	name = utils.resolveParameter(name)
	return p.getPerkDescription(p.getPerkByName(name))
end


function p.getPerkOwnerByPerk(perk)
	if perk.character == nil then return notUniquePerk end
	if perk.charType == 'S' then
		return utils.getCharacterById(perk.character, survivors)
	elseif perk.charType == 'K' then
		return utils.getCharacterById(perk.character, killers)
	--else
	--	return "Unknown Character"
	end
end

function p.getPerksOwnerNameByPerk(perk)
	return p.getPerkOwnerByPerk(perk).name
end



function p.getPortraitOfPerkOwnerByPerk(perk)
	return perk.charType .. string.format("%02d", p.getPerkOwnerByPerk(perk).id) .. '_charSelect_portrait.png'
end

function getPerkOwnerFirstName(perk)
	
	local owner = p.getPerkOwnerByPerk(perk)
	if perk.charType == 'S' then
		if owner.shortName ~= nil then
			return string.split(owner.shortName)[1]
		else
			return string.split(owner.name)[1]
		end
	else --Killer name
		return owner.name
	end
end

function p.resolvePerkChar_PerkPage(perkName)
	perkName = utils.resolveParameter(perkName)
	local perk = p.getPerkByName(perkName)
	
	if not perk then return strings.perkNotFound .. space .. brackets(strings.name .. colon .. space .. quotes(perkName or cstr.empty)) end
	
	if not perk.character then
		return strings.availableToAll .. space .. utils.IconLink(((perk.charType == 'S' and strings.survivors) or strings.killers))
	end
	
	local owner = p.getPerkOwnerByPerk(perk)
	local isKiller = utils.isKiller(owner)
	return strings.belongingTo .. space .. 
	utils.IconLink(
		(owner.multiName and owner.realName) or (not isKiller and owner.shortName) or owner.name, 
		((isKiller and the(owner)) or cstr.empty) .. ((not isKiller and owner.shortName) or owner.name)
	)
end

function p.resolvePerkPrestige_PerkPage(perkName)
	perkName = utils.resolveParameter(perkName)
	local perk = p.getPerkByName(perkName)
	
	if not perk then return strings.perkNotFound .. space .. brackets(strings.name .. colon .. space .. quotes(perkName or cstr.empty)) end
	
	if not perk.character then
		return cstr.empty
	end
	
	local owner = p.getPerkOwnerByPerk(perk)
	local isKiller = utils.isKiller(owner)
	
	return link(strings.perks .. '#' .. strings.uniquePerks, strings.prestige) .. space .. ((isKiller and the(owner)) or cstr.empty) .. ((not isKiller and owner.shortName) or owner.name) .. space .. strings.prestigeText1 .. space .. b(strings.prestige .. " 1, 2, 3") .. space .. 
		strings.prestigeText2 .. space .. b(clr(2, strings.tier .. space .. 'I') .. comma .. clr(3, strings.tier .. space .. 'II') .. comma .. clr(4, strings.tier .. space .. 'III')) .. space .. 
		strings.prestigeText3 .. space .. b(perk.name) .. space .. strings.prestigeText4 .. dot
	-- [[Perks#Unique Perks|Prestige]] the associated Character to '''Prestige 1, 2, 3''' respectively to unlock '''{{clr|2|Tier I}}, {{clr|3|Tier II}}, {{clr|4|Tier III}}''' of '''{{PAGENAME}}''' for all other Characters.
end

--cat = category
--solution = defines which way the category should be processed
--charType = 'K' - Only Killers, 'S' - Only survivors, skipped - Both
function p.resolvePerkCategory(cat, solution, charType)
	category = utils.resolveParameter(cat)
	solution = solution or utils.resolveParameter(cat, 2)
	charType = charType or utils.resolveParameter(cat, 3, true)

	utils.sortItemsByName(perks)
	if		solution == "table"			then return getPerksTableByCategory(category, charType)
	elseif	solution == "charTable"		then return getPerksTableWithPortrait(category, charType)
	elseif	solution == "unusedTable"	then return getPerksTableUnused(category, charType)
	--elseif	solution == "secondApproach"	then return functionReturningCategorisedPerks(cat, charType)
	else return solution
	end
end

--*********** Perk Solution Functions ***********
function getPerksTableByCategory(cat, charType)
	local result = cstr.empty
	local perkList = getPerksByCategory(cat, charType)

	for _, perk in ipairs(perkList) do
		if not perk.retired then
			result = result .. getTableRowPerk(perk)
			if perk.id ~= perkList[#perkList].id then
				result = result .. ntl .. nl
			end
		end
	end
	
	result = utils.wrapBasicTable(result)
	
	--mw.log(result)
	return result
end

function getPerksTableWithPortrait(cat, charType)
	local result = cstr.empty
	local perkList = getPerksByCategory(cat, charType)
	
	for _, perk in ipairs(perkList) do
		result = result .. getTableRowWithPortraitPerk(perk)
		if perk.id ~= perkList[#perkList].id then
			result = result .. ntl .. nl
		end
	end
	
	result = getPerkTableHeader({strings.icon, strings.name, strings.desc, strings.character}, nil, {false, true, false, true}) .. result
	result = utils.wrapBasicTable(result, "sortable")
	
	--mw.log(result)
	return result
end

function getPerksTableUnused(cat, charType)
	local result = cstr.empty
	local perkList = getUnusedPerks(charType)
	
	for _, perk in ipairs(perkList) do
		result = result .. getUnusedTableRow(perk)
		if perk.id ~= perkList[#perkList].id then
			result = result .. ntl .. nl
		end
	end
	
	result = getPerkTableHeader({strings.icon, strings.name, strings.desc, strings.belongs}, nil, {false, true, false, true}) .. result
	result = utils.wrapBasicTable(result)
	
	--mw.log(result)
	return result
end
--*********** END Perk Solution Functions ***********
--*********** Perk Row Functions ***********
function getTableRowPerk(perk)
	return
		hl .. file(utils.getIcon(perk.name), perk.name, '100px') .. nl ..
		hl .. link(perk.name) .. nl ..
		tl .. (p.getPerkDescription(perk) or cstr.empty) .. nl
end

function getCharTableRowPerk(perk, ext) --using gif version of perk (character page)
	return
		hl .. file(((ext == cstr.png and utils.getIcon(perk.name)) or p.getPerkIconFilenameByPerk(perk, ext or 'gif')), perk.name, '128px') .. nl ..
		hl .. link(perk.name) .. nl ..
		tl .. (p.getPerkDescription(perk) or cstr.empy) .. nl
end

function getTableRowWithPortraitPerk(perk)
	return
		hl .. file(utils.getIcon(perk.name), perk.name, '100px') .. nl ..
		hl .. link(perk.name) .. nl ..
		tl .. (p.getPerkDescription(perk) or cstr.empty) .. nl ..
		hl .. ((perk.character and ( link(p.getPerkOwnerByPerk(perk).name .. tl .. getPerkOwnerFirstName(perk)) .. br .. file(p.getPortraitOfPerkOwnerByPerk(perk), '73px'))) or span(dot, 'display-none') .. strings.all) .. nl
end

function getUnusedTableRow(perk)
	return 
		getTableRowPerk(perk) ..
		hl .. ((perk.character and (link(getPerkOwnerFirstName(perk)) .. br .. file(p.getPortraitOfPerkOwnerByPerk(perk), '73px'))) or
			(perk.charType and ((perk.charType == 'S' and utils.IconLink('Survivors')) or (perk.charType == 'K' and utils.IconLink('Killers')))) or cstr.empty) .. nl
end
--*********** END Perk Row Functions ***********
--*********** Get PerkList Functions ***********
function getPerksByCategory(cat, charType)
	local result = {}
	cat = string.split(cat, ',')
	
	if cat[#cat] == "all" then 
		return getAllCharTypePerks(charType)
	elseif cat[#cat] == "GeneralPerk" then
		return getGeneralPerksByCharType(charType)
	end
	for _, perk in ipairs(perks) do
		if perk.tags ~= nil then
			local found = false
			for _,searchedCat in ipairs(cat) do
				for _, category in ipairs(perk.tags) do
					if category == searchedCat and (charType == nil or perk.charType == charType) then
						result[#result + 1] = perk
						found = true
						break
					end
				end
				if found then break end
			end
		end
	end
	
	return result
end

function getAllCharTypePerks(charType)
	local result = {}
	for _, perk in ipairs(perks) do
		if (charType == nil or perk.charType == charType) and not perk.unused then
			result[#result + 1] = perk
		end
	end
	return result
end

function getGeneralPerksByCharType(charType)
	local result = {}
	for _, perk in ipairs(perks) do
		if not perk.character and (perk.charType == charType) and not perk.unused then
			result[#result + 1] = perk
		end
	end
	return result
end

function getUnusedPerks(charType)
	result = {}
	for _, perk in ipairs(perks) do
		if (charType == nil or perk.charType == charType) and perk.unused then
			result[#result + 1] = perk
		end
	end
	return result
end
--*********** END Get PerkList Functions ***********

function p.getPerkDescriptions(params, last) --temporary function, not used anywhere permanently
	first = tonumber(utils.resolveParameter(params))
	last = tonumber(last or utils.resolveParameter(params, 2))
	local result = ''
	
	utils.sortTableById(perks)
	for _, perk in ipairs(perks) do
		if perk.id >= first and perk.id <= last then
			result = result .. hl .. perk.id .. nl .. 
			hl .. (perk.techName or perk.name) .. nl ..
			'| ' .. p.getPerkDescription(perk) .. nl
			if perk.id ~= last then
				result = result .. ntl .. nl
			end
		end
	end
	
	result = utils.wrapBasicTable(result)
	--mw.log(result)
	return result
end
--************************************
function getPerkTableHeader(colList, colors, sortings)
	result = ''
	
	for i, header in ipairs(colList) do
		result = result .. hl .. ((sortings and not sortings[i] and ' class = "unsortable" ' .. ' | ') or '') .. ((colors and clr(colors[i], header)) or header) .. nl
	end
	result = result .. ntl .. nl
	return result
end

function p.getPerkIconFilenameByPerk(perk, ext, forceName, teachable)
	return p.getPerkIconFilename(nil, ext, perk, forceName, teachable)
end

--forceName => in order to avoid calling expensive file existence check we can force the name regardless it's uploaded on server or not
function p.getPerkIconFilename(args, ext, perk, forceName, teachable)
	local name = (utils.resolveParameter(args, 1)) --should be (args, 1, true)?
	ext = (ext or utils.resolveParameter(args, 2, true))
	perk = (perk or p.getPerkByName(name))
	
	local owner = p.getPerkOwnerByPerk(perk)
	local isOwnerLive = (owner and utils.isCharacterLive(owner))
	if perk then
		local perkFilename = utils.resolveFileName(((teachable and "Teachable_") or cstr.empty) .. (perk.techName or perk.name), false, true)
		if not isOwnerLive then
			if utils.isValidFileName(perkFilename, ext) then
				return perkFilename .. ((ext and  dot .. ext) or name)
			else
				return 'Teachable unknown.png'
			end
		elseif forceName or utils.isValidFileName(perkFilename, ext) then
			return perkFilename .. ((ext and  dot .. ext) or name)
		end
	end
	if forceName then
		return name .. dot .. ext
	end
	
	return 'Teachable unknown.png'
end

--Currently probably used only at SoS
function p.getTeachablePerkIconFilename(args)
	return p.getPerkIconFilename(args, cstr.png, nil, false, true)
end

function p.getTeachablePerkIcon(perk, forceName)
	return p.getPerkIconFilenameByPerk(perk, cstr.png, forceName, true)
end

function p.getPerksByCharacter(character)
	local result = {}
	charType = (character.power == nil and 'S') or 'K' --to determine whether the character is killer or survivor, since the power is unique attribute for killers and should be mandatory
	
	for _, perk in ipairs(perks) do
		if character.id == perk.character and charType == perk.charType then
			result[#result + 1] = perk
		end
	end
	return result
end

function p.resolveCharPerks(character, ext) --character can be character object as well (or string, or .args[1] = char name)
	ext = ext or utils.resolveParameter(character, 2, true)
	character = utils.resolveParameter(character)
	character = (character.name and character) or utils.getCharacterByName(character)
	if not character then return strings.charNotFound end
	local perkList = p.getPerksByCharacter(character)
	local result = cstr.empty
	
	utils.sortPerksByLevel(perkList)
	for _, perk in ipairs(perkList) do
		result = result .. getCharTableRowPerk(perk, ext)
		if perk.id ~= perkList[#perkList].id then
			result = result .. ntl .. nl
		end
	end
	
	result = utils.wrapBasicTable(result)
	
	--mw.log(result)
	return result
end

--used directly on wiki
function p.getPerkNameByLevel(level, character)
	character = character or utils.resolveParameter(level, 2)
	level = tonumber(utils.resolveParameter(level))
	local perk = p.getPerkByCharAndLevel(character, level)
	
	return (type(perk) == types.table and perk.name) or strings.noChar
end

function p.getPerkByCharAndLevel(character, level)
	level = level or utils.resolveParameter(character, 2)
	character = utils.getCharacterByName(utils.resolveParameter(character))
	if not character then return nil end
	local charPerks = p.getCharPerks(character)
	
	for _, perk in ipairs(charPerks) do
		if perk.level == level then
			return perk
		end
	end
	
	return strings.noPerk
end

function p.getCharPerks(character)
	if not character then return nil end
	local charType = utils.isCharacterKiller(character) and 'K' or 'S'
	charPerks = {}
	
	for _, perk in ipairs(perks) do
		if perk.character == character.id and perk.charType == charType then
			table.insert(charPerks, perk)
		end
	end
	
	return #charPerks > 0 and charPerks or nil
end

--currently not used
function p.getPerkNameByDlcAndLevel(charType, level, order, dlcName)
	return p.getPerkByDlcAndLevel(charType, order, level, dlcName).name
end

--currently used only in p.getPerkNameByDlcAndLevel
function p.getPerkByDlcAndLevel(charType, order, level, dlcName)
	order = order or tonumber(utils.resolveParameter(charType, 2, true)) or 1 
	level = level or tonumber(utils.resolveParameter(charType, 3, true))
	dlcName = dlcName or utils.resolveParameter(charType, 4, true) or dlcs.getShortName(utils.getPageTitle())
	if not level then return strings.noLevel end
	charType = utils.resolveParameter(charType)
	
	chars = p.getCharsWithPerksFromDLC(charType, order, dlcName)
	if #chars > 0 then
		for _, perk in ipairs(chars[order].perks) do
			if perk.level == level then return perk end
		end
		return strings.perkByLvlNotFound
	end
	return dlcName .. dot .. space .. strings.noChar
end

--returns characters from DLC with added "perks" table inside
function p.getCharsWithPerksFromDLC(charType, order, dlcName)
	local dlcs = require("Module:DLCs")
	dlcName = (dlcName and dlcs.getShortName(dlcName)) or dlcs.getShortName(utils.getPageTitle())
	order = order or tonumber(utils.resolveParameter(charType, 2, true)) or 1
	charType = utils.resolveParameter(charType)
	
	local dlc = dlcs.getDlcByName(dlcName)
	if not dlc then return strings.dlcNotFound end
	local characters = utils.getCharsByDlc(dlc)

	if #characters > 0 then
		for i, ch in ipairs(characters) do
			ch.perks = p.getPerksByCharacter(characters[i])
		end
		return characters
	end
	return nil
end

--charType - K/S
--[order] - #th character from DLC
function p.getCharPerksByDLC(charType, order, dlcName)
	local dlcs = require("Module:DLCs")
	local dlcName = (dlcName and dlcs.getShortName(dlcName)) or dlcs.getShortName(utils.getPageTitle())
	order = order or tonumber(utils.resolveParameter(charType, 2, true)) or 1
	charType = utils.resolveParameter(charType)
	local dlc = dlcs.getDlcByName(dlcName)
	if not dlc then return strings.dlcNotFound end
	local characters = utils.getCharsByDlc(dlc, charType)
	
	if #characters > 0 then
		return p.resolveCharPerks((characters[order] or characters[1]), "png")
	end
	return dlcName .. dot .. space .. strings.noChar
end

function p.getPerksTableByNames(...)
	if type(...) ~= "table" then
		args = {...} 
	else
		args = ...
	end

	local perkList = p.getPerksByNames(args)
	result = cstr.empty
	
	for _, perk in ipairs(perkList) do
		result = result .. getTableRowPerk(perk)
		
		if perkList[#perkList].id ~= perk.id then
			result = result .. nl .. ntl .. nl
		end
	end
	result = utils.wrapBasicTable(result)

	return result
end

function p.getPerkPageTable(perkName)
	perkName = utils.resolveParameter(perkName)
	local perk = p.getPerkByName(perkName)
	if perk == nil then return strings.perkNotFound end
	local bpClasses1 = 'BG-All PerkCostsBG'
	local bpClasses2 = 'borderless'
	local bpClasses3 = 'SquareBG-#-enh'
	local perkIconFilename = p.getPerkIconFilenameByPerk(perk, cstr.gif)
	--if file exist then no link, otherwise make link for link to upload
	local perkIcon = utils.assembleImage("perk", perk.name)
	local bpIcon = file('IconHelp bloodpoints' .. dot .. cstr.png, '56px', 'link=' .. strings.bpLink)
	local perkDesc = p.getPerkDescription(perk)
	local firstLevel = 2 --based on indexes in perkBPCosts list
	local lastLevel = 4

	-------------------------------- PC --------------------------------
	local pcView = 
		hl .. strings.icon .. nl ..
		hl .. 'colspan = ' .. 3 .. tl .. strings.cost .. nl .. ntl .. nl ..
		tl .. perkIcon .. nl
	for i = firstLevel, lastLevel, 1 do
		pcView = pcView ..
			tl .. class(bpClasses1, bpClasses2, string.gsub(bpClasses3, "#", i)) .. tl .. utils.formatNum(perkBPCosts[i], 0) .. br .. bpIcon .. nl
	end
	pcView = pcView ..
		ntl .. nl ..
		hl .. 'colspan = ' .. 5 .. tl .. strings.desc .. nl .. ntl .. nl ..
		tl .. 'colspan = ' .. 5 .. tl .. perkDesc .. nl
		
	pcView = utils.wrapBasicTable(pcView, 'pcView', 'display: none;')
	
	-------------------------------- Mobile --------------------------------
	local mobileView =
		hl .. 'width = "128px"' .. tl .. strings.icon .. nl ..
		hl .. 'colspan = 1' .. tl .. strings.cost .. nl .. ntl .. nl ..
		tl .. 'rowspan = 3' .. tl .. center(perkIcon) .. nl
	for i = firstLevel, lastLevel, 1 do
		mobileView = mobileView ..
			tl .. center(bclr(i, utils.formatNum(perkBPCosts[i], 0)) .. utils.IconLink(ils.bloodpoints, 'img')) .. nl .. ntl .. nl
	end
	mobileView = mobileView ..
		hl .. 'colspan = 2' .. tl .. strings.desc .. nl .. ntl .. nl ..
		tl .. 'colspan = 2' .. tl .. perkDesc .. nl
		
	mobileView = utils.wrapBasicTable(mobileView, 'mobileView')

	result = pcView .. dnl .. mobileView
	
	--mw.log(result)
	return result
end

return p
Advertisement