local p = {}
local utils = require("Module:Utils")
local data = require("Module:Datatable" .. utils.lang())
local perksData = mw.loadData("Module:Datatable/Perks" .. utils.lang())
local mathOps = require("Module:MathOps")
local perkImg = require("Module:PerkImage")
local str = require("Module:Strings")
local frame = mw.getCurrentFrame()
local _defaultSpeed = 4 --m/s | 100%
local perks = perksData.perks
p.strings = {
killers = "Zabójcy",
the = "",
unkwnKiller = "Nieznany Zabójca",
realName = "Nazwa",
noName = "Brak", --When the killer doesn't have the real name (ex. Demogorgon)
altName = "Alias",
gender = "Płeć",
origin = "Pochodzenie",
realm = "Lokacja", --link
power = "Moc", --link
powers = "Moce", --link
powerType = "Typ Mocy [[Atak|Ataku]]",
spAttackTrue = "Specjalny Atak",
spAttackFalse = "Podstawowy Atak",
weapon = "Broń",
weapons = "Bronie",
speed = "Prędkość Ruchu", --iconlink
altSpeed = "Alternatywna Prędkość ruchu",
metres = "metrów",
m = "m", --abbreviation of metres
terror = "Zasięg Terroru", --iconlink
altTerror = "Alternatywny Zasięg Terroru",
lullabyRadius = "Zasięg [[Kołysanka|Kołysanki]]",
height = "Wzrost", --image
tall = "Wysoki",
avg = "Średni",
short = "Niski",
dlc = "DLC",
actor = "Aktor Głosowy",
breathing = "Oddech",
altBreathing = "Alternatywny Oddech",
menuMusic = "Muzyka Menu",
terrorMusic = "Muzyka Zasięgu Terroru",
lullaby = "Kołysanka",
lullabies = "Kołysanki",
uknownActor = "Nieujawniony Aktor Głosowy",
unkownPower = "Nieznana Moc",
unkownSpeed = "Nieznana Szybkość",
cost = "Koszt",
freeCost = "Darmowe", --this string needs to be same as the string at DLCs that are free
metadata = "Metadata",
charid = "CharID",
mps = "m/s",
err = "Error"
}
local strings = p.strings
if utils.lang() ~= cstr.empty and (counter or 0) < 1 then
counter = (counter or 0) + 1
strings = require("Module:Killers" .. utils.lang()).strings
end
function p.getCountOfKillers()
return utils.getCount("killer")
end
function p.getKillerById(id)
for _, killer in ipairs(killers) do
if killer.id == id then return killer end
end
return nil
end
function getKillerByName(name)
for _, killer in ipairs(killers) do
if killer.shortName == name or killer.realName == name or killer.name == name or (the(killer) .. killer.name) == name then
return killer
end
end
return false
end
function getKillerIdByName(name)
local result = getKillerByName(name)
return (result and result.id) or 0
end
--Function not used on English wiki (Currently: IT)
function p.getKillerRealName(killer) --expected nickname
killer = utils.resolveParameter(killer)
if type(killer) == types.string then
killer = getKillerByName(killer)
end
return killer.realName
end
function p.getKillersPowerByName(name)
local result = getKillerByName(utils.resolveParameter(name))
return (result and result.power) or strings.unkownPower
end
function p.getKillersSpeedByName(name)
local result = getKillerByName(utils.resolveParameter(name))
if result then
if type(result.speed) == types.table then
return result.speed[0]
else
return result.speed
end
end
return strings.unkownSpeed
end
--articleless => whether the nickname is supposed to return with "The " before the name itself
function p.getKillerNicknameByRealName(args, articleless)
articleless = utils.bool(utils.resolveParameter(args, "articleless", true))
name = utils.resolveParameter(args)
for _, killer in ipairs(killers) do
if killer.shortName == name or killer.realName == name or killer.name == name or (the(killer) .. killer.name) == name then
return ((not articleless and the(killer) .. space) or cstr.empty) .. killer.name
end
end
return strings.unkwnKiller
end
function p.resolveKillerCharTable(name)
local dlcs = require("Module:DLCs")
local various = require("Module:Various")
name = utils.resolveParameter(name)
local killerId = getKillerIdByName(name)
local killer = utils.getCharacterById(killerId, killers)
local result = cstr.empty
if type(killer) ~= "table" then return killer end
killer.dlc = dlcs.getDlcById(killer.dlc)
result =
'{| class = "infoboxtable charInfoboxTable killerInfobox"' .. nl ..
ntl ..' class = "infoboxTitle" | ' .. nl ..
'! class = "center bold" colspan = 2 | ' .. the(killer) .. ' ' .. killer.name .. nl .. ntl .. nl ..
-- '<tabber>' ..
-- '|-|First=' ..
-- 'First tab sample text.' ..
-- '|-|Second=' ..
-- 'Second tab content goes here. ' ..
-- '|-|Third Tab Title=' ..
-- 'Third tab content goes here.' ..
-- '</tabber>' ..
'! class = "center charInfoboxImage" colspan = 2 | ' .. file(resolveKillerPortraitImageFileName(killer) .. '.png', '270px') .. nl ..
ntl .. nl
if killer.realName ~= nil then
result = result .. tl .. class('titleColumn') .. tl .. strings.realName .. dtl .. class('valueColumn') .. tl .. (killer.shortName or killer.realName or strings.noName) .. nl .. ntl .. nl
end
if killer.altName ~= nil then
result = result .. tl ..class('titleColumn') .. tl .. strings.altName .. dtl .. class('valueColumn', 'italic') .. tl .. resolveAltName(killer) .. nl .. ntl .. nl
end
result = result ..
tl .. class('titleColumn') .. tl .. strings.gender ..
dtl .. class('valueColumn') .. tl .. utils.resolveGender(killer.gender) .. nl .. ntl .. nl ..
tl .. class('titleColumn') .. tl .. strings.origin ..
dtl .. class('valueColumn') .. tl .. killer.origin .. nl .. ntl .. nl
if killer.realm ~= nil or killer.dlc ~= nil then
local killerRealm = resolveKillerRealm(killer)
if killerRealm ~= 0 then
result = result .. tl .. class('titleColumn') .. tl .. link(strings.realm) .. dtl .. class('valueColumn') .. tl .. link(killerRealm) .. nl .. ntl .. nl
end
end
result = result ..
tl .. class('titleColumn') .. tl .. link(strings.power) .. dtl .. class('valueColumn') .. tl .. link(strings.powers .. '#' .. the(killer) .. killer.name .. tl .. killer.power) .. nl .. ntl .. nl
if killer.specialAttack ~= nil then
result = result .. tl .. class('titleColumn') .. tl .. strings.powerType .. dtl .. class('valueColumn') .. tl .. resolvePowerAttack(killer) .. nl .. ntl .. nl
end
result = result ..
tl .. class('titleColumn') .. tl .. link(strings.weapon) .. dtl .. class('valueColumn') .. tl .. link(strings.weapons .. '#' .. the(killer) .. killer.name .. tl .. killer.weapon) .. nl .. ntl .. nl ..
tl .. class('titleColumn') .. tl .. utils.IconLink(strings.speed) .. dtl .. class('valueColumn') .. tl .. resolveKillerSpeed(killer) .. nl .. ntl .. nl
if killer.altSpeed ~= nil then
result = result .. tl .. class('titleColumn') .. tl .. strings.altSpeed .. dtl .. class('valueColumn') .. tl .. resolveAltSpeed(killer) .. nl .. ntl .. nl
end
result = result ..
tl .. class('titleColumn') .. tl .. utils.IconLink(strings.terror) .. dtl .. class('valueColumn') .. tl .. resolveTerrorRadius(killer) .. nl .. ntl .. nl
local altTerror = resolveAltTerrorRadius(killer)
if altTerror then
result = result .. tl .. class('titleColumn') .. tl .. strings.altTerror .. dtl .. class('valueColumn') .. tl .. altTerror .. nl .. ntl .. nl
end
local lullabyRadius = resolveLullabyRadius(killer)
if lullabyRadius then
result = result .. tl .. class('titleColumn') .. tl .. strings.lullabyRadius .. dtl .. class('valueColumn') .. tl .. lullabyRadius .. nl .. ntl .. nl
end
result = result ..
tl .. class('titleColumn') .. tl .. strings.height .. space .. utils.IconLink(strings.height, "img") .. dtl .. class('valueColumn') .. tl .. resolveHeight(killer) .. nl .. ntl .. nl
if killer.dlc ~= nil then
result = result .. tl .. class('titleColumn') .. tl .. strings.dlc .. dtl .. class('valueColumn') .. tl .. link(dlcs.getDlcFullNameByCharacter(killer)) .. space .. nl .. ntl .. nl
end
result = result ..
tl .. class('titleColumn') .. tl .. strings.actor .. dtl .. class('valueColumn') .. tl .. resolveActor(killer) .. nl
if killer.dlc and not killer.dlc.retracted and (killer.dlc.cost == nil or type(killer.dlc.cost) == types.table or (type(killer.dlc.cost) == types.string and killer.dlc.cost ~= strings.freeCost)) then
local ac = utils.getCcyById(5) --we retrieve the ac and is currency (mainly due to other non-en wikis)
local is = utils.getCcyById(3)
result = result .. ntl .. nl ..
tl .. class('titleColumn') .. tl .. strings.cost .. dtl .. class('valueColumn') .. tl ..
((not killer.dlc.licensed and utils.commaFormat(data.charISCost) .. space .. utils.IconLink(is.plural or is.name .. "s") .. nl) or cstr.empty) ..
utils.commaFormat(data.charACCost) .. space .. utils.IconLink(ac.plural or ac.name .. "s") .. nl
end
local breathingMusic = resolveBreathingMusic(killer)
if breathingMusic then
result = result .. ntl .. nl ..
'| class = "titleColumn center" colspan = 2 ' .. tl .. space .. strings.breathing .. nl .. ntl .. nl ..
'| class = "valueColumn center soundColumn" colspan = 2 ' .. tl .. space .. breathingMusic .. nl
end
local altBreathing = resolveAltBreathing(killer)
if altBreathing then
result = result .. ntl .. nl ..
tl .. ' class = "titleColumn center" colspan = 2 ' .. tl .. space .. strings.altBreathing .. nl .. ntl .. nl ..
tl .. ' class = "valueColumn center soundColumn" colspan = 2 ' .. tl .. space .. altBreathing .. nl
end
local theme, themeSuccess = various.resolveCharacterThemeMusic(killer, true)
if themeSuccess then
result = result .. ntl .. nl ..
'| class = "titleColumn center" colspan = 2 ' .. tl .. space .. strings.menuMusic .. nl .. ntl .. nl ..
'| class = "valueColumn center soundColumn" colspan = 2 ' .. tl .. space .. theme .. nl
end
local terrorMusic = resolveTRMusic(killer)
if terrorMusic then
result = result .. ntl .. nl ..
'| class = "titleColumn center" colspan = 2 ' .. tl .. space .. strings.terrorMusic .. nl .. ntl .. nl ..
'| class = "valueColumn center soundColumn" colspan = 2 ' .. tl .. space .. terrorMusic .. nl
end
local lullaby = resolveLullaby(killer, 1)
local counter = ((lullaby and 1) or 0) --if you find a lullaby then set the counter to 1, otherwise 0
local tempResult = cstr.empty
while lullaby do
tempResult = tempResult .. ntl .. nl ..
'| class = "valueColumn center soundColumn" colspan = 2 ' .. tl .. space .. lullaby .. nl
counter = counter + 1
lullaby = resolveLullaby(killer, counter)
end
if counter > 0 then --if lullaby was found
result = result .. ntl .. nl .. '| class = "titleColumn center" colspan = 2 | ' .. ((counter > 2 and strings.lullabies) or strings.lullaby) .. nl .. tempResult
end
--Metadata
local metadataNewLine = ntl .. class("metadata") .. nl .. tl .. class("titleColumn") .. tl
result = result ..
ntl .. nl ..
tl .. colspan(2) .. space .. class("metadata") .. tl .. center(b(strings.metadata)) .. nl ..
metadataNewLine .. strings.charid .. dtl .. utils.getCharacterIdentifier(killer) .. nl ..
(killer.theme ~= false and (not themeSuccess and various.shouldHaveTheme(killer) and metadataNewLine .. strings.themeFilename .. dtl .. theme .. nl) or cstr.empty)
result = result ..
'|}'
--mw.log(result)
return result
end
function resolveAltTerrorRadius(killer)
if not killer.altRadius then return false end
local result = killer.altRadius
if type(killer.altRadius) == "table" then
result = cstr.empty
for i, radius in ipairs(killer.altRadius) do
result = result .. radius[1] .. space .. brackets(radius[2]) .. ((i < #killer.altRadius and dnl) or cstr.empty)
end
end
return result
end
function resolveActor(killer)
local result = strings.uknownActor
if type(killer.actor) == "string" then
result = killer.actor
elseif type(killer.actor) == "table" then
result = cstr.empty
for i, actor in ipairs(killer.actor) do
result = result .. actor .. ((i < #killer.actor and dnl) or cstr.empty)
end
end
return result
end
function resolveLullabyRadius(killer)
if not killer.lullabyRadius then return false end
local result = cstr.empty
if type(killer.lullabyRadius) == "table" then
for i, lullaby in ipairs(killer.lullabyRadius) do
result = result .. lullaby[1] .. space .. strings.metres .. space .. brackets(lullaby[2])
if i < #killer.lullabyRadius then
result = result .. dnl
end
end
else
result = (killer.lullabyRadius and killer.lullabyRadius .. space ..strings.metres) or cstr.empty
end
return result
end
function resolveBreathingMusic(killer)
local file = (killer.techName or killer.name) .. space .. 'Breathing'
local valid = utils.isValidFileName(file, cstr.ogg)
return (valid and link(cstr.file .. file .. dot .. cstr.ogg)) or valid
end
function resolveAltBreathing(killer, index)
local file = (killer.techName or killer.name) .. space .. 'Breathing' .. space .. (index or 2)
valid = utils.isValidFileName(file, cstr.ogg)
return (valid and link(cstr.file .. file .. dot .. cstr.ogg)) or valid
end
function resolveTRMusic(killer)
local file = 'TerrorRadius_' .. (killer.techName or killer.name)
local valid = utils.isValidFileName(file, cstr.ogg)
return (valid and link(cstr.file .. file .. dot .. cstr.ogg)) or valid
end
function resolveLullaby(killer, index)
local file = (killer.techName or killer.name) .. space .. 'Lullaby' .. ((index and space .. index) or cstr.empty)
local valid = utils.isValidFileName(file, cstr.ogg)
return (valid and link(cstr.file .. file .. dot .. cstr.ogg)) or valid
end
--addon is for cosmetics portraits (used in Module:Cosmetics)
function resolveKillerPortraitImageFileName(killer, addon)
local fileConst = "_charSelect_portrait"
return "K" .. string.format("%02d", killer.id) .. ((addon and space .. addon) or cstr.empty) .. fileConst
end
function resolveAltName(killer)
if type(killer.altName) == "string" then return '"' .. killer.altName .. '"'
elseif type(killer.altName) == "table" then
local result = ""
for i, name in ipairs(killer.altName) do
result = result .. '"' .. name .. '"'
if i < #killer.altName then
result = result .. dnl
end
end
return result
end
return strings.err
end
function resolvePowerAttack(killer)
local result = cstr.empty
if killer.specialAttack then
result = strings.spAttackTrue
else
result = strings.spAttackFalse
end
if killer.altAttackNote ~= nil then
result = result .. nl .. "(" .. killer.altAttackNote .. ")"
end
return result
end
function resolveKillerRealm(killer)
if killer.dlc == nil then
for _, realm in ipairs(realms) do
if realm.id == killer.realm then return realm.name end
end
else
for _, realm in ipairs(realms) do
if type(realm.dlc) == types.number and realm.dlc == resolveDlcProperty(killer) then return realm.name
elseif type(realm.dlc) == types.table then
for _, dlcId in ipairs(realm.dlc) do
if dlcId == resolveDlcProperty(killer) then return realm.name end
end
end
end
end
return 0
end
--check if the killer has populated dlc as a table
function resolveDlcProperty(killer)
return ((type(killer.dlc) == types.number and killer.dlc) or (type(killer.dlc) == types.table and killer.dlc.id) or -1)
end
function resolveKillerSpeed(killer)
local result = cstr.empty
if type(killer.speed) == "number" then
result = getPercentSpeed(killer.speed) .. space .. '%' .. space .. b(bar) .. space .. killer.speed .. space .. strings.mps
else --so the killer speed is table
result = getPercentSpeed(killer.speed[1]) .. space .. '%' .. space .. b(bar) .. space .. killer.speed[1] .. space .. strings.mps .. space .. brackets(killer.speed[2])
end
return result
end
function resolveAltSpeed(killer)
local result = cstr.empty
local speedPercent
for i, altSpeed in ipairs(killer.altSpeed) do
speedPercent = getPercentSpeed(altSpeed[1])
result = result .. speedPercent .. " % " .. b(bar) .. space .. altSpeed[1] .. space .. strings.mps
if altSpeed[2] ~= nil then
result = result .. pg .. "(" .. altSpeed[2] .. ")"
end
if i < #killer.altSpeed then
result = result .. "<hr>" --.. nl .. nl
end
end
return result
end
function getPercentSpeed(speed)
return (speed / _defaultSpeed) * 100
end
function resolveTerrorRadius(killer)
local result = cstr.empty
if type(killer.radius) == "number" then
return killer.radius .. space .. strings.metres
elseif type(killer.radius) == "table" then
for i, radius in ipairs(killer.radius) do
if radius[3] ~= nil then --open span with title hover
result = result .. '<span class = "valueTooltip" title = "' .. radius[3] .. '">'
end
result = result .. radius[1] --metres value
if radius[2] ~= nil then --note for alt speed, if there is a note for the speed the abbreviation for metres is used instead of full name
result = result .. strings.m .. space .. brackets(radius[2])
else
result = result .. " " .. strings.metres
end
if radius[3] ~= nil then --close span hover
result = result .. '</span>'
end
if i < #killer.radius then
result = result .. nl .. nl
end
end
end
return result
end
function resolveHeight(killer)
if killer.height == 'T' then return strings.tall
elseif killer.height == 'A' then return strings.avg
elseif killer.height == 'S' then return strings.short
else return strings.err
end
end
function p.resolveKillersTable()
local result = ""
local name
local fileName
result = result .. '<div style="color: #fff;">'
maxId = utils.getMaxId(killers)
for i, killer in ipairs(killers) do
name = killer.shortName or killer.realName or killer.name
fileName = utils.resolveCharacterPortraitFileName(killer, maxId)
result = result ..
'<div style="display: inline-block; text-align:center; margin: 10px">' .. link(name) .. ' - ' .. killer.name ..
link(cstr.file .. fileName .. '.png|center|frameless|link=' .. the(killer) .. " " .. killer.name) .. '</div>'
end
result = result .. '</div>'
return result
end
function p.resolveKillersTableMainPage() --todo: check this (rmv)
local result = cstr.empty
local name, fileName
result = result ..
'<div class = "fpbox" id = "fpkiller" style = "text-align: center;">' .. nl ..
'<div class = "heading">' .. the(strings.killers) .. link(strings.killers) .. space .. file('IconHelpLoading killer.png', '32px') .. '</div>' .. nl ..
'<div class = "fplinks charSection">' .. nl
local maxId = utils.getMaxId(killers)
for i, killer in ipairs(killers) do
fileName = utils.resolveCharacterPortraitFileName(killer, maxId)
result = result ..
'<div class = "fplink charMainPageBox plainlinks image">' .. nl ..
'<div class="box">' .. nl ..
'<div class="row">' .. nl ..
'<div class="cell">' .. nl ..
'<div class = "image">' .. file(fileName .. dot .. cstr.png, "link=" .. the(killer) .. killer.name) .. '</div>' .. nl ..
'<div class = "charLink killerLink link">' .. link(the(killer) .. killer.name) .. '</div>' .. nl ..
'<div class = "charPerkBox">' .. resolveCharPerksMainPage(killer) .. '</div>' .. nl ..
'</div>' .. nl ..
'</div>' .. nl ..
'</div>' .. nl ..
'</div>'
end
result = result ..
'</div>' .. nl ..
'</div>' .. nl
return result
end
function resolveCharPerksMainPage(character)
local mPerks = require("Module:Perks")
local result = cstr.empty
local perkList = mPerks.getPerksByCharacter(character)
utils.sortPerksByLevel(perkList)
for _, perk in ipairs(perkList) do
result = result .. utils.assembleImage("sosPerk", perk.name, 42)
end
return result
end
function getKillerListWithPerks()
local perkTable = {}
for _,perk in ipairs(perks) do
if perk.character ~= nil and perk.charType == 'K' then
if perkTable[perk.character] == nil then
perkTable[perk.character] = {}
end
perkTable[perk.character].id = perk.character
perkTable[perk.character][#perkTable[perk.character]+1] = perk
end
end
return perkTable
end
function p.resolveKillersEntries()
local perkTable = getKillerListWithPerks()
local result = cstr.empty
result = result .. '<div style = "display: flex; flex-flow: row wrap; justify-content:center;">' .. nl
for _, trio in ipairs(perkTable) do
result = result .. '<div class = "entryTable">' .. nl ..
'{| class = "wikitable"' .. nl
killer = p.getKillerById(trio.id)
result = result .. '|+ ' .. killer.name .. nl ..
ntl .. nl ..
tl .. 'class = "center" rowspan = 3 | [[' .. cstr.file .. resolveKillerPortraitImageFileName(killer) .. '.png|99px|link=' .. (killer.shortName or killer.realName or killer.name) .. ']]' .. nl
utils.sortPerksByLevel(trio)
for i, perk in ipairs(trio) do
result = result .. hl .. file(perkImg.main(perk.techName or perk.name),"33px") .. nl ..
hl ..link(perk.name) .. nl
if i < #trio then
result = result .. ntl .. nl
end
end
result = result .. '|}' .. nl ..
'</div>' .. nl
end
result = result .. '</div>' .. nl
--mw.log(result)
--mw.log(mw.dumpObject(perkTable))
return result
end
return p
Advertisement
English
Moduł:Killers
Advertisement