Dead by Daylight Wiki

Current Tome: Tome IX - Crescendo

Featuring Yun-Jin Lee SurvivorYun-Jin.png and The Trickster IconHelpLoading trickster.png

TomeIX Crescendo Banner.jpg

Current Event: The Midnight Grove Halloween Event

READ MORE

Dead by Daylight Wiki
Advertisement

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

local strings = {
	descNotFound = "The description wasn't found or the error with displaying it occured.",
	perkValuesNotFound = "The Values for the perk wasn't found",
	unitNotFound = "The Unit value wasn't found",
	notUniquePerk = "Perk is not unique to any character, thus no name provided",
	several = "several",
	all = "All", --used in Perk Table for common perks of Survivros and Killers
	icon = "Icon",
	name = "Name",
	desc = "Description",
	character = "Character",
	belongs = "Belonging to",
	noChar = "Character not found to show their perks"
}

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 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 = table.getn(perks) - _unusedPerksCount - _commonPerksCount
local _nonUniquePerksCount = _unusedPerksCount + _commonPerksCount

p._nonUniquePerksCount = _nonUniquePerksCount
p._allPerksCount = table.getn(perks)

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, mode)
	tripplet = tonumber(tripplet)
	for _,perk in ipairs(perks) do
		if perk.id == id then
			if (mode and mode == "teachable") then
				return utils.clr(b(strings.several .. space .. getUnitById(perk.units[tripplet])), 13)
			else
				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
				return "'''" .. utils.clr(perk.values[index], 2) .. "'''/'''" .. utils.clr(perk.values[index + 1], 3) .. "'''/'''" .. utils.clr(perk.values[index + 2], 4) .. " " ..
				--I remove the dynamic base level as long as the perks are not diversed anymore and all perks are uncommon/rare/very rare value
				--return "'''" .. utils.clr(perk.values[index], perk.baseLevel) .. "'''/'''" .. utils.clr(perk.values[index + 1], perk.baseLevel + 1) .. "'''/'''" .. utils.clr(perk.values[index + 2], perk.baseLevel + 2) .. " " ..
					getUnitById(perk.units[tripplet]) .. "'''" --Units, Tripplet is an index in 'units' list
			end
		end
	end
	return "'''" .. strings.perkValuesNotFound .. "'''"
end

--Function replaces "#pl(x)" string with tripplet value of according number in brackets
function subValues(perkDesc, mode)
	local regexString = "#pl%((%d)%)" -- looking and extracting number from "#pl(x)"
	if perkDesc.desc[1][1] ~= nil then
		for m in perkDesc.desc[1][1]: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[1][1] = perkDesc.desc[1][1]:gsub(currentRegexString, pl(perkDesc.id, tonumber(m), mode))
			--mw.log(perkDesc.desc[1][1])
		end
	end
	--mw.log("PL: " .. pl)
	return perkDesc
end

function subNames(perkDesc)
	local regexString = "#pn"
	if perkDesc.desc[1][1] ~= nil then
		for m in perkDesc.desc[1][1]: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[1][1] = perkDesc.desc[1][1]:gsub(regexString, "''".. p.GetPerkById(perkDesc.id).name .. "''")
		end
	end
	return perkDesc
end

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

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

function reparseRawDesc(text)
	mw.log(text)
	mw.log("************************")
	
	--IconLink removal
	local regex = '( %&%#91;%&%#91;' .. cstr.file .. '.-%&%#93;%&%#93;)' --"( %[%[" .. cstr.file .. ".-%]%])" --&#91; &#93; --iconLinks/images
	for m in text:gmatch(regex) do
		text = text:gsub(regex, cstr.empty)--cstr.empty)
	end
	
	--[[Link]]
	regex = '%&%#91;%&%#91;(.-)%&%#93;%&%#93;' --simple links
	for m in text:gmatch(regex) do
		local currentRegex = '%&%#91;%&%#91;' .. m .. '%&%#93;%&%#93;'
		text = text:gsub(currentRegex, m)--cstr.empty)
	end
	
	--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)--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.name == name then
			return perk
		end
	end
end

