Dead by Daylight Wiki
mNie podano opisu zmian
Nie podano opisu zmian
(Nie pokazano 19 wersji utworzonych przez 3 użytkowników)
Linia 4: Linia 4:
 
local utils = require("Module:Utils")
 
local utils = require("Module:Utils")
 
local mPerks = require("Module:Perks")
 
local mPerks = require("Module:Perks")
 
local str = require("Module:Strings")
 
local frame = mw.getCurrentFrame()
 
local frame = mw.getCurrentFrame()
  +
local nl = "\n"
 
local ntl = "|-" -- new table line
+
local _inception = {year = 2016, month = 10, day = 26}
local inception = {year = 2016, month = 10, day = 26}
 
 
local _day = 24 * 60 * 60 --hours * minutes * seconds
 
local _day = 24 * 60 * 60 --hours * minutes * seconds
 
local _week = 7 * _day
 
local _week = 7 * _day
 
local _soSCountTableColumns = 6
 
local _soSCountTableColumns = 6
local inceptionColor = "3bg" --clr template value
+
local _inceptionColor = "3bg" --clr template value
  +
local _countOfPerksWithHigherPrice
local CountOfPerksWithHigherPrice = 12
 
   
 
local strings = {
 
local strings = {
Linia 33: Linia 33:
 
 
 
cost = "Koszt",
 
cost = "Koszt",
tPerk = "Umiejętność Przyswajalna",
+
tPerk = "Umiejętności Przyswajalne",
uPerkOf = "Unikalne dla",
+
uPerkOf = "Właściciele Umiejętności",
 
refreshes = "odświeżenie za",
 
refreshes = "odświeżenie za",
 
hours = "godziny",
 
hours = "godziny",
 
hour = "godzinę",
 
hour = "godzinę",
 
days = "dni",
 
days = "dni",
--day = "day", --not used
+
--day = "dzień", --not used
unknownPerk = "Nieznana Umiejętność",
+
unknownPerk = "Nieznana Umiejętność",
  +
unknown = "Nieznany",
  +
notImplemented = "Not Implemented",
 
}
 
}
   
Linia 54: Linia 56:
 
}
 
}
   
