Module:ECR

--[=[ -- LUA script to get Enchanted Chests Rewards -- --]=]

local p = {}

local availableData = mw.loadData( 'Module:Available/data' ) local cData = mw.loadData( 'Module:ItemCollection/data' ) ---[==[ For testing purposes local chestData = mw.loadData( 'Module:ECR/data' ) --[===[]==] local chestData = { ["Legendary"] = { ["Pinocchio"] = { ["C"] = "EC-Gems #60$EC-Gems #120^x3", ["R"] = { ["Common"] = "EC-Magic #50-613 $ Jiminy Cricket $ Figaro $ Geppetto's Workshop", ["Uncommon"] = "EC-Magic #100-1,225 $ Geppetto $ Blue Fairy $ Pinocchio Village Haus $ Jiminy Cricket's Hat Stand", ["Rare"] = "EC-Magic #150-1,838 $ Honest John $ Stromboli's Caravan", ["Epic"] = "Stromboli $ Pinocchio's Daring Journey $ Pinocchio's Hat Stand", ["Legendary"] = "Pinocchio", },		},	}, 	["Radiant"] = {true, ["THOND Event"] = { ["N"] = "", ["D"] = {"2022/12/28", 18}, ["C"] = "EC-Gems #20$Real Money^x6", ["R"] = { ["Tokens"] = {"Phoebus$Djali$Claude Frollo$Esmeralda$Quasimodo"}, ["Common"] = "EC-THOND #200 $ EC-Magic #100-700 $ IP-THOND #5", ["Uncommon"] = "EC-Magic #200-1,400", ["Rare"] = "EC-Magic #500-3,500", },		},	}, } --]===]

local util = require('Module:Utility') local RARITY = require("Module:Rarity").rarity local oneItem = require("Module:MultiItems").getOneItem local EC = require("Module:EC").getEC local TOK = require("Module:CharacterToken") local CHEST = require("Module:EnchantedChest").getChest local COLL = require("Module:ItemCollection").getCollection local date = require("Dev:Date") local today = os.date("%Y/%m/%d %H:%M:%S")

local bubbles = {}

local function addItem(data) local TokenData = {} TokenData["unknown"] = data["Unknown"] or "" TokenData["common"] = data["Common"] or "" TokenData["uncommon"] = data["Uncommon"] or "" TokenData["rare"] = data["Rare"] or "" TokenData["epic"] = data["Epic"] or "" TokenData["legendary"] = data["Legendary"] or ""

local raTok = "" local rbTok = ""

if data["Tokens"] and data["Tokens"][1] then for tCh in mw.text.gsplit(data["Tokens"][1], "%s*$%s*") do raTok = TOK.getTokenDirect((tCh .. ",2"), "R", "") rbTok = TOK.getTokenDirect((tCh .. ",3"), "R", "")

TokenData[raTok] = TokenData[raTok] .. "$" .. tCh .. ",2 #" .. (data["Tokens"][raTok] or "1") TokenData[rbTok] = TokenData[rbTok] .. "$" .. tCh .. ",3 #" .. (data["Tokens"][rbTok] or "1") end end

local tRarity = {} table.insert(tRarity, {"Legendary", TokenData["legendary"]}) table.insert(tRarity, {"Epic", TokenData["epic"]}) table.insert(tRarity, {"Rare", TokenData["rare"]}) table.insert(tRarity, {"Uncommon", TokenData["uncommon"]}) table.insert(tRarity, {"Common", TokenData["common"]}) table.insert(tRarity, {"Unknown", TokenData["unknown"]})

return tRarity end

local function chItems(inStr) local tIn = mw.text.split(inStr, "%s*%$%s*") local tOut = {} for idx = 1, #tIn do		local tt = mw.text.split(tIn[idx], "%s*#%s*") if tt[1] ~= "" then if not tt[2] or tt[2] == "" then tt[2] = 1 end table.insert(tOut, tt) end end return tOut end

local function colItem(iNumb, tNumb, aNumb, item) local tOut = {}

if iNumb == 1 then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, '\n| colspan="2"|') elseif iNumb == 2 then if aNumb == (tNumb - 1) then table.insert(tOut, '\n|\n| colspan="2"|') table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) elseif aNumb == tNumb then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) table.insert(tOut, '\n| colspan="2"|\n|') end elseif iNumb == 3 then if aNumb == (tNumb - 2) then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) elseif aNumb == (tNumb - 1) then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) elseif aNumb == tNumb then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) table.insert(tOut, '\n| colspan="2"|') end elseif iNumb == 4 then if aNumb == (tNumb - 3) then table.insert(tOut, '\n|\n| colspan="2"|') table.insert(tOut, item) elseif aNumb == (tNumb - 2) then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) elseif aNumb == (tNumb - 1) then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) elseif aNumb == tNumb then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, item) table.insert(tOut, '\n|') end end