function p.getPerkDescription(perk, mode)
	perk = utils.resolveParameter(perk)
	for _, perkDesc in ipairs(perkDescription) do
		if perkDesc.id == perk.id then
			perkDesc = subValues(perkDesc, mode) --pl(#) => Perk # trio Values
			perkDesc = subNames(perkDesc) -- #pn => Perk Name
			if perk.retired then perkDesc = prependRetire(perkDesc) end
			--if perk.id == 188 then
				perkDesc = prependRawDesc(perkDesc)
			--end

			
			--mw.log(perkDesc.desc[1][1])
			return perkDesc.desc[1][1]
		end
	end
	return ""
end

function p.getPerkTeachableDescription(id)
	id = tonumber(utils.resolveParameter(id))
	
	for _, perkDesc in ipairs(perkDescription) do
		if perkDesc.id == id then
			--mw.log(perkDesc.teachDesc[1])
			return perkDesc.teachDesc[1]
		end
	end
end

function p.getPerkDescriptionByName(name)
	name = utils.resolveParameter(name)

	for _, perk in ipairs(perks) do
		if perk.name == name then
			return p.getPerkDescription(perk)
		end
	end
	return strings.descNotFound .. space .. 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) --Name
	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 utils.split(owner.shortName)[1]
		else
			return utils.split(owner.name)[1]
		end
	else --Killer name
		return owner.name
	end
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
		result = result .. getTableRowPerk(perk)
		if perk.id ~= perkList[#perkList].id then
			result = result .. ntl .. nl
		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)
	
	--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 .. '[[' .. cstr.file .. utils.getIcon(perk.techName or perk.name) .. '| ' .. perk.name .. ' | 100px]]' .. nl ..
		hl .. '[[' .. perk.name .. ']]' .. nl ..
		'| ' .. (p.getPerkDescription(perk) or '') .. nl
end

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

function getTableRowWithPortraitPerk(perk)
	return
		hl .. '[[' .. cstr.file .. utils.getIcon(perk.techName or perk.name) .. '| ' .. perk.name .. ' | 100px]]' .. nl ..
		hl .. '[[' .. perk.name .. ']]' .. nl ..
		'| ' .. (p.getPerkDescription(perk) or '') .. nl ..
		hl .. ((perk.character and ( '[[' .. getPerkOwnerFirstName(perk) .. ']]' .. br .. '[[' .. cstr.file .. p.getPortraitOfPerkOwnerByPerk(perk) .. '|73px]]')) or strings.all) .. nl
end

function getUnusedTableRow(perk)
	return 
		getTableRowPerk(perk) ..
		hl .. ((perk.character and ( '[[' .. getPerkOwnerFirstName(perk) .. ']]' .. br .. '[[' .. cstr.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 = utils.split(cat, ',')
	
	if cat[#cat] == "all" then 
		return getAllCharTypePerks(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 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 utils.clr(header, colors[i])) or header) .. nl
	end
	result = result .. ntl .. nl
	return result
end

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

function p.getPerkIconFilename(args, ext, perk)
	local name = (utils.resolveParameter(args, 1, true)) --should be (args, 1, true)?
	ext = (ext or utils.resolveParameter(args, 2, true))
	perk = (perk or p.getPerkByName(name))

	return (not perk and 'Teachable unknown.png') or utils.resolveFileName((perk.techName or name or perk.name), false, true) .. ((ext and  '.' .. ext) or name)
end

function p.getTeachablePerkIconFilename(args)
	return "Teachable_" ..	utils.FirstLetterLower(p.getPerkIconFilename(args))
end

function p.getTeachablePerkIcon(perk)
	return "Teachable_" ..	utils.FirstLetterLower(p.getPerkIconFilenameByPerk(perk, 'png'))
end

function p.getTeachableDescriptionById(id)
	return p.getPerkDescription(p.getPerkById(id), "teachable")
end

function p.getPerksByCharacter(character)
	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)
	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

--charType - K/S
--[order] - #th character from DLC
function p.getCharPerksByDLC(charType, order)
	local dlcs = require("Module:DLCs")
	local dlcName = dlcs.getShortName(utils.getPageTitle())
	order = order or tonumber(utils.resolveParameter(charType, 2, true)) or 1
	charType = utils.resolveParameter(charType)
	local characters = utils.getCharsByDlc(dlcs.getDlcByName(dlcName), charType)

	if #characters > 0 then
		return p.resolveCharPerks((characters[order] or characters[1]), "png")
	end
	return dlcName .. dot .. space .. strings.noChar
end

function p.getPerkCostISByName(name)
	local sos = require("Module:SoS")
	perk = p.getPerkByName(name)
	if perk ~= nil then
		return sos.GetPerkCostByPerk(perk)
	else
		return 0
	end
end


return p
Advertisement