function p.convertSoSIds() -- this is ust helping function generating a SoS list increased by 32 common and unused perks (it's not uused in any other function)
+
function p.convertSoSIds() -- this is just helping function generating a SoS list increased by 32 common and unused perks (it's not used in any other function)
 
local modulePerks = require("Module:Perks")
 
local modulePerks = require("Module:Perks")
 
local result = {}
 
local result = {}
Linia 71: Linia 73:
 
-- Assembling SoS Table --
 
-- Assembling SoS Table --
   
function p.AssembleSoSTable(sosPerks)
+
function p.AssembleSoSTable(sosPerks, showCountdown, parameters)
  +
showCountdown = showCountdown or false
  +
parameters = parameters or false
 
local result = ""
 
local result = ""
  +
local cost = parameters and parameters.cost or 0
  +
local timer = parameters and parameters.timer or 0
 
 
result = result .. '{| class = "wikitable"' ..nl .. ntl .. nl
+
result = result .. '{| class = "sosTable"' ..nl .. ntl .. nl
 
result = result .. '! class = "sosHeader" width = "256px" colspan = 2 | ' .. strings.tPerk .. nl
 
result = result .. '! class = "sosHeader" width = "256px" colspan = 2 | ' .. strings.tPerk .. nl
 
result = result .. '! class = "sosHeader" width = "64px" | ' .. strings.cost .. nl
 
result = result .. '! class = "sosHeader" width = "64px" | ' .. strings.cost .. nl
 
result = result .. '! class = "sosHeader" width = "256px" colspan = 2 | ' .. strings.uPerkOf .. nl
 
result = result .. '! class = "sosHeader" width = "256px" colspan = 2 | ' .. strings.uPerkOf .. nl
  +
 
 
for i, perk in ipairs(sosPerks) do
 
for i, perk in ipairs(sosPerks) do
 
result = result .. ntl .. ' class = "sosRow"' .. nl
 
if type(perk) == "table" and perk.character ~= nil and perk.charType ~= nil then
 
if type(perk) == "table" and perk.character ~= nil and perk.charType ~= nil then
result = result .. ntl .. ' style="text-align:center"' .. nl
+
result = result .. '! [[' .. cstr.file .. GetSoSPerkImageByPerk(perk) .. '|64px|frameless|center]]' .. nl
result = result .. '! [[' .. strings.file .. ':' .. GetSoSPerkImageByPerk(perk) .. '|64px|frameless|center]]' .. nl
+
result = result .. '| class = "sosText" | [[' .. utils.GetDisplayName(perk) .. ']]' .. nl
result = result .. '| [[' .. perk.name .. ']]' .. nl
+
result = result .. '| class="BG-All ISACBG-All ISBG SoS-IS" | <div>' .. GetPerkCostByPerk(perk, cost, i) .. '</div><div>[[' ..cstr.file .. 'IconHelp iridescentShards.png|48px]]</div>' .. nl
result = result .. '| class="BG-All ISACBG-All ISBG SoS-IS" | <div>' .. GetPerkCostByPerk(perk) .. '</div><div>[[' ..strings.file .. ':' .. 'IconHelp iridescentShards.png|48px]]</div>' .. nl
+
result = result .. '| class = "sosText" | [[' .. mPerks.getPerksOwnerNameByPerk(perk) .. ']]' .. nl
result = result .. '| [[' .. mPerks.getPerksOwnerNameByPerk(perk) .. ']]' .. nl
+
result = result .. '! [[' .. cstr.file .. mPerks.getPortraitOfPerkOwnerByPerk(perk) .. '|64px|frameless|center]]' .. nl
result = result .. '! [[' .. strings.file .. ':' .. mPerks.getPortraitOfPerkOwnerByPerk(perk) .. '|64px|frameless|center]]' .. nl
 
 
else
 
else
result = result .. ntl .. ' style="text-align:center"' .. nl
+
result = result .. '! [[' .. cstr.file .. ':Dbd-perks-teachable.png|64px|frameless|center]]' .. nl
result = result .. '! [[' .. strings.file .. ':Dbd-perks-teachable.png|64px|frameless|center]]' .. nl
+
result = result .. '| class = "sosText" | ' .. strings.unknownPerk .. nl
result = result .. '| ' .. strings.unknownPerk .. nl
+
result = result .. '| class="BG-All ISACBG-All ISBG SoS-IS" | <div> - </div><div>[[' ..cstr.file .. 'IconHelp iridescentShards.png|48px]]</div>' .. nl
result = result .. '| class="BG-All ISACBG-All ISBG SoS-IS" | <div> - </div><div>[[' ..strings.file .. ':' .. 'IconHelp iridescentShards.png|48px]]</div>' .. nl
+
result = result .. '| class = "sosText" | - ' .. nl
result = result .. '| - ' .. nl
 
 
result = result .. '! - ' .. nl
 
result = result .. '! - ' .. nl
 
end
 
end
 
end
 
end
 
 
  +
if showCountdown then
result = result .. ntl .. nl
+
result = result .. ntl .. nl
result = result .. '! class = "sosHeader" colspan= 5 | ' .. strings.refreshes .. ' '.. utils.clr(p.GetSoSRemaningTime(), 4) .. nl
+
result = result .. '! class = "sosHeader" colspan= 5 | ' .. strings.refreshes .. ' '.. utils.clr(p.GetSoSRemainingTime(timer), 4) .. nl
 
end
 
result = result .. '|}'
 
result = result .. '|}'
  +
 
 
 
mw.log(result)
 
mw.log(result)
Linia 105: Linia 113:
 
end
 
end
   
function p.GetSoSRemaningTime()
+
function p.GetSoSRemainingTime(timer)
  +
timer = timer or 0
 
local currentWeekDay = tonumber(os.date("%w"))
 
local currentWeekDay = tonumber(os.date("%w"))
 
local result = ""
 
local result = ""
 
 
mw.log(os.date("Current weekday: %w"))
+
mw.log(os.date("Current weekday before offsetting: %w"))
if currentWeekDay == 2 then
+
if timer ~= 24 and timer ~= 0 then
  +
return strings.notImplemented --timer is bigger then the week, which means you need implement whole logic for it
  +
elseif timer == 24 then
  +
currentWeekDay = 2
  +
end
  +
mw.log(os.date("Current weekday after offsetting: %w"))
  +
if currentWeekDay == 2 then --one day remaning
 
local remainingHours = 24 - os.date("%H")
 
local remainingHours = 24 - os.date("%H")
return remainingHours .. " " .. remainingHours == 1 and strings.hours or strings.hour
+
return remainingHours .. " " .. (remainingHours == 1 and strings.hour or strings.hours)
 
elseif currentWeekDay > 2 then
 
elseif currentWeekDay > 2 then
 
result = 10 - currentWeekDay .. " " .. strings.days
 
result = 10 - currentWeekDay .. " " .. strings.days
Linia 125: Linia 140:
 
return result
 
return result
 
end
 
end
  +
function p.GetPerkCostByPerk(perk)
 
function GetPerkCostByPerk(perk)
+
return GetPerkCostByPerk(perk)
  +
end
  +
function GetPerkCostByPerk(perk, cost, i)
  +
if not _countOfPerksWithHigherPrice then SetGlobalCountOfPerksWithHigherPrice() end
  +
i = i or 0
  +
cost = cost or 0
 
if perk == 0 then return "-" end
 
if perk == 0 then return "-" end
if perk.id <= mPerks._allPerksCount - CountOfPerksWithHigherPrice then return price.normal
+
if type(cost) == "table" and i > 0 then return cost[i] end
  +
if perk.id <= mPerks._allPerksCount - _countOfPerksWithHigherPrice then return price.normal + cost
else return price.high end
+
else return price.high + cost end
 
end
 
end
   
 
function GetSoSPerkImageByPerk(perk)
 
function GetSoSPerkImageByPerk(perk)
 
if perk == 0 then return "Dbd-perks-template.png" end
 
if perk == 0 then return "Dbd-perks-template.png" end
local name = utils.FirstLetterLower(utils.resolveFileName(perk.engName, false))
+
local name = utils.FirstLetterLower(utils.resolveFileName((perk.techName or perk.name), false))
 
return strings.teachable .. "_" .. name .. ".png"
 
return strings.teachable .. "_" .. name .. ".png"
 
end
 
end
   
 
function GetSoSPerks(sos)
 
function GetSoSPerks(sos)
result = {}
+
local result = {}
  +
 
  +
for i, perkId in ipairs(sos) do --this form should prevent to to fial due to metadata table in args table when the args table is passed
for i = 1, 4, 1 do
 
  +
local perk = mPerks.getPerkById(tonumber(perkId))
table.insert(result, GetPerkById(sos[i]))
 
  +
if perk ~= nil then
 
table.insert(result, perk)
 
end
 
end
 
end
  +
 
mw.log(mw.dumpObject(result))
+
--mw.log(mw.dumpObject(result))
 
return result
 
return result
 
end
 
end
   
function GetPerkById(id)
+
function SetGlobalCountOfPerksWithHigherPrice()
 
for _,dlc in ipairs(dlcs) do
local dataPerks = require("Module:Datatable/Perks")
 
  +
if not utils.IsFullDateTime(dlc.rDate) then
local modulePerks = require("Module:Perks")
 
  +
_countOfPerksWithHigherPrice = 24
--mw.log(mw.dumpObject(modulePerks))
 
 
return 24
--mw.log('Type: ' .. type(perks))
 
  +
end
 
for _, perk in ipairs(perks) do
 
if perk.id == id then return perk end --TODO: Remove the tomporary variable. Before that the IDs in Module:Datatable/SoS must by raised by this constant!! (32)
 
 
end
 
end
  +
_countOfPerksWithHigherPrice = 18
return 0
 
  +
return 18
 
end
 
end
   
Linia 176: Linia 199:
   
 
function p.CurrentSoS()
 
function p.CurrentSoS()
return p.AssembleSoSTable(GetSoSPerks(sos[1]))
+
return p.AssembleSoSTable(GetSoSPerks(sos[1]), true, sos[1][5])
 
end
 
end
   
function p.ManualSoS(args) --Unused?
+
function p.ManualSoS(args) --Used in Documentation
args = args.args
+
return p.AssembleSoSTable(GetSoSPerks(args.args))
p.AssembleSoSTable(GetSoSPerks(args))
 
 
end
 
end
   
Linia 205: Linia 227:
 
end
 
end
   
function GetEmptyPerkTable(emptyTables)
+
function GetEmptyPerkTable()
 
local result = {}
 
local result = {}
 
if not emptyTable then for i = 1, #perks do result[i] = 0 end --make empty table with 0 values for every perk in sos table
 
if not emptyTable then for i = 1, #perks do result[i] = 0 end --make empty table with 0 values for every perk in sos table
Linia 212: Linia 234:
 
end
 
end
   
function GetCountOfPerks(year)
+
function GetCountOfPerks()
 
local perkList = GetEmptyPerkTable()
 
local perkList = GetEmptyPerkTable()
   
Linia 218: Linia 240:
 
for j, sosPerk in ipairs(sosWeek) do
 
for j, sosPerk in ipairs(sosWeek) do
 
if type(sosPerk) ~= "table" then
 
if type(sosPerk) ~= "table" then
  +
mw.logObject("sosPerk: " .. sosPerk)
 
if perkList[sosPerk] == nil then --sosPerk, the perk ID will be an index of perkList table. Due to Lua logic there must not be a nil between items (that's why there is getEmptyPerkTable())
 
if perkList[sosPerk] == nil then --sosPerk, the perk ID will be an index of perkList table. Due to Lua logic there must not be a nil between items (that's why there is getEmptyPerkTable())
 
perkList[sosPerk] = 1 --DEV TODO check if possible to remove it
 
perkList[sosPerk] = 1 --DEV TODO check if possible to remove it
Linia 245: Linia 268:
 
end
 
end
 
number = SoSPerkCountTable[perk.id]
 
number = SoSPerkCountTable[perk.id]
result = result .. "! [[" .. strings.file .. ":" .. strings.teachable .. " " .. utils.FirstLetterLower(utils.resolveFileName(perk.engName)) .. ".png|64px|center]]" .. nl
+
result = result .. "! [[" .. cstr.file .. strings.teachable .. " " .. utils.FirstLetterLower(utils.resolveFileName((perk.techName or perk.name))) .. ".png|64px|center]]" .. nl
 
result = result .. "! [[" .. perk.name .. "]]" .. nl
 
result = result .. "! [[" .. perk.name .. "]]" .. nl
 
if number ~= 0 then
 
if number ~= 0 then
Linia 265: Linia 288:
 
elseif number == 0 then return frame:expandTemplate{title = "clr", args = {8, number}}
 
elseif number == 0 then return frame:expandTemplate{title = "clr", args = {8, number}}
 
elseif number == 1 then return frame:expandTemplate{title = "clr", args = {2, number}}
 
elseif number == 1 then return frame:expandTemplate{title = "clr", args = {2, number}}
  +
elseif number == nil then return strings.unknown
 
end
 
end
 
return number
 
return number
Linia 278: Linia 302:
 
if j <= 4 then
 
if j <= 4 then
 
if perk == id then
 
if perk == id then
mw.log("Last Occ: " .. GetDateFromSoSIndex(i + offset))
+
mw.log("Last Occ.: " .. GetDateFromSoSIndex(i + offset) .. ", Perk: " .. mPerks.getPerkById(id).name)
 
return i - 1 + offset
 
return i - 1 + offset
 
end
 
end
Linia 329: Linia 353:
   
 
function GetIndexesOfPeriod(year)
 
function GetIndexesOfPeriod(year)
local currentWeekDate = os.time(inception)
+
local currentWeekDate = os.time(_inception)
 
local currentYear
 
local currentYear
 
local index = #sos
 
local index = #sos
local perkList = GetEmptyPerkTable()
 
 
local result = {}
 
local result = {}
   
 
for i, sosWeek in ipairs(sos) do
 
for i, sosWeek in ipairs(sos) do
 
currentYear = tonumber(os.date("%Y", currentWeekDate))
 
currentYear = tonumber(os.date("%Y", currentWeekDate))
  +
--mw.log("current Year: " .. currentYear .. ", i: " .. i .. ", index: " .. index .. "sos: {" .. (sos[index][1] ~= nil and (sos[index][1] .. ", " .. sos[index][2] .. ", " .. sos [index][3] .. ", " ..sos[index][4]) or "NULL, NULL, NULL, NULL") .. "}") -- sos[index][1] .. ", " .. sos[index][2] .. ", " .. sos [index][3] .. ", " ..sos[index][4]
 
if year == nil or year == currentYear then
 
if year == nil or year == currentYear then
 
if result[1] == nil then
 
if result[1] == nil then
Linia 354: Linia 378:
 
end
 
end
 
--mw.log(mw.dumpObject(result))
 
--mw.log(mw.dumpObject(result))
  +
if #result == 0 then return {0, 0} end --if pStart and pEnd is nil then return zero values
 
return result
 
return result
 
end
 
end
Linia 367: Linia 392:
 
end
 
end
   
function SoSArchiveCalendar(year)
+
function SoSArchiveCalendar(year, pStart, pEnd)
local currentWeekDate = os.time(inception)
+
local currentWeekDate = os.time(_inception)
 
local perkList = GetEmptyPerkTable()
 
local perkList = GetEmptyPerkTable()
  +
if pStart == nil or pEnd == nil then
local pStart, pEnd = unpack(GetIndexesOfPeriod(year)) --Period Start and Period End
+
pStart, pEnd = unpack(GetIndexesOfPeriod(year)) --Period Start and Period End
  +
end
 
local offset = 0
 
local offset = 0
 
local offset2016 = 0
 
local offset2016 = 0
Linia 377: Linia 404:
 
local color
 
local color
 
local index
 
local index
  +
local text, header
 
 
 
if year == 2016 then
 
if year == 2016 then
offset2016 = tonumber(os.date("%W", os.time(inception))) - 1 --setting offset by 43 weeks
+
offset2016 = tonumber(os.date("%W", os.time(_inception))) - 1 --setting offset by 43 weeks
 
end
 
end
 
 
Linia 388: Linia 416:
 
color = sos[i][5].color
 
color = sos[i][5].color
 
notices[week] = sos[i][5].notice
 
notices[week] = sos[i][5].notice
 
text = sos[i][5].text
  +
header = sos[i][5].header
 
else
 
else
 
color = nil
 
color = nil
Linia 394: Linia 424:
 
if type(sosPerk) ~= "table" then
 
if type(sosPerk) ~= "table" then
 
if sosPerk ~= 0 then
 
if sosPerk ~= 0 then
  +
local occurenceIndex
 
if perkList[sosPerk] == 0 then --sosPerk, the perk ID will be an index of perkList table. Due to Lua logic there must not be a nil between items (that's why there is getEmptyPerkTable())
 
if perkList[sosPerk] == 0 then --sosPerk, the perk ID will be an index of perkList table. Due to Lua logic there must not be a nil between items (that's why there is getEmptyPerkTable())
  +
occurenceIndex = 1
perkList[sosPerk] = {{week = week + offset}}
 
if color ~= nil then
+
perkList[sosPerk] = {}
perkList[sosPerk][1].color = color
 
end
 
 
else
 
else
perkList[sosPerk][#perkList[sosPerk] + 1] = {week = week + offset, color = color}
+
occurenceIndex = #perkList[sosPerk] + 1
 
end
 
end
  +
  +
local newOccurence = { --here insert data you want to be accessible while creating a calendar (+ initialize the variable above (#413))
 
week = week + offset,
 
color = color,
  +
text = text,
  +
header = header
  +
}
  +
  +
perkList[sosPerk][occurenceIndex] = newOccurence
 
end
 
end
 
end
 
end
Linia 437: Linia 475:
 
releaseWeek = tonumber(os.date("%W", os.time(dlcDate))) - weekOffset + 1 -- +1 because week indexing start at 0
 
releaseWeek = tonumber(os.date("%W", os.time(dlcDate))) - weekOffset + 1 -- +1 because week indexing start at 0
 
 
result[perk.id] = {week = releaseWeek, color = inceptionColor, inception = true}
+
result[perk.id] = {week = releaseWeek, color = _inceptionColor, inception = true}
 
 
mw.log("Perk " .. perk.name .. " was released at week " .. releaseWeek .. "(+" .. weekOffset .. ")")
+
--mw.log("Perk " .. perk.name .. " was released at week " .. releaseWeek .. "(+" .. weekOffset .. ")")
 
end
 
end
 
end
 
end
Linia 478: Linia 516:
 
year = ResolveYearParam(year)
 
year = ResolveYearParam(year)
 
local pStart, pEnd = unpack(GetIndexesOfPeriod(year))
 
local pStart, pEnd = unpack(GetIndexesOfPeriod(year))
local perkList, weekNames = unpack(SoSArchiveCalendar(year))
+
local perkList, weekNames = unpack(SoSArchiveCalendar(year, pStart, pEnd))
 
local perkInception = GetPerksInception(year)
 
local perkInception = GetPerksInception(year)
perkList = mergePerkListWithInceptionList(perkList, perkInception)
 
 
local result = ""
 
local result = ""
 
local currentWeekDate = 1
 
local currentWeekDate = 1
Linia 487: Linia 524:
 
local hideable
 
local hideable
 
if year == 2016 then
 
if year == 2016 then
currentWeekDate = tonumber(os.date("%W", os.time(inception)))
+
currentWeekDate = tonumber(os.date("%W", os.time(_inception)))
startWeekDate = tonumber(os.date("%W", os.time(inception)))
+
startWeekDate = tonumber(os.date("%W", os.time(_inception)))
 
end
 
end
 
local globalOffset = GetGlobalOffsetInYear(pStart, pEnd)
 
local globalOffset = GetGlobalOffsetInYear(pStart, pEnd)
Linia 495: Linia 532:
 
 
 
if perkInception == -1 then return strings.wrongCharType end
 
if perkInception == -1 then return strings.wrongCharType end
 
perkList = mergePerkListWithInceptionList(perkList, perkInception)
 
 
 
result = result .. "<div id=\"inceptionPerks" .. year .."\" class=\"inceptionSwitch\"></div>" .. nl --Show/Hide Switch
 
result = result .. "<div id=\"inceptionPerks" .. year .."\" class=\"inceptionSwitch\"></div>" .. nl --Show/Hide Switch
Linia 501: Linia 539:
 
result = result .. ntl .. nl
 
result = result .. ntl .. nl
 
result = result .. "! colspan = 2" .. "| " .. nl
 
result = result .. "! colspan = 2" .. "| " .. nl
mw.log(mw.dumpObject(weekNames))
+
--mw.log(mw.dumpObject(weekNames))
 
 
 
for i = 1, numberOfWeeksInYear do -- Weeks Header
 
for i = 1, numberOfWeeksInYear do -- Weeks Header
Linia 515: Linia 553:
 
 
 
utils.sortItemsByName(perks)
 
utils.sortItemsByName(perks)
mw.log("pStart: " .. pStart)
+
--mw.log("pStart: " .. pStart)
mw.log("pEnd: " .. pEnd)
+
--mw.log("pEnd: " .. pEnd)
mw.log(numberOfWeeksInYear)
+
--mw.log("Number of Weeks (without weeks with offsets): " .. numberOfWeeksInYear)
mw.log(lastWeekNumber)
+
--mw.log(mw.dumpObject(sos[pStart]))
mw.log(lastWeekNumber - (pStart - pEnd))
+
--mw.log(mw.dumpObject(sos[pEnd]))
mw.log(43)
+
--mw.log(lastWeekNumber)
  +
--mw.log(lastWeekNumber - (pStart - pEnd))
  +
--mw.log(43)
 
for i, perk in ipairs(perks) do
 
for i, perk in ipairs(perks) do
 
if perk.character ~= nil and perkList[perk.id] ~= 0 then
 
if perk.character ~= nil and perkList[perk.id] ~= 0 then
Linia 534: Linia 574:
 
result = result .. " class=\"inception-row" .. year .. "\" style=\"display: none;\" "
 
result = result .. " class=\"inception-row" .. year .. "\" style=\"display: none;\" "
 
end
 
end
result = result .. nl .. "! [[" .. strings.file .. ":" .. strings.teachable .. " " .. utils.FirstLetterLower(utils.resolveFileName(perk.engName)) .. ".png|32px]] !! " .. perk.name .. nl .. "|"
+
result = result .. nl .. "! [[" .. cstr.file .. strings.teachable .. " " .. utils.FirstLetterLower(utils.resolveFileName((perk.techName or perk.name))) .. ".png|32px]] !! " .. perk.name .. nl .. "|"
 
 
 
for j = startWeekDate, lastWeekNumber do --going through week in year
 
for j = startWeekDate, lastWeekNumber do --going through week in year
  +
--j = week currently processed
 
weekFound = false
 
weekFound = false
  +
local titleText = ""
  +
local color = "white"
  +
local sameWeekCounter = 0
 
for k, perkOcc in ipairs(perkList[perk.id]) do --perkOcc = Perk Occurrence
 
for k, perkOcc in ipairs(perkList[perk.id]) do --perkOcc = Perk Occurrence
if perk.id == 30 then mw.log("Perk " .. perk.name .. ": " .. perk.id .. ", weekOcc:" .. perkOcc.week .. ", j: " .. j) end
+
--if perk.id == 63 and j == perkOcc.week then mw.log("Perk " .. perk.name .. ": " .. perk.id .. ", weekOcc:" .. perkOcc.week .. ", j: " .. j .. ", Text: " .. (perkOcc.text or "") .. "\n*****\n" .. mw.dumpObject(perkList[63]) .. "\n*****\n") end
if perkOcc.week == j then
+
if perkOcc.week == j and not weekFound then
  +
sameWeekCounter = sameWeekCounter + 1
local color = frame:expandTemplate{title = "clr", args = {perkOcc.color or "white"}}
 
  +
color = (perkOcc.color or "white")
 
result = result .. "style=\"background-color: #" .. color .. ";\" title = \"" ..strings.week .. " " .. perkOcc.week .. "\" | " --[[File:nothing.png]]
+
titleText = strings.week .. " " .. perkOcc.week
  +
if perkOcc.header then
  +
titleText = titleText .. " - " .. perkOcc.header
  +
end
 
weekFound = true
 
weekFound = true
break
+
if perkOcc.inception then break end
  +
elseif perkOcc.week == j and weekFound then
  +
if not perkOcc.inception then
  +
sameWeekCounter = sameWeekCounter + 1
  +
titleText = titleText .. "&#010;" .. strings.week .. " " .. perkOcc.week
  +
if perkOcc.header then
  +
titleText = titleText .. " - " .. perkOcc.header
  +
end
  +
else
  +
color = perkOcc.color
  +
end
  +
end
  +
end
 
color = frame:expandTemplate{title = "clr", args = {color}}
  +
  +
if weekFound then
 
local class = ""
  +
result = result .. "style=\"background-color: #" .. color .. "\"; "
  +
  +
if sameWeekCounter > 1 then
  +
class = "class = \"multipleOccurenceSoSCalendar\" "
  +
else
  +
sameWeekCounter = ""
 
end
 
end
  +
result = result .. class .. "\" title = \"" .. titleText .. "\" | " .. sameWeekCounter --[[File:nothing.png]]
 
end
 
end
  +
 
if j ~= lastWeekNumber then --if it's not occurence in last week then add delimeters
 
if j ~= lastWeekNumber then --if it's not occurence in last week then add delimeters
 
result = result .. " ||"
 
result = result .. " ||"
Linia 558: Linia 629:
 
result = result .. "|}"
 
result = result .. "|}"
 
 
mw.log(result)
+
--mw.log(result)
 
return result
 
return result
 
end
 
end
Linia 571: Linia 642:
 
local header
 
local header
 
if year == 2016 then
 
if year == 2016 then
currentWeekDate = tonumber(os.date("%W", os.time(inception))) --43
+
currentWeekDate = tonumber(os.date("%W", os.time(_inception))) --43
startWeekDate = tonumber(os.date("%W", os.time(inception))) --52
+
startWeekDate = tonumber(os.date("%W", os.time(_inception))) --52
 
end
 
end
 
local currentOffset = 0
 
local currentOffset = 0
Linia 587: Linia 658:
 
for i = startWeekDate, lastWeekNumber do --going through week in year
 
for i = startWeekDate, lastWeekNumber do --going through week in year
 
sosIndex = pStart + startWeekDate - i
 
sosIndex = pStart + startWeekDate - i
  +
-- do return end
  +
if sosIndex > #sos or sosIndex < 1 then break end --If the index is actually higher than the number of elements in SoS table or the index is below 0
 
if sos[sosIndex][5] ~= nil then --If there's a table after 4 perks then retrieve data
 
if sos[sosIndex][5] ~= nil then --If there's a table after 4 perks then retrieve data
 
if sos[sosIndex][5].offset ~= nil then
  +
currentOffset = currentOffset + sos[sosIndex][5].offset --the number itself is a negative value, thus a +
  +
end
  +
 
if sos[sosIndex][5].header ~= nil then
 
if sos[sosIndex][5].header ~= nil then
 
header = sos[sosIndex][5].header
 
header = sos[sosIndex][5].header
elseif sos[sosIndex][5].offset ~= nil then
 
currentOffset = currentOffset - 1
 
header = strings.week .. " " .. (i + currentOffset)
 
if sos[sosIndex][5].hideVersion ~= true then
 
header = header .. " v." .. (1 - sos[sosIndex][5].offset)
 
end
 
 
else
 
else
header = strings.week .. " " .. i + currentOffset
+
header = strings.week .. space .. (i + currentOffset)
 
end
 
end
  +
text = sos[sosIndex][5].text or ""
 
 
text = sos[sosIndex][5].text or cstr.empty
 
else
 
else
header = strings.week .. " " .. i + currentOffset
+
header = strings.week .. space .. (i + currentOffset)
text = ""
+
text = cstr.empty
 
end
 
end
 
--result = sos[sosIndex][1] .. ", " .. sos[sosIndex][2] .. ", " .. sos[sosIndex][3] .. ", " .. sos[sosIndex][4] .. nl .. nl .. result
 
--result = sos[sosIndex][1] .. ", " .. sos[sosIndex][2] .. ", " .. sos[sosIndex][3] .. ", " .. sos[sosIndex][4] .. nl .. nl .. result

Wersja z 14:59, 17 sty 2022


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

local _inception = {year = 2016, month = 10, day = 26}
local _day = 24 * 60 * 60 --hours * minutes * seconds
local _week = 7 * _day
local _soSCountTableColumns = 6
local _inceptionColor  = "3bg" --clr template value
local _countOfPerksWithHigherPrice

local strings = {
	file = "Plik", --[[File:...]]
	teachable = "Teachable", --[[File:Teachable ...]]
	
	foreignLang = false, --not used
	wrongCharType = "Error: There's an invalid CharType in [[Module:DataTable]] - table perks",
	icon = "Ikona",
	name = "Nazwa",
	weeksOf = "Tygodnie w",
	shrineCount = "Sanktuarium Tajemnic",
	week = "Tydzień",
	weeks = "tygodnie",
	weeksAgo = "temu",
	weekAgoString = "#result #weekString #weeksAgo",
	--weekAgoString = "#weeksAgo #result #weekString", --example for foreign language with different wording order
	currentlyInSoS = "Currently in Shrine of Secrets!",
	lastOcc = "Last occ",
	
	cost = "Koszt",
	tPerk = "Umiejętności Przyswajalne",
	uPerkOf = "Właściciele Umiejętności",
	refreshes = "odświeżenie za",
	hours = "godziny",
	hour = "godzinę",
	days = "dni",
	--day = "dzień", --not used
	unknownPerk = "Nieznana Umiejętność",
	unknown = "Nieznany",
	notImplemented = "Not Implemented",
}

regexTable = {
	["#weeksAgo"] = strings.weeksAgo,
	["#week"] = strings.week:lower(),
	["#weeks"] = strings.weeks
}

price = {
	normal = 2000,
	high = 2700
}

function p.convertSoSIds() -- this is just helping function generating a SoS list increased by 32 common and unused perks (it's not used in any other function)
	local modulePerks = require("Module:Perks")
	local result = {}
	for _, week in ipairs(sos) do
			local newWeek = {}
		for i = 1, 4, 1 do
			table.insert(newWeek, week[i] + modulePerks._nonUniquePerksCount)
		end
		table.insert(result, newWeek)
	end
	for _, week in ipairs(result) do
		mw.log("{" .. week[1] .. ", " .. week[2] .. ", " .. week[3] .. ", " .. week[4] .. "},")
	end
end

-- Assembling SoS Table --

function p.AssembleSoSTable(sosPerks, showCountdown, parameters)
	showCountdown = showCountdown or false
	parameters = parameters or false
	local result = ""
	local cost = parameters and parameters.cost or 0
	local timer = parameters and parameters.timer or 0
	
	result = result .. '{| class = "sosTable"' ..nl .. ntl .. nl
	result = result .. '! class = "sosHeader" width = "256px" colspan = 2 | ' .. strings.tPerk .. nl
	result = result .. '! class = "sosHeader" width = "64px" | ' .. strings.cost .. nl
	result = result .. '! class = "sosHeader" width = "256px" colspan = 2 | ' .. strings.uPerkOf .. nl

	for i, perk in ipairs(sosPerks) do
			result = result .. ntl .. ' class = "sosRow"' .. nl
		if type(perk) == "table" and perk.character ~= nil and perk.charType ~= nil then
			result = result .. '! [[' .. cstr.file .. GetSoSPerkImageByPerk(perk) .. '|64px|frameless|center]]' .. nl
			result = result .. '| class = "sosText" | [[' .. utils.GetDisplayName(perk) .. ']]' .. nl
			result = result .. '| class="BG-All ISACBG-All ISBG SoS-IS" | <div>' .. GetPerkCostByPerk(perk, cost, i) .. '</div><div>[[' ..cstr.file .. 'IconHelp iridescentShards.png|48px]]</div>' .. nl
			result = result .. '| class = "sosText" | [[' .. mPerks.getPerksOwnerNameByPerk(perk) .. ']]' .. nl
			result = result .. '! [[' .. cstr.file .. mPerks.getPortraitOfPerkOwnerByPerk(perk) .. '|64px|frameless|center]]' .. nl
		else
			result = result .. '! [[' .. cstr.file .. ':Dbd-perks-teachable.png|64px|frameless|center]]' .. nl
			result = result .. '| class = "sosText" | ' .. strings.unknownPerk .. nl
			result = result .. '| class="BG-All ISACBG-All ISBG SoS-IS" | <div> - </div><div>[[' ..cstr.file .. 'IconHelp iridescentShards.png|48px]]</div>' .. nl
			result = result .. '| class = "sosText" | - ' .. nl
			result = result .. '! - ' .. nl
		end
	end
	
	if showCountdown then
		result = result .. ntl .. nl
		result = result .. '! class = "sosHeader" colspan= 5 |  ' .. strings.refreshes .. ' '.. utils.clr(p.GetSoSRemainingTime(timer), 4) .. nl
	end
	result = result .. '|}'

	
	mw.log(result)
	return result
end

function p.GetSoSRemainingTime(timer)
	timer = timer or 0
	local currentWeekDay = tonumber(os.date("%w"))
	local result = ""
	
	mw.log(os.date("Current weekday before offsetting: %w"))
	if timer ~= 24 and timer ~= 0 then 
		return strings.notImplemented --timer is bigger then the week, which means you need implement whole logic for it
	elseif timer == 24 then
		currentWeekDay = 2
	end
	mw.log(os.date("Current weekday after offsetting: %w"))
	if currentWeekDay == 2 then --one day remaning
		local remainingHours = 24 - os.date("%H")
		return remainingHours .. " " .. (remainingHours == 1 and strings.hour or strings.hours)
	elseif currentWeekDay > 2 then
		result = 10 - currentWeekDay .. " " ..  strings.days
		--3 4 5 6 --weekday
		--7 6 5 4 --days remaining
	else
		result = 3 - currentWeekDay .. " " .. strings.days --day/days
		--0 1 --weekday
		--3 2 --days remaining
	end
	mw.log(result)
	return result
end
function p.GetPerkCostByPerk(perk)
	return GetPerkCostByPerk(perk)
end
function GetPerkCostByPerk(perk, cost, i)
	if not _countOfPerksWithHigherPrice then SetGlobalCountOfPerksWithHigherPrice() end
	i = i or 0
	cost = cost or 0
	if perk == 0 then return "-" end
	if type(cost) == "table" and i > 0 then return cost[i] end
	if perk.id <= mPerks._allPerksCount - _countOfPerksWithHigherPrice then return price.normal + cost
	else return price.high + cost end
end

function GetSoSPerkImageByPerk(perk)
	if perk == 0 then return "Dbd-perks-template.png" end
	local name = utils.FirstLetterLower(utils.resolveFileName((perk.techName or perk.name), false))
	return strings.teachable .. "_" .. name .. ".png"
end

function GetSoSPerks(sos)
	local result = {}

	for i, perkId in ipairs(sos) do --this form should prevent to to fial due to metadata table in args table when the args table is passed
		local perk = mPerks.getPerkById(tonumber(perkId))
		if perk ~= nil then
			table.insert(result, perk)
		end
	end

	--mw.log(mw.dumpObject(result))
	return result
end

function SetGlobalCountOfPerksWithHigherPrice()
	for _,dlc in ipairs(dlcs) do
		if not utils.IsFullDateTime(dlc.rDate) then
			_countOfPerksWithHigherPrice = 24
			return 24
		end
	end
	_countOfPerksWithHigherPrice = 18
	return 18
end

-- #END# Assembling SoS Table #END# --

function sos.last()
	return sos[#sos]	
end

function p.SoS(index)
	return p.AssembleSoSTable(GetSoSPerks(sos[#sos - tonumber(index.args[1])]))
end

function SoS(index)
	return p.AssembleSoSTable(GetSoSPerks(sos[index]))
end

function p.CurrentSoS()
	return p.AssembleSoSTable(GetSoSPerks(sos[1]), true, sos[1][5])
end

function p.ManualSoS(args) --Used in Documentation
	return p.AssembleSoSTable(GetSoSPerks(args.args))
end

--ISO: https://en.wikipedia.org/wiki/ISO_week_date
--If 1 January is on a Monday, Tuesday, Wednesday or Thursday, it is in W01. If it is on a Friday, it is part of W53 of the previous year.
--If it is on a Saturday, it is part of the last week of the previous year which is numbered W52 in a common year and W53 in a leap year.
--If it is on a Sunday, it is part of W52 of the previous year.
function GetWeekNumber(dateStamp) --in milliseconds, os.time()
	firstWeekDayOfYear = tonumber(os.date("%w", os.time({year = os.date("%Y", dateStamp), month = 1, day = 1})))
	firstWeekOfYear = tonumber(os.date("%W", os.time({year = os.date("%Y", dateStamp), month = 1, day = 1})))
	
	-- ATTENTION as per description above some years have first week 01
	-- because all first weeks of year that starts with Sunday, Saturday, Friday or Thursday must be shifted
	if firstWeekDayOfYear > 0 and firstWeekDayOfYear < 4  and firstWeekOfYear == 0 then
		return tonumber(os.date("%W", dateStamp)) + 1
	else
		return tonumber(os.date("%W", dateStamp))
	end
end

function p.GetCurrentWeekNumber()
	return GetWeekNumber(os.time())
end

function GetEmptyPerkTable()
	local result = {}
	if not emptyTable then for i = 1, #perks do result[i] = 0 end  --make empty table with 0 values for every perk in sos table
	else for i = 1, #perks do result[i] = {} end end
	return result
end

function GetCountOfPerks()
	local perkList = GetEmptyPerkTable()

	for i, sosWeek in ipairs(sos) do
		for j, sosPerk in ipairs(sosWeek) do
			if type(sosPerk) ~= "table" then
				mw.logObject("sosPerk: " .. sosPerk)
				if perkList[sosPerk] == nil then --sosPerk, the perk ID will be an index of perkList table. Due to Lua logic there must not be a nil between items (that's why there is getEmptyPerkTable())
					perkList[sosPerk] = 1 --DEV TODO check if possible to remove it
				else
					perkList[sosPerk] = perkList[sosPerk] + 1
				end
			end
		end
	end
	return perkList
end

function p.AssembleSoSPerkCountTable()
	local SoSPerkCountTable = GetCountOfPerks()
	local maxOccurrence = math.max(unpack(SoSPerkCountTable))
	local result = ""
	local number
	utils.sortItemsByName(perks)
	
	result = result .. "{| class=\"wikitable unsortable\"" .. nl

	local i = 1
	for _, perk in ipairs(perks) do
		if perk.character ~= nil then
			if (i - 1) % _soSCountTableColumns == 0 then
				result = result .. ntl .. nl
			end
			number = SoSPerkCountTable[perk.id]
			result = result .. "! [[" .. cstr.file .. strings.teachable .. " " .. utils.FirstLetterLower(utils.resolveFileName((perk.techName or perk.name))) .. ".png|64px|center]]" .. nl
			result = result .. "! [[" .. perk.name .. "]]" .. nl
			if number ~= 0 then
				result = result .. "<div class='noticeText' title='" .. GetTextWeeksAgoOfLastOccurrenceById(perk.id) .. "'>" .. strings.lastOcc .. ": " .. GetLastPerkOccurrenceById(perk.id) .. "</div>" .. nl
			end
			result = result .. "| <center>'''" .. GetColoredOccurrenceNumber(number, maxOccurrence) ..  "'''</center>" .. nl
			
			i = i + 1
		end
	end
	
	result = result .. "|}"
	--mw.log(mw.dumpObject(result))
	return result
end

function GetColoredOccurrenceNumber(number, maxOccurrence)
	if number == maxOccurrence then return frame:expandTemplate{title = "clr", args = {3, number}}
	elseif number == 0 then return frame:expandTemplate{title = "clr", args = {8, number}}
	elseif number == 1 then return frame:expandTemplate{title = "clr", args = {2, number}}
	elseif number == nil then return strings.unknown
	end
	return number
end

--Old ID is the ID that occurs in old Perk table in Datatable (not in Datatable/Perks)
function GetWeeksAgoOfLastOccurrenceById(id)
	local offset = 0

	for i, sosWeek in ipairs(sos) do -- i = weeks ago (to current day)
		--mw.log(mw.dumpObject(sosWeek))
		for j, perk in ipairs(sosWeek) do
			if j <= 4 then
				if perk == id then
					mw.log("Last Occ.: " .. GetDateFromSoSIndex(i + offset) .. ", Perk: " .. mPerks.getPerkById(id).name)
					return i - 1 + offset
				end
			else
				if perk.offset ~= nil then
					offset = offset + perk.offset
				end
			end
		end
	end
	return 0
end

function GetLastPerkOccurrenceById(id)
	return GetDateFromSoSIndex(GetWeeksAgoOfLastOccurrenceById(id))
end

--sosIndex should be a number of how many weeks ago the perk occurred
function GetDateFromSoSIndex(sosIndex)
	local result = os.time() - sosIndex * _week
	local weekDay =  tonumber(os.date("%w", result))
	local offset
	
	if weekDay < 3 then offset = (-weekDay - 4) * _day -- current day is Sunday, Monday, or Tuesday (WeekDay = 0 - 2)
	elseif weekDay > 3 then offset = (-weekDay + 3) * _day --current day is Thursday, Friday, or Saturday (WeekDay = 4 - 6)
	else offset = 0	end -- current day is Wednesday
	
	return os.date("%d.%m.%Y", result + offset) --offset is in negative
	--2 = -6
	--1 = -5
	--0 = -4
	--6 = -3
	--5 = -2
	--4 = -1
	--3 =  0
end

function GetTextWeeksAgoOfLastOccurrenceById(id) --there will be probably needed to make a copy of a replacing string
	result =  GetWeeksAgoOfLastOccurrenceById(id)
	if result > 1 then
		strings.weekAgoString = strings.weekAgoString:gsub("#weekString", "#weeks")
	elseif result == 1 then
		strings.weekAgoString = strings.weekAgoString:gsub("#weekString", "#week")
	else
		return strings.currentlyInSoS
	end
	
	return utils.regularReplace(strings.weekAgoString:gsub("#result", result), regexTable)
end

function GetIndexesOfPeriod(year)
	local currentWeekDate = os.time(_inception)
	local currentYear
	local index = #sos
	local result = {}

	for i, sosWeek in ipairs(sos) do
		currentYear = tonumber(os.date("%Y", currentWeekDate))
		--mw.log("current Year: " .. currentYear .. ", i: " .. i .. ", index: " .. index .. "sos: {" .. (sos[index][1] ~= nil and (sos[index][1] .. ", " .. sos[index][2] .. ", " .. sos [index][3] .. ", " ..sos[index][4]) or "NULL, NULL, NULL, NULL") .. "}") -- sos[index][1] .. ", " .. sos[index][2] .. ", " .. sos [index][3] .. ", " ..sos[index][4]
		if year == nil or year == currentYear then
			if result[1] == nil then 
				result[1] = index
			end
			--mw.log("[" .. index .. "] Week " ..GetWeekNumber(currentWeekDate) .. ", Year: " .. os.date("%Y", currentWeekDate) .. ": {" .. sos[index][1] .. ", " .. sos[index][2] .. ", " .. sos[index][3] .. ", " .. sos[index][4] .. "} (" .. os.date("%d. %m. %Y",currentWeekDate) .. ")")
			result[2] = index
		end
		
		-------------------------------
		index = #sos - i -- INDEX SHIFT
		if sos[index] ~= nil and sos[index][5] ~= nil and sos[index][5].offset ~= nil then --need to reorder logic instructions
			currentWeekDate = currentWeekDate + (_week * (sos[index][5].offset + 1))
		else
			currentWeekDate = currentWeekDate + _week
		end
	end
	--mw.log(mw.dumpObject(result))
	if #result == 0 then return {0, 0} end --if pStart and pEnd is nil then return zero values
	return result
end

function ResolveYearParam(year)
	if type(year) == "table" and year.args[1] ~= nil then
		return tonumber(year.args[1])
	elseif type(year) == "number" then
		return year
	else
		return os.date("%Y")
	end
end

function SoSArchiveCalendar(year, pStart, pEnd)
	local currentWeekDate = os.time(_inception)
	local perkList = GetEmptyPerkTable()
	if pStart == nil or pEnd == nil then
		pStart, pEnd = unpack(GetIndexesOfPeriod(year)) --Period Start and Period End
	end
	local offset = 0
	local offset2016 = 0
	local notices = {}
	local week
	local color
	local index
	local text, header
	
	if year == 2016 then
		offset2016 = tonumber(os.date("%W", os.time(_inception))) - 1 --setting offset by 43 weeks
	end
	
	for i = pStart, pEnd, -1 do
		week = (pStart - i + 1 + offset2016)
		if sos[i][5] ~= nil and type(sos[i][5]) == "table" then
			offset = offset + (sos[i][5].offset or 0) --offset must be global because we need to shift the rest of all weeks as well
			color  = sos[i][5].color
			notices[week] = sos[i][5].notice
			text = sos[i][5].text
			header = sos[i][5].header
		else
			color = nil
		end
		for j, sosPerk in ipairs(sos[i]) do --sosPerk = individual perk in sos Week row, goes 4x - 5x
			if type(sosPerk) ~= "table" then
				if sosPerk ~= 0 then
					local occurenceIndex
					if perkList[sosPerk] == 0 then --sosPerk, the perk ID will be an index of perkList table. Due to Lua logic there must not be a nil between items (that's why there is getEmptyPerkTable())
						occurenceIndex = 1
						perkList[sosPerk] = {}
					else
						occurenceIndex = #perkList[sosPerk] + 1
					end
					
					local newOccurence = { --here insert data you want to be accessible while creating a calendar (+ initialize the variable above (#413))
						week = week + offset,
						color = color,
						text = text,
						header = header
					}
					
					perkList[sosPerk][occurenceIndex] = newOccurence
				end
			end
		end
	end
	return {perkList, notices} -- sorting: perkList[perks.id] gives you weeks of appropriate perk
end

function GetGlobalOffsetInYear(pStart, pEnd)
	local offset = 0
	for i = pStart, pEnd, -1 do
		if sos[i][5] ~= nil and type(sos[i][5]) == "table" then
			offset = offset + (sos[i][5].offset or 0)
		end
	end
	mw.log("Week Offset: " .. offset)
	return tonumber(offset)
end

function GetPerksInception(year)
	local charTable
	local dlcDate
	local weekOffset
	local result = GetEmptyPerkTable()
	for i, perk in ipairs(perks) do
		if perk.character ~= nil then --if Perk has associated character that means it's a unique perk
			if		perk.charType == 'S' then charTable = survivors
			elseif	perk.charType == 'K' then charTable = killers
			else	return -1
			end
			if charTable[perk.character].dlc ~= nil then
				dlcDate = utils.GetDatetime(dlcs[charTable[perk.character].dlc].rDate)
				if tonumber(year) == tonumber(dlcDate.year) then
					weekOffset = tonumber(os.date("%W", os.time({year = dlcDate.year, month = 1, day = 1}))) --check if the year starts with W0 or W1 - see #48 (documentation of GetWeekNumber())
					releaseWeek = tonumber(os.date("%W", os.time(dlcDate))) - weekOffset + 1 -- +1 because week indexing start at 0
					
					result[perk.id] = {week = releaseWeek, color = _inceptionColor, inception = true}
						
					--mw.log("Perk " .. perk.name .. " was released at week " .. releaseWeek .. "(+" .. weekOffset .. ")")
				end
			end
		end
	end
	return result
end

function mergePerkListWithInceptionList(perkList, perkInception)
	local merged = GetEmptyPerkTable()
	
	for i = 1, #perkList do --perkList as I would to keep dependency on the logic that's used when creating perkList variable due to potential later changes
		if perkInception[i] ~= 0 then
			if perkList[i] == 0 then
				perkList[i] = {perkInception[i]}
			else
				perkList[i][#perkList[i] + 1] = perkInception[i]
			end
		end
	end
	
	--mw.log(mw.dumpObject(perkList))
	return perkList
end

function ResolvePerkOccurence(perkOccurenceList)
	local result = 0
	for _, perkOcc in ipairs(perkOccurenceList) do
		if perkOcc.inception == true then
		else
			result = result + 1
		end
	end
	return result
end

function p.AssembleSoSCalendarTable(year)
	year = ResolveYearParam(year)
	local pStart, pEnd = unpack(GetIndexesOfPeriod(year))
	local perkList, weekNames = unpack(SoSArchiveCalendar(year, pStart, pEnd))
	local perkInception = GetPerksInception(year)
	local result = ""
	local currentWeekDate = 1
	local startWeekDate = 1
	local weekFound
	local hideable
	if year == 2016 then
		currentWeekDate = tonumber(os.date("%W", os.time(_inception)))
		startWeekDate = tonumber(os.date("%W", os.time(_inception)))
	end
	local globalOffset = GetGlobalOffsetInYear(pStart, pEnd)
	local lastWeekNumber = currentWeekDate + (pStart - pEnd + globalOffset)
	local numberOfWeeksInYear = pStart - pEnd + 1 + globalOffset
	
	if perkInception == -1 then return strings.wrongCharType end
	perkList = mergePerkListWithInceptionList(perkList, perkInception)
	
	result = result .. "<div id=\"inceptionPerks" .. year .."\" class=\"inceptionSwitch\"></div>" .. nl --Show/Hide Switch
	result = result .. "{| class=\"wikitable unsortable\"" .. nl
	result = result .. "! " .. strings.icon .." !! " .. strings.name .. " !! colspan = " .. numberOfWeeksInYear .. "| " .. strings.weeksOf .. " " .. year .. "!! " .. strings.shrineCount .. nl
	result = result .. ntl .. nl
	result = result .. "! colspan = 2" .. "| " .. nl
	--mw.log(mw.dumpObject(weekNames))
	
	for i = 1, numberOfWeeksInYear do -- Weeks Header
		if i ~= 1 then
			result = result .. " || class = \"week-cell\" | "
		else
			result = result .. "| class = \"week-cell\" | "
		end
		result = result ..  (weekNames[currentWeekDate] or currentWeekDate)
		currentWeekDate = currentWeekDate + 1
	end
	result = result .. nl .. "!" .. nl
	
	utils.sortItemsByName(perks)
	--mw.log("pStart: " .. pStart)
	--mw.log("pEnd: " .. pEnd)
	--mw.log("Number of Weeks (without weeks with offsets): " .. numberOfWeeksInYear)
	--mw.log(mw.dumpObject(sos[pStart]))
	--mw.log(mw.dumpObject(sos[pEnd]))
	--mw.log(lastWeekNumber)
	--mw.log(lastWeekNumber - (pStart - pEnd))
	--mw.log(43)
	for i, perk in ipairs(perks) do
		if perk.character ~= nil and perkList[perk.id] ~= 0 then
			for j, perkOcc in ipairs(perkList[perk.id]) do
				hideable = false
				if perkOcc.inception == true and (j == 1 and #perkList[perk.id] == 1) then
					hideable = true
					break
				end
			end
			result = result .. ntl
			if hideable then
				result = result .. " class=\"inception-row" .. year .. "\" style=\"display: none;\" " 
			end
			result = result .. nl .. "! [[" .. cstr.file .. strings.teachable .. " " .. utils.FirstLetterLower(utils.resolveFileName((perk.techName or perk.name))) .. ".png|32px]] !! " .. perk.name .. nl .. "|"
			
			for j = startWeekDate, lastWeekNumber do --going through week in year
				--j = week currently processed
				weekFound = false
				local titleText = ""
				local color = "white"
				local sameWeekCounter = 0
				for k, perkOcc in ipairs(perkList[perk.id]) do --perkOcc = Perk Occurrence
					--if perk.id == 63 and j == perkOcc.week then mw.log("Perk " .. perk.name .. ": " .. perk.id .. ", weekOcc:" .. perkOcc.week .. ", j: " .. j .. ", Text: " .. (perkOcc.text or "") .. "\n*****\n" .. mw.dumpObject(perkList[63]) .. "\n*****\n") end
					if perkOcc.week == j and not weekFound then
						sameWeekCounter = sameWeekCounter + 1
						color = (perkOcc.color or "white")
						titleText = strings.week .. " " .. perkOcc.week
						if perkOcc.header then
							titleText =  titleText .. " - " .. perkOcc.header
						end
						weekFound = true
						if perkOcc.inception then break end
					elseif perkOcc.week == j and weekFound then
						if not perkOcc.inception then
							sameWeekCounter = sameWeekCounter + 1
							titleText = titleText .. "&#010;" .. strings.week .. " " .. perkOcc.week
							if perkOcc.header then
								titleText = titleText .. " - " .. perkOcc.header
							end
						else
							color = perkOcc.color
						end
					end
				end
				color = frame:expandTemplate{title = "clr", args = {color}}
				
				if weekFound then
					local class = ""
					result = result .. "style=\"background-color: #" .. color .. "\"; "
					
					if sameWeekCounter > 1 then
						class = "class = \"multipleOccurenceSoSCalendar\" "
					else
						sameWeekCounter = ""	
					end
					result = result .. class .. "\" title = \"" .. titleText .. "\" | " .. sameWeekCounter --[[File:nothing.png]]
				end
				
				if j ~= lastWeekNumber then --if it's not occurence in last week then add delimeters
					result = result .. " ||"
				end
			end
			result = result .. nl .. "! " .. ResolvePerkOccurence(perkList[perks[i].id]) .. nl
		end
	end
	
	result = result .. "|}"
	
	--mw.log(result)
	return result
end

function p.AssembleSoSYearPage(year)
	year = ResolveYearParam(year)
	local pStart, pEnd = unpack(GetIndexesOfPeriod(year))
	local result = ""
	local currentWeekDate = 1
	local startWeekDate = 1
	local sosIndex = 0
	local header
	if year == 2016 then
		currentWeekDate = tonumber(os.date("%W", os.time(_inception))) --43
		startWeekDate = tonumber(os.date("%W", os.time(_inception))) --52
	end
	local currentOffset = 0
	local lastWeekNumber = currentWeekDate + (pStart - pEnd)

	if perkInception == -1 then return strings.wrongCharType end
	
	utils.sortItemsByName(perks)
	mw.log("pStart: " .. pStart)
	mw.log("pEnd: " .. pEnd)
	mw.log("lastWeekNumber: " .. lastWeekNumber)
	mw.log("lastWeekNumber CALC: " .. lastWeekNumber - (pStart - pEnd))
	mw.log("startWeekDate: " .. startWeekDate)
	for i = startWeekDate, lastWeekNumber do --going through week in year
		sosIndex = pStart + startWeekDate - i
		-- do return end
		if sosIndex > #sos or sosIndex < 1 then break end --If the index is actually higher than the number of elements in SoS table or the index is below 0
		if sos[sosIndex][5] ~= nil then --If there's a table after 4 perks then retrieve data
			if sos[sosIndex][5].offset ~= nil then
				currentOffset = currentOffset + sos[sosIndex][5].offset --the number itself is a negative value, thus a +
			end
			
			if sos[sosIndex][5].header ~= nil then
				header = sos[sosIndex][5].header
			else
				header = strings.week .. space .. (i + currentOffset)
			end
			
			text = sos[sosIndex][5].text or cstr.empty
		else
			header = strings.week .. space .. (i + currentOffset)
			text = cstr.empty
		end
		--result = sos[sosIndex][1] .. ", " .. sos[sosIndex][2] .. ", " .. sos[sosIndex][3] .. ", " .. sos[sosIndex][4] .. nl .. nl .. result
		--result = ("i: " .. i .. "| Index: " .. sosIndex .. "| lastWeekNumber - currentOffset: " .. lastWeekNumber - currentOffset) .. nl .. result
		result = SoS(sosIndex) .. nl .. nl .. result
		result = text .. nl .. result
		result = "== " .. header .. " ==" ..nl .. result

	end
	
	mw.log(result)
	return result
end

return p