return table.concat(tOut) end

local function allRarity(data, special) local tOut = {} local rData = addItem(data)

for cNumb, item in ipairs(rData) do		if item[2] ~= "" then table.insert(tOut, '\n|-\n! colspan="10" style="padding: 5px;"|') table.insert(tOut, RARITY({item[1], "ECR"}))

local tItems = {} tItems = chItems(item[2]) local tNo = #tItems local rNo = tNo%5 local iNo = math.floor(tNo/5)

local br = 1 for i, rData in ipairs(tItems) do				if i == br then table.insert(tOut, '\n|-') br = br + 5 end if i <= (iNo * 5) then table.insert(tOut, '\n| colspan="2"|') table.insert(tOut, oneItem(rData[1], rData[2], nil, true)) else table.insert(tOut, colItem(rNo, tNo, i, oneItem(rData[1], rData[2], nil, true))) end

if special then if cData["Items"][rData[1]] and cData["Items"][rData[1]][2] and cData["Items"][rData[1]][2] == "ch" then table.insert(bubbles, {cNumb*0.1, 1, "specialchance", rData[1]}) elseif cData["Items"][rData[1]] and cData["Items"][rData[1]][2] and cData["Items"][rData[1]][2] == "ba" then table.insert(bubbles, {cNumb*0.1, 2, "specialchance", rData[1]}) elseif cData["Items"][rData[1]] and cData["Items"][rData[1]][2] and cData["Items"][rData[1]][2] == "bc" then table.insert(bubbles, {cNumb*0.1, 3, "specialchance", rData[1]}) elseif cData["Items"][rData[1]] and cData["Items"][rData[1]][2] and cData["Items"][rData[1]][2] == "d" then table.insert(bubbles, {cNumb*0.1, 4, "specialchance", rData[1]}) elseif rData[1]:match("^EC") then table.insert(bubbles, {cNumb*0.1, 6, "specialchance", rData[1]}) else table.insert(bubbles, {cNumb*0.1, 5, "specialchance", rData[1]}) end else if cData["Items"][rData[1]] and cData["Items"][rData[1]][2] and cData["Items"][rData[1]][2] == "ch" then table.insert(bubbles, {cNumb, 1, item[1]:lower, rData[1]}) elseif cData["Items"][rData[1]] and cData["Items"][rData[1]][2] and cData["Items"][rData[1]][2] == "ba" then table.insert(bubbles, {cNumb, 2, item[1]:lower, rData[1]}) elseif cData["Items"][rData[1]] and cData["Items"][rData[1]][2] and cData["Items"][rData[1]][2] == "bc" then table.insert(bubbles, {cNumb, 3, item[1]:lower, rData[1]}) elseif cData["Items"][rData[1]] and cData["Items"][rData[1]][2] and cData["Items"][rData[1]][2] == "d" then table.insert(bubbles, {cNumb, 4, item[1]:lower, rData[1]}) elseif rData[1]:match("^EC") then table.insert(bubbles, {cNumb, 6, item[1]:lower, rData[1]}) else table.insert(bubbles, {cNumb, 5, item[1]:lower, rData[1]}) end end end end end

return table.concat(tOut) end

local function getPrizeTable(ecData, sName, sArgs) local tTable = {'{| class="dmk-chests', "", '" style="text-align: center; line-height: 1.0; width: 100%;', ' background: #b3b4c112; border-radius: 20px; margin: 1em 1em 1em 0;', '"\n', '!', "", ' colspan="10" style="background: linear-gradient(#14bfe4 5%,#2866ce 100%); border-radius: 20px 20px 0 0; height: 35px; color: white; text-shadow: 1px 2px 3px #030d9d; padding: 5px;"| Possible Rewards You can receive the following rewards.\n|- style="height: 0px;"|\n||||||||||||||||||||'} if sName then tTable[2] = ' mw-collapsible mw-collapsed" id="mw-customcollapsible-' .. sName:gsub(" ", "_") tTable[4] = ' display: unset;' tTable[7] = ' id="' .. sName .. '"' end

if ecData["S"] then table.insert(tTable, '\n|-\n! colspan="10"|⸺⸺⸺ Only at ') table.insert(tTable, (ecData["S"][1] or "?")) table.insert(tTable, '% Special Chance  ⸺⸺⸺ ') table.insert(tTable, allRarity(ecData["S"], true)) table.insert(tTable, '\n|-\n! colspan="10"|⸺⸺⸺⸺ ⸺⸺⸺⸺ ') end

if ecData["R"] then table.insert(tTable, allRarity(ecData["R"])) end

if sArgs then table.insert(tTable, '\n|-\n|colspan="10" style="line-height: 1.75; text-align: left;"|') table.insert(tTable, sArgs) end

table.insert(tTable, '\n|}\n')

return tTable end

function p.getPrizeTable(ecData) return table.concat(getPrizeTable(ecData)) end

local function getBubbles(legendary) table.sort(bubbles, function(a,b)			if a[1] == b[1] then				return a[2] < b[2]			else				return a[1] < b[1]			end		end)

local tOut = {} local k = 1

for _, v in ipairs(bubbles) do		if legendary then if k == 1 then table.insert(tOut, (' ')) k = k + 1 elseif k == 2 and v[3] ~= "specialchance" then table.insert(tOut, (' ')) break end else if k == 1 then table.insert(tOut, (' ')) k = k + 1 elseif k == 2 and v[3] ~= "specialchance" then table.insert(tOut, (' ')) k = k + 1 elseif k == 3 and v[3] ~= "specialchance" then table.insert(tOut, (' ')) if bubbles[#bubbles-1][4] ~= v[4] then table.insert(tOut, (' ')) end if bubbles[#bubbles][4] ~= v[4] and bubbles[#bubbles][4] ~= bubbles[#bubbles-1][4] then table.insert(tOut, (' ')) end break end end end

return table.concat(tOut) end

local function getCost(costData, cardFormat) local tOut = {}

for costItem in mw.text.gsplit(costData, "%s*$%s*") do		local costName, costNumb = mw.ustring.match(costItem, "^(.-)%s*^%s*(.-)$") if not costName then costName = costItem end

if costName:match("^EC-") then local curName, curNumb = mw.ustring.match(costName, "^([^,]-)%s*#%s*(.-)$") if not curName then curName = costName end if not curNumb then curNumb = "1" end

local cNumb, sNumb = mw.ustring.match(curNumb, "^([^,]-)%s*-%s*(.-)$") if not cNumb then cNumb = count end

if sNumb then cNumb = tonumber((string.gsub(cNumb or "", "[,]", ""))) sNumb = tonumber((string.gsub(sNumb or "", "[,]", "")))

if cardFormat then table.insert(tOut, " ") end table.insert(tOut, EC({(curName .. " #" .. util.th_comma(sNumb)), nil, nil, nil, 30})) if cardFormat then table.insert(tOut, " ") end table.insert(tOut, ' ') table.insert(tOut, util.th_comma(cNumb)) table.insert(tOut, ' (-')				table.insert(tOut, (100-(string.format("%.2f", (sNumb/cNumb))*100)))				table.insert(tOut, '%) ') else if cardFormat then table.insert(tOut, " ") end table.insert(tOut, EC({costName, nil, nil, nil, 30})) if cardFormat then table.insert(tOut, " ") end end else table.insert(tOut, costName) end table.insert(tOut, (costNumb and (" (" .. costNumb .. ") ") or " ")) end

return table.concat(tOut) end

function p.getECR(frame) local tArgs = util.getArgs(frame)

local pagename = tArgs[1] or mw.title.getCurrentTitle.baseText local cName = mw.ustring.gsub(pagename, " Chests", "") local tOut = {} local cSection = {} local allcoll = "" if chestData[cName] then for k, v in pairs(chestData[cName]) do			if v ~= true then local aData = (v["D"] or {"2016/01/01", 0}) if availableData[cName] and availableData[cName][k] then aData = availableData[cName][k] end

local unlockdate = aData[1] .. util.dayStart local lockdate = date(aData[1]):adddays(aData[2]):fmt("%Y/%m/%d") .. (aData[3] or util.dayStart)

local cDur = nil if cName == "Legendary" then local cNumb = k				 	if k:match("^The .*$") then cNumb = k:match("^The (.*)$") end if unlockdate <= today and today < lockdate then lockdate = "1 " .. cNumb else lockdate = cNumb end cDur = util.strDate(aData[1], aData[2]) elseif aData[2] == 0 then lockdate = date(aData[1]):adddays(1):fmt("%Y/%m/%d") .. (aData[3] or util.dayStart) elseif unlockdate <= today then cDur = util.strDate(aData[1], aData[2]) end table.insert(cSection, {lockdate, k, v, cDur, unlockdate, (aData["C"] or v["C"]), aData["L"]}) end end

if cName == "Legendary" then table.sort(cSection, function(a,b) return a[1] < b[1] end) else table.sort(cSection, function(a,b) return a[1] > b[1] end) end

for _, cItem in pairs(cSection) do			if chestData[cName][1] and (cItem[5] >= today) then table.insert(tOut, "") else bubbles = {} local tTable = getPrizeTable(cItem[3], cItem[2], tArgs[cItem[2]]) local tCard = {'{| class="chestcard ', "default", '"\n', '| class="Part_1"|', "", '\n', '| class="Part_2"|', "", '\n', '|-\n| colspan="2" class="Part_3"| ', CHEST({cName .. "-" .. cItem[2], 100}), getBubbles, '  \n', '|-\n| colspan="2" class="Part_4"| ', (cItem[3]["N"] or cItem[2]), ' \n', '|-\n| colspan="2" class="Part_5"| \n', '|-\n| colspan="2" class="Part_6"|', "", '\n|}\n'}

if cName == "Special Request Wishes" then tCard[11] = '' end

if cItem[6] then tCard[20] = '' .. getCost(cItem[6], true) .. ' '				end

if cName == "Legendary" then tCard[2] = COLL({cItem[2], "S"}):lower tCard[8] = COLL({cItem[2], 35}) tCard[11] = "" tCard[12] = getBubbles(true) allcoll = allcoll .. "$" .. cItem[2] if cItem[7] then cItem[4] = "Limited Time Content ( Last Time in Bundle: " .. cItem[4] .. ") " else cItem[4] = "Permanent Content ( Last Time in Bundle: " .. cItem[4] .. ") " end elseif cItem[5] <= today and today <= cItem[1] then cItem[4] = util.countdown(cItem[1], " for ", " until ", true) elseif cItem[5] >= today then cItem[4] = ": " .. util.countdown(cItem[5], " in ", " on ") end

if cItem[4] then tCard[23] = ' ' end

table.insert(tOut, table.concat(tCard)) table.insert(tOut, table.concat(tTable)) end end end

if allcoll ~= "" then table.insert(tOut, 1, (COLL({allcoll, "A"}) .. " \n")) end

return frame:preprocess(table.concat(tOut)) end

local function findInChest(pagename, data, category) local tOut = nil local tokenpage = pagename:gsub(" Token$", "") or ""

if (data["NoTokens"] and not data["NoTokens"]:match(tokenpage)) or not data["NoTokens"] then for _, item in pairs(addItem(data)) do			if item[2] ~= "" then for i, iData in ipairs(chItems(item[2])) do					local iName = iData[1]

if iName:match("^EC") then iName = EC({iName, "T"}) elseif not category and not cData.Items[iName] then iName = TOK.getTokenDirect(iName, "T") end

if pagename == iName then tOut = iData[2] end end end end end

return tOut end

function p.getTokenFormat(tOut, name) local pagename = name or mw.title.getCurrentTitle.text local tChests = {}

for cName, chest in pairs(chestData) do		for n, v in pairs(chest) do			if v ~= true then local dateData = v["D"] or {"2016/01/01", 0} if availableData[cName] and availableData[cName][n] then dateData = availableData[cName][n] end local UnlockDate = dateData[1] .. util.dayStart local LockDate = date(dateData[1]):adddays(dateData[2]):fmt("%Y/%m/%d") .. (dateData[3] or util.dayStart)

if UnlockDate < today and (dateData[2]==0 or today < LockDate) then table.insert(tChests, {cName, n, findInChest(pagename, v["R"]), nil, (dateData[2]~=0 and LockDate)}) if v["S"] then table.insert(tChests, {cName, n, findInChest(pagename, v["S"]), true, (dateData[2]~=0 and LockDate)}) end

if not pagename:match("^.+ Blueprint Token$") and not pagename:match("^.+ Elixir Ingot Token$") and not pagename:match("^Time Skip Token$") then local pRarity = TOK.tokenType({pagename, "I"}) --Type

if pRarity ~= "collection" and pRarity ~= "npc" then pRarity = TOK.tokenType({pagename}) --Rarity end

pRarity = string.upper(string.sub(pRarity, 1, 1)) .. string.sub(pRarity, 2) if pagename:match("^.+ Relic Token$") then pRarity = "Relic " .. pRarity end

table.insert(tChests, {cName, n, findInChest(pRarity, v["R"], true), nil, (dateData[2]~=0 and LockDate)}) if v["S"] then table.insert(tChests, {cName, n, findInChest(pRarity, v["S"], true), true, (dateData[2]~=0 and LockDate)}) end end end end end end

for k, v in pairs(tChests) do		if v[3] then tOut[v[1] .. "-" .. v[2] .. " Chests"] = "$ $ x" .. v[3] .. " $ $ $ " .. (v[4] and "Special Chance Only" or "") .. " $ " .. (v[5] or "") end end

return tOut end

function p.getDATA(pagename) local tChest = {}

for cName, chest in pairs(chestData) do		for n, v in pairs(chest) do			if v ~= true then local aData = (v["D"] or {"2016/01/01", 0}) if availableData[cName] and availableData[cName][n] then aData = availableData[cName][n] end local LockDate = date(aData[1]):adddays(aData[2]):fmt("%Y/%m/%d") .. (aData[3] or util.dayStart) if cName == "Legendary" and ((LockDate < today) or ((aData[1] .. util.dayStart) > today)) and not aData["L"] then aData = {"2016/01/01", 0} LockDate = aData[1] .. util.dayStart end

if (LockDate > today or aData[2] == 0) then if v["R"] then local tRarity = addItem(v["R"]) for _, item in pairs(tRarity) do							if item[2] ~= "" then item[2] = chItems(item[2]) for _, rData in ipairs(item[2]) do									if pagename == rData[1] then table.insert(tChest, {rData[1], aData[1], aData[2], (aData[3] or util.dayStart), {(cName .. " Chests"), n, ((cName=="Legendary" and n or cName) .. " Chests")}}) end end end end end if v["S"] then local tRarity = addItem(v["S"]) for _, item in pairs(tRarity) do							if item[2] ~= "" then item[2] = chItems(item[2]) for _, rData in ipairs(item[2]) do									if pagename == rData[1] then table.insert(tChest, {rData[1], aData[1], aData[2], (aData[3] or util.dayStart), {(cName .. " Chests"), n, ((cName=="Legendary" and n or cName) .. " Chests")}}) end end end end end end end end end

return tChest end

function p.availability(frame) local VL = mw.ext.VariablesLua local tArgs = util.getArgs(frame) local pagename = tArgs[1] or mw.title.getCurrentTitle.text pagename = mw.ustring.gsub(pagename, " Chests", "") or ""

local tItem = {} local space = "" local tAv = {} local lastCost = ""

for cName, chest in pairs(chestData) do		if (pagename=="All" or cName==pagename) and cName~="Special Request Wishes" then for n, v in pairs(chest) do				if v ~= true then local dateData = v["D"] or {} if availableData[cName] and availableData[cName][n] then dateData = availableData[cName][n] end table.insert(tItem, {n, dateData[1], dateData[2], (dateData[3] or util.dayStart), (pagename=="All" and (cName .. " Chests")), (dateData["C"] or v["C"] or "")}) end end end end

table.sort(tItem, function(a,b) return (date(a[2]):adddays(a[3]):fmt("%Y/%m/%d")) < (date(b[2]):adddays(b[3]):fmt("%Y/%m/%d")) end)

for _, v in pairs(tItem) do local UnlockDate = v[2] .. util.dayStart local LockDate = date(v[2]):adddays(v[3]):fmt("%Y/%m/%d") .. v[4]

if today <= UnlockDate then table.insert(tAv, space) table.insert(tAv, "")			table.insert(tAv, v[5] or v[1])			table.insert(tAv, ":  : ") table.insert(tAv, util.countdown(UnlockDate, " in ", " on ")) space = " " elseif v[3] == 0 then lastCost = getCost(v[6]) table.insert(tAv, space) table.insert(tAv, "")			table.insert(tAv, v[5] or v[1])			table.insert(tAv, ":  : Currently Available ") space = " " elseif today <= LockDate then lastCost = getCost(v[6]) table.insert(tAv, space) table.insert(tAv, "")			table.insert(tAv, v[5] or v[1])			table.insert(tAv, ":  : ") table.insert(tAv, util.countdown(LockDate, " for ", " until ")) space = " " end end

if space == " " then VL.vardefine("availability", table.concat(tAv)) VL.vardefine("cost", lastCost) else VL.vardefine("availability", ("" .. pagename .. " Chests:  : Not Currently Available")) VL.vardefine("cost", "") end

return (pagename=="All" and VL.var("availability") or "") end

return p