Editing Module:LoRUtility

Jump to navigation Jump to search
Warning: You are not logged in. Your IP address will be publicly visible if you make any edits. If you log in or create an account, your edits will be attributed to your username, along with other benefits.

Always explain the reason in the edit summary rather than using only the default message, unless you are undoing vandalism.

Latest revision Your text
Line 1: Line 1:
-- <pre>
-- <pre>
-- Inherit from https://github.com/SwitchbladeBot/runeterra


local lib = require('Module:Feature')
local lib = require('Module:Feature')
local MAX_KNOWN_VERSION = 5
local MAX_KNOWN_VERSION = 2
local p = {}
local p = {}
local VarInt = {}
local VarInt = {}
Line 16: Line 17:
[6] = {code = "SI", name = "Shadow Isles"},
[6] = {code = "SI", name = "Shadow Isles"},
[7] = {code = "BW", name = "Bilgewater"},
[7] = {code = "BW", name = "Bilgewater"},
[8] = {code = "SH", name = "Shurima"},
[10] = {code = "MT", name = "Targon"}
[10] = {code = "MT", name = "Targon"},
[11] = {code = "BC", name = "Bandle City"},
[13] = {code = "RU", name = "Runeterra"}
}
}

--To test debug this line mw.executeFunction(p.test)
function p.test(frame)
output = p.adventureRegions{"RUIODE--"}
mw.log(output)
end


function base32_decode(str)
function base32_decode(str)
Line 55: Line 47:


function p.deckDataFromCode(frame)
function p.deckDataFromCode(frame)
local args = lib.frameArguments(frame)
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
local lorData = mw.loadData("Module:LoRData/data")
local lorData = mw.loadData("Module:LoRData/data")
Line 61: Line 53:
local firstByte = bytes[1]
local firstByte = bytes[1]
local deckList = {}
local deckList = {}

table.remove(bytes, 1)
table.remove(bytes, 1)
local version = BitOperator.AND(tonumber(firstByte), 0xF)
local version = BitOperator.AND(tonumber(firstByte), 0xF)
Line 73: Line 65:
local followerCount = 0
local followerCount = 0
local spellCount = 0
local spellCount = 0
local landmarkCount = 0
local equipmentCount = 0
local rarities = {}
local rarities = {}
local champions = {}
local champions = {}
Line 86: Line 76:
local topChampion = nil
local topChampion = nil
local topFollower = nil
local topFollower = nil
local runeterranChampions = {}
local allCards = {}
function handleCardData(cardData, count, cardCode, regionName)
function handleCardData(cardData, count, cardCode, regionName)
Line 94: Line 82:
if cardData.supertype ~= nil and cardData.supertype == "Champion" then
if cardData.supertype ~= nil and cardData.supertype == "Champion" then
cardType = "Champion"
cardType = "Champion"
if regionName == "Runeterra" then
table.insert(runeterranChampions,cardData.name)
end
else
else
cardType = "Follower"
cardType = "Follower"
Line 102: Line 87:
end
end
table.insert(allCards,{code=cardCode, count=count, regionName=regionName})
regions[regionName] = (regions[regionName] or 0) + count
if args['detail'] then
if args['detail'] then
totalShards = totalShards + shardValues[cardData.rarity] * count
totalShards = totalShards + shardValues[cardData.rarity] * count
Line 139: Line 122:
followerCount = followerCount + count
followerCount = followerCount + count
end
end
elseif cardType == "Spell" then
else
spellCount = spellCount + count
spellCount = spellCount + count
elseif cardType == "Landmark" then
landmarkCount = landmarkCount + count
elseif cardType == "Equipment" then
equipmentCount = equipmentCount + count
end
end
regions[regionName] = (regions[regionName] or 0) + count
else
else
table.insert(
table.insert(
Line 161: Line 141:
end
end
for i = 3, 1, -1 do
for i = 3, 0, -1 do
local numGroupOfs = tonumber(VarInt.Pop(bytes)) or 0
local numGroupOfs = tonumber(VarInt.Pop(bytes)) or 0
for j = 1, numGroupOfs, 1 do
for j = 1, numGroupOfs, 1 do
Line 185: Line 165:
end
end
end
end

--For cards with over 3 copies
while true do
local count = tonumber(VarInt.Pop(bytes)) or nil
local set = VarInt.Pop(bytes)
local region = VarInt.Pop(bytes)
local card = VarInt.Pop(bytes)
if not count or not set or not region or not card then
break --end of stream
end
local setString = Utility.padLeft(tostring(set), 2, "0")
local regionData = REGIONS[region + 1]
local cardString = Utility.padLeft(tostring(card), 3, "0")
local cardCode = setString .. regionData.code .. cardString
if (not lorData[cardCode]) then
return 'Card Code "' .. cardCode .. '" does not exist'
end
handleCardData(lorData[cardCode], count, cardCode, regionData.name)
end
while #bytes > 0 do
while #bytes > 0 do
local fourPlusCount = VarInt.Pop(bytes)
local fourPlusCount = VarInt.Pop(bytes)
Line 226: Line 183:


if (not lorData[cardCode]) then
if (not lorData[cardCode]) then
return 'Card Code "' .. cardCode .. '" does not exist'
return 'Card Code "' .. cardCode .. '" is not exist'
end
end
handleCardData(lorData[cardCode], fourPlusCount, cardCode, regionData.name)
handleCardData(lorData[cardCode], fourPlusNumber, cardCode, regionData.name)
end
end
local multiregion = {}
if args['detail'] then
if args['detail'] then
for _, champion in ipairs(runeterranChampions) do
for _, data in ipairs(allCards) do
if p.isFromRuneterran{data.code,champion} then
regions["Runeterra"] = (regions["Runeterra"] or 0) + data.count
regions[data.regionName] = (regions[data.regionName] or 0) - data.count
data.regionName = "Runeterra"
end
end
end
for _, data in ipairs(allCards) do
if data.regionName ~= "Runeterra" and lorData[data.code].categoryRefs and lorData[data.code].regions then
for _,ref in ipairs(lorData[data.code].categoryRefs) do
if ref == "Multi-region" then
regions[data.regionName] = (regions[data.regionName] or 0) - data.count
local region1 = data.regionName
local region2 = nil
for _,region in ipairs(lorData[data.code].regions) do
if region1 ~= region then
region2 = region
break
end
end
table.insert(multiregion,{
count=data.count,
region1=region1,
region2=region2
})
break
end
end
end
end
for _,data in pairs(multiregion) do
if not data.region2 or (regions[data.region1] and regions[data.region1] > 0) then
regions[data.region1] = (regions[data.region1] or 0) + data.count
elseif regions[data.region2] and regions[data.region2] > 0 then
regions[data.region2] = (regions[data.region2] or 0) + data.count
else
regions[data.region1] = (regions[data.region1] or 0) + data.count
end
end
for region, count in pairs(regions) do
if count <= 0 then
regions[region] = nil
end
end
return {
return {
shards = totalShards,
shards = totalShards,
Line 287: Line 197:
followerCount = followerCount,
followerCount = followerCount,
spellCount = spellCount,
spellCount = spellCount,
landmarkCount = landmarkCount,
equipmentCount = equipmentCount,
rarities = rarities
rarities = rarities
}
}
else
else
for _, champion in ipairs(runeterranChampions) do
for _, data in ipairs(deckList) do
if p.isFromRuneterran{data.code,champion} then
data.region = "Runeterra"
end
end
end
for _, data in ipairs(allCards) do
if lorData[data.code].categoryRefs and lorData[data.code].regions then
for _,ref in ipairs(lorData[data.code].categoryRefs) do
if ref == "Multi-region" then
regions[data.regionName] = (regions[data.regionName] or 0) - data.count
break
end
end
end
end
for _, data in ipairs(deckList) do
if data.region ~= "Runeterra" and lorData[data.code].categoryRefs and lorData[data.code].regions then
for _,ref in ipairs(lorData[data.code].categoryRefs) do
if ref == "Multi-region" then
local region1 = data.region
local region2 = nil
for _,region in ipairs(lorData[data.code].regions) do
if region1 ~= region then
region2 = region
break
end
end
if not region2 or (regions[region1] and regions[region1] > 0) then
data.region = region1
elseif regions[region2] and regions[region2] > 0 then
data.region = region2
else
data.region = region1
end
break
end
end
end
end
return deckList
return deckList
end
end
end

function p.isFromRuneterran(frame)
local args = lib.frameArguments(frame)
local lorData = require("Module:LoRData/data")
local cardCode = args['code'] or args[1] or nil
local region = args['region'] or args['champion'] or args[2] or nil
if not cardCode or not region or not lorData[cardCode] then
return false
end
local card = lorData[cardCode]
if card.supertype == "Champion" then
return false
end
if region == "Aatrox" and card.subtype then
for _, subtype in ipairs(card.subtype) do
if subtype == "Darkin" then
return true
end
end
elseif region == "Bard" then
local CHIME_CARDS = { ["06BC011"] = true, ["06BC026"] = true, ["06BC031"] = true,
["06BC032"] = true, ["06BC044"] = true, ["06MT029"] = true, ["06MT047"] = true,
["08BC005"] = true, ["08SI021"] = true
}
if CHIME_CARDS[cardCode] then return true end
elseif region == "Elder Dragon" then
if card.cost >= 6 then return true end
elseif region == "Evelynn" and card.categoryRefs then
for _, ref in ipairs(card.categoryRefs) do
if ref == "Husk-generating" then
return true
end
end
elseif region == "Jax" and card.subtype then
for _, subtype in ipairs(card.subtype) do
if subtype == "Weaponmaster" then
return true
end
end
elseif region == "Jhin" and card.keywordRefs then
for _, ref in ipairs(card.keywordRefs) do
if ref == "Skill-generating" then
return true
end
end
elseif (region == "Kayn" or region == "Varus") and card.subtype then
for _, subtype in ipairs(card.subtype) do
if subtype == "Cultist" then
return true
end
end
elseif region == "Neeko" and card.subtype then
local SUBTYPES = { ["Bird"] = true, ["Cat"] = true, ["Dog"] = true,
["Elnuk"] = true, ["Fae"] = true, ["Reptile"] = true, ["Spider"] = true
}
for _, subtype in ipairs(card.subtype) do
if SUBTYPES[subtype] then
return true
end
end
elseif region == "Ryze" and card.type == "Spell" and card.keywords then
for _, keyword in ipairs(card.keywords) do
if keyword == "Burst" or keyword == "Focus" then
return true
end
end
elseif region == "The Poro King" then
local PORO_CARDS = { ["01FR016"] = true, ["01FR025"] = true, ["02FR003"] = true,
["03FR018"] = true, ["03PZ018"] = true, ["06BC043"] = true, ["09FR009"] = true,
["99FR001"] = true, ["99FR002"] = true, ["99PZ118"] = true
}
if PORO_CARDS[cardCode] then return true end
if card.subtype then
for _, subtype in ipairs(card.subtype) do
if subtype == "Poro" then
return true
end
end
end
end
return false
end

function p.adventureRegions(frame)
local args = lib.frameArguments(frame)
local str = args[1] or nil
local size = args["size"] or args[2] or "20px"
local sep = args["sep"] or "&nbsp;&nbsp;"
if not str then return nil end -- Exit if no input
local result = {}
local REGION_CODES = {
DE = "Demacia",
FR = "Freljord",
IO = "Ionia",
NX = "Noxus",
PZ = "Piltover and Zaun",
SI = "Shadow Isles",
BW = "Bilgewater",
SH = "Shurima",
MT = "Targon",
BC = "Bandle City",
RU = "Runeterra"
}
for i = 1, #str, 2 do
local pair = str:sub(i, i + 1):upper()
mw.log(pair)
local region = REGION_CODES[pair] or "Neutral"
table.insert(result, "[[File: " .. region .. " LoR Region.png|" .. size .. "|link=]]")
end
return table.concat(result, sep)
end

function p.adventureRewards(frame)
local args = lib.frameArguments(frame)
local step = args["step"] or "5"
step = tonumber(step)
if not step then
return "Step Error."
end
local base_start = "<center><table style=\"border-collapse: collapse;\"><tr>"
local base_end = "</tr></table></center>"
local r = ""
local count = 0
for i, a in ipairs(args) do
count = i
end
local rows = math.ceil(count/step)
local index_lastrow = ((rows-1)*step)+1
for i, a in ipairs(args) do
if i % step == 1 then
if i ~= 1 then
r = r .. base_end
end
r = r .. base_start
if i < index_lastrow then
r = r .. "<td style=\"text-align: center; padding: 5px; border-right: 1px solid #3e4452; border-left: 1px solid #3e4452; border-bottom: 1px solid #3e4452;\"> "
else
r = r .. "<td style=\"text-align: center; padding: 5px; border-right: 1px solid #3e4452; border-left: 1px solid #3e4452;\"> "
end
else
if i < index_lastrow then
r = r .. "<td style=\"text-align: center; padding: 5px; border-right: 1px solid #3e4452; border-bottom: 1px solid #3e4452;\"> "
else
r = r .. "<td style=\"text-align: center; padding: 5px; border-right: 1px solid #3e4452;\"> "
end
end
r = r .. args[i] .. "</td>"
end
r = r .. base_end
return frame:preprocess(r)
end
end


function p.headerDeck(frame)
function p.headerDeck(frame)
local args = lib.frameArguments(frame)
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
local builder = require("Module:SimpleHTMLBuilder")
args['name'] = args['name'] or 'Untitled Deck'
args['name'] = args['name'] or 'Untitled Deck'
Line 522: Line 226:
local followerCount = deckDetail['followerCount'] or nil
local followerCount = deckDetail['followerCount'] or nil
local spellCount = deckDetail['spellCount'] or nil
local spellCount = deckDetail['spellCount'] or nil
local landmarkCount = deckDetail['landmarkCount'] or nil
local equipmentCount = deckDetail['equipmentCount'] or nil
local rarities = deckDetail['rarities'] or nil
local rarities = deckDetail['rarities'] or nil
local template = builder.create('div')
local template = mw.html.create('div')
:css('position', 'relative')
:css('position', 'relative')
:css('font-family', 'BeaufortLoL')
:css('font-family', 'BeaufortLoL')
Line 534: Line 236:
:done()
:done()
local deckHeader = builder.create('div')
local deckHeader = mw.html.create('div')
:addClass('deck-header')
:addClass('deck-header')
:css('position', 'absolute')
:css('position', 'absolute')
Line 551: Line 253:
:tag('span')
:tag('span')
:addClass('inline-image')
:addClass('inline-image')
:wikitext('[[File:' .. regionName .. ' LoR Region.png|60px|link=LoR:' .. regionName .. ']]')
:wikitext('[[File:' .. regionName .. ' LoR Region.png|60px|link=' .. regionName .. ' (Legends of Runeterra)]]')
:done()
:done()
end
end
Line 560: Line 262:
:css('color', '#FFE3B0')
:css('color', '#FFE3B0')
:css('font-size', '16px')
:css('font-size', '16px')
:wikitext('[[File:Shard icon.png|40px|link=LoR:Shard]]' .. Utility.comma_value(totalShards))
:wikitext('[[File:Shard icon.png|40px|link=Shard (Legends of Runeterra)]]' .. Utility.comma_value(totalShards))
:done()
:done()
deckHeader:done()
deckHeader:done()
local deckInfo = builder.create('div')
local deckInfo = mw.html.create('div')
:addClass('deck-info')
:addClass('deck-info')
:css('position', 'absolute')
:css('position', 'absolute')
Line 589: Line 291:
:addClass('deck-info')
:addClass('deck-info')
:css('position', 'absolute')
:css('position', 'absolute')
:css('top', '240px')
:css('top', '170px')
:css('left', '15px')
:css('left', '20px')
:css('font-size', '20px')
:css('font-size', '20px')
:css('color', '#FFE3B0')
:css('color', '#FFE3B0')
:tag('span')
:tag('span')
:addClass('inline-image')
:addClass('inline-image')
:wikitext('[[File:Follower card.png|25px|link=LoR:Follower]]' .. followerCount .. '&nbsp;')
:wikitext('[[File:Follower card.svg|25px|link=Follower (Legends of Runeterra)]]' .. followerCount .. '&nbsp;')
:done()
:done()
:tag('span')
:tag('span')
:addClass('inline-image')
:addClass('inline-image')
:wikitext('[[File:Spell card.png|25px|link=LoR:Spell]]' .. spellCount .. '&nbsp;')
:wikitext('[[File:Spell card.svg|25px|link=Spell (Legends of Runeterra)]]' .. spellCount .. '&nbsp;')
:done()
:tag('span')
:addClass('inline-image')
:wikitext('[[File:Keyword Landmark.png|25px|link=LoR:Landmark]]' .. landmarkCount .. '&nbsp;')
:done()
:tag('span')
:addClass('inline-image')
:wikitext('[[File:Keyword Equipment.png|25px|link=LoR:Equipment]]' .. equipmentCount .. '&nbsp;')
:done()
:done()
:tag('br')
:tag('br')
Line 613: Line 307:
:tag('span')
:tag('span')
:addClass('inline-image')
:addClass('inline-image')
:wikitext('[[File:LoR Common icon.png|25px|link=LoR:Card_types#By_rarity]]' .. (rarities[1] or 0) .. '&nbsp;')
:wikitext('[[File:Common rarity.svg|25px|link=Card_types_(Legends_of_Runeterra)#By_rarity]]' .. (rarities[1] or 0) .. '&nbsp;')
:done()
:done()
:tag('span')
:tag('span')
:addClass('inline-image')
:addClass('inline-image')
:wikitext('[[File:LoR Rare icon.png|25px|link=LoR:Card_types#By_rarity]]' .. (rarities[2] or 0) .. '&nbsp;')
:wikitext('[[File:Rare rarity.svg|25px|link=Card_types_(Legends_of_Runeterra)#By_rarity]]' .. (rarities[2] or 0) .. '&nbsp;')
:done()
:done()
:tag('span')
:tag('span')
:addClass('inline-image')
:addClass('inline-image')
:wikitext('[[File:LoR Epic icon.png|25px|link=LoR:Card_types#By_rarity]]' .. (rarities[3] or 0) .. '&nbsp;')
:wikitext('[[File:Epic rarity.svg|25px|link=Card_types_(Legends_of_Runeterra)#By_rarity]]' .. (rarities[3] or 0) .. '&nbsp;')
:done()
:done()
:tag('span')
:tag('span')
:addClass('inline-image')
:addClass('inline-image')
:wikitext('[[File:LoR Champion icon.png|25px|link=LoR:Card_types#By_rarity]]' .. (rarities[4] or 0) .. '&nbsp;')
:wikitext('[[File:Champion rarity.svg|25px|link=Card_types_(Legends_of_Runeterra)#By_rarity]]' .. (rarities[4] or 0) .. '&nbsp;')
:done()
:done()
:done()
:done()
if #champions then
if #champions then
local deckChampions = builder.create('div')
local deckChampions = mw.html.create('div')
:addClass('deck-champions')
:addClass('deck-champions')
:css('position', 'absolute')
:css('position', 'absolute')
:css('bottom', '20px')
:css('bottom', '20px')
:css('left', '200px')
:css('left', '20px')
:css('font-size', '20px')
:css('font-size', '20px')
:css('color', '#FFE3B0')
:css('color', '#FFE3B0')
:tag('span')
:tag('span')
:addClass('inline-image')
:addClass('inline-image')
:wikitext('[[File:Champion card.png|25px|link=LoR:Champion]]')
:wikitext('[[File:Champion card.svg|25px|link=Champion (Legends of Runeterra)]]')
:done()
:done()
for _, deckData in pairs(champions) do
for _, deckData in pairs(champions) do
Line 645: Line 339:
:tag('span')
:tag('span')
:addClass('inline-image')
:addClass('inline-image')
:wikitext('[[File:' .. deckData.code .. '.png|60px|link=LoR:'.. deckData.code .. ']]')
:wikitext('[[File:' .. deckData.code .. '.png|60px|link='.. deckData.code .. ' (Legends of Runeterra)]]')
:done()
:done()
:tag('span')
:tag('span')
Line 664: Line 358:


function p.deckDecoder(frame)
function p.deckDecoder(frame)
local args = lib.frameArguments(frame)
local args; if frame.args == nil then args = lib.arguments(frame) else args = lib.arguments(frame.args) end
if args['code'] == nil then
if args['code'] == nil then
Line 674: Line 368:
if Utility.table_contains(groupByValues, groupBy) == false then
if Utility.table_contains(groupByValues, groupBy) == false then
return 'Only support Group By "region", "type" or none'
return 'Only support Group By "region", "type" or none'
end
local header = args['header'] or true
if header == 'false' then
header = false
end
end
Line 693: Line 382:
groupByKey = deckData.region
groupByKey = deckData.region
elseif groupBy == 'type' then
elseif groupBy == 'type' then
groupByKey = deckData.type .. 's'
groupByKey = cardType .. 's'
else
else
groupByKey = 'List'
groupByKey = 'List'
Line 720: Line 409:
local template = ""
local template = ""
template = template .. p.headerDeck{code = args['code'], name = args['name'], description = args['description']}
if header then
template = template .. p.headerDeck{code = args['code'], name = args['name'], description = args['description']}
end
local newline = "\n"
local newline = "\n"
Line 731: Line 418:
template = template .. "|-|" .. newline
template = template .. "|-|" .. newline
end
end
template = template .. groupByKey .. "=" .. newline .. "'''Code:''' " .. args['code'] .. newline
template = template .. groupByKey .. "=" .. newline .. "Code: " .. args['code'] .. newline


local regionData = result[groupByKey]
local regionData = result[groupByKey]
Line 775: Line 462:


return frame:preprocess(template)
return frame:preprocess(template)
end

function p.pocHeaderDeck(frame)
local args = lib.frameArguments(frame)
local builder = require("Module:SimpleHTMLBuilder")
local adventureData = require("Module:LoRPoCData/adventure")
local lorData = require("Module:LoRData/data")
args['name'] = args['name'] or args['foe'] or 'Untitled Deck'
local cmp = args['campaign'] or "World Adventures"
if args['adventure'] == nil or not adventureData[cmp][args['adventure']] then
return 'Adventure missing or invalid'
end
local adventure = adventureData[cmp][args['adventure']]
if args['foe'] == nil or not adventure[args['foe']] then
return 'Foe missing or invalid'
end
local foe = adventure[args['foe']]
local stars = adventure.stars or false
local adventureType = adventure["type"] or false
args['code'] = args['code'] or foe.deck or nil
if args['code'] == nil then
return 'Empty Code'
end
local hasPower = foe.power or false
local hasPowerArgs = args['powername'] or args['powerdesc'] or false
local powername = nil
local powerdesc = nil
local powericon = nil
local powerrarity = nil
if hasPower then
powername = foe.power.name or 'Power Name'
powerdesc = foe.power.desc or 'Power Description.'
powericon = foe.power.icon or nil
powerrarity = foe.power.rarity or 'Common'
end
if hasPowerArgs then
powername = args['powername'] or powername or 'Power Name'
powerdesc = args['powerdesc'] or powerdesc or 'Power Description.'
powericon = args['powericon'] or powericon or nil
powerrarity = args['powerrarity'] or powerrarity or 'Common'
hasPower = true
end
local deckDetail = p.deckDataFromCode{code = args['code'], detail = true}
if type(deckDetail) ~= 'table' then
return deckDetail
end
local deckSimple = p.deckDataFromCode{code = args['code'], detail = false}
if type(deckSimple) ~= 'table' then
return deckSimple
end
local topUnitCode = args['topUnitCode'] or foe.code or deckDetail['topUnitCode'] or nil
local regions = deckDetail['regions'] or nil
local champions = deckDetail['champions'] or nil
local followerCount = deckDetail['followerCount'] or nil
local spellCount = deckDetail['spellCount'] or nil
local landmarkCount = deckDetail['landmarkCount'] or nil
local equipmentCount = deckDetail['equipmentCount'] or nil
local MAX_MOBILE_ITEMS = 3
local MAX_ITEMS = 7
--Extract items on cards
local items = foe.items or nil
--Fuse champions with items
local championsItem = {}
if items then
for code, data in pairs(items) do
if lorData[code] and lorData[code]["supertype"] == "Champion" then
table.insert(championsItem,{
code=code,
count=0,
items=data
})
end
end
end
for _, deckData in pairs(champions) do
local found = false
for _, data in pairs(championsItem) do
if data.code == deckData.code then
found = true
data.count=deckData.count
break
end
end
if not found then
table.insert(championsItem, {
code=deckData.code,
count=deckData.count,
items=nil
})
end
end
table.sort(championsItem, function(a, b)
if (lorData[a.code].name == args['foe']) ~= (lorData[b.code].name == args['foe']) then -- 1. Priority if "name" is the foe
return lorData[a.code].name == args['foe']
end
local aitems = {}
local bitems = {}
if a.items then aitems = a.items end
if b.items then bitems = b.items end
if #aitems ~= #bitems then -- 2. Sort by the number of items (higher count first)
return #aitems > #bitems
end
if lorData[a.code].cost ~= lorData[b.code].cost then -- 3. Sort by "cost" (lowest to highest)
return lorData[a.code].cost < lorData[b.code].cost
end
return lorData[a.code].name < lorData[b.code].name -- 4. Sort alphabetically by "name"
end)
--detailed cards with items list
local detailedItems = {}
if items then
for code, data in pairs(items) do
table.insert(detailedItems, {
code=code,
name=lorData[code].name,
cost=lorData[code].cost,
items=data
})
end
end
table.sort(detailedItems, function(a, b)
if (a.name == args['foe']) ~= (b.name == args['foe']) then -- 1. Priority if "name" is the foe
return a.name == args['foe']
end
if #a.items ~= #b.items then -- 2. Sort by the number of items (higher count first)
return #a.items > #b.items
end
if a.cost ~= b.cost then -- 3. Sort by "cost" (lowest to highest)
return a.cost < b.cost
end
return a.name < b.name -- 4. Sort alphabetically by "name"
end)
local template = builder.create('div')
:css('display', 'inline-block')
:css('position', 'relative')
:css('font-family', 'BeaufortLoL')
:tag('div')
:css('opacity', '0.5')
:wikitext('[[File:' .. topUnitCode .. '-full.png|800px|link=]]')
:done()
local deckHeader = builder.create('div')
:addClass('deck-header')
:css('position', 'absolute')
:css('max-width', '650px')
:css('top', '10px')
:css('left', '10px')
:tag('span')
:css('font-weight', 'bold')
:css('color', '#FFE3B0')
:css('font-size', '30px')
:css('margin-left', '10px')
:css('margin-right', '10px')
:wikitext(args['name'])
:done()
local regionSize = 60
local count = 0
for _ in pairs(regions) do
count = count + 1
if count > 9 then
regionSize = 50
break
end
end
for regionName, regionCount in pairs(regions) do
deckHeader
:tag('span')
:addClass('inline-image')
:wikitext('[[File:' .. regionName .. ' LoR Region.png|' .. tostring(regionSize) .. 'px|link=LoR:' .. regionName .. ']]')
:done()
end
if stars then
local starHeader= builder.create('div')
:addClass('deck-header')
:css('position', 'absolute')
:css('top', '10px')
:css('left', '730px')
:tag('span')
:css('font-weight', 'bold')
:css('color', 'white')
:css('font-size', '18px')
:tag('span')
:addClass('PoC-Star-Difficulty')
:css('white-space', 'nowrap')
:tag('span')
:css('position', 'relative')
:css('text-indent', '0')
:css('top', '-3px')
:wikitext('[[File:PoC Star icon.png|60px|link=]]')
:tag('span')
:css('position', 'absolute')
:css('left', '17px')
:css('top', '30%')
:css('user-select', 'none')
:css('line-height', '1.5')
:css('text-align', 'center')
:css('width', '25px')
:css('height', '25px')
:css('transform', 'translateY(-25%)')
:css('text-shadow', '0.5px 0.5px 1px #000, 0.5px 0.5px 1px #000, -0.5px -0.5px 1px #000, -0.5px -0.5px 1px #000, 0.5px -0.5px 1px #000, 0.5px -0.5px 1px #000, -0.5px 0.5px 1px #000, -0.5px 0.5px 1px #000, 0.5px 0.5px 1px #000, 0.5px 0.5px 1px #000;')
:wikitext(stars)
:done()
:done()
:done()
:done()
template
:node(starHeader)
end
if adventureType then
local leftOffset = '660px'
if not stars then leftOffset = '730px' end
local typeImage = ''
if adventureData.Icons[adventureType] then
typeImage = '[[File:' .. adventureData.Icons[adventureType] .. '|60x60px|link=LoR:World Adventures]]'
end
local typeHeader= builder.create('div')
:addClass('deck-header')
:css('position', 'absolute')
:css('top', '8px')
:css('left', leftOffset)
:tag('span')
:wikitext(typeImage)
:done()
template
:node(typeHeader)
end
if #championsItem > 0 then
local deckChampions = builder.create('div')
:addClass('deck-champions')
:css('position', 'absolute')
:css('top', '70px')
:css('left', '20px')
:css('font-size', '20px')
:css('color', '#FFE3B0')
:tag('span')
:addClass('inline-image')
:wikitext('[[File:Champion card.png|25px|link=LoR:Champion]]')
:done()
local n = 0
for _, deckData in pairs(championsItem) do
if (n == MAX_MOBILE_ITEMS and args['mobile']) or (n == MAX_ITEMS) then
deckChampions
:tag('span')
:css('font-weight', 'bold')
:css('font-size', '30px')
:addClass('inline-image')
:wikitext(frame:preprocess(' ...'))
:done()
break
end
if deckData.items then
local s = '{{PoCCardItems|size=70|' .. deckData.code
for _, item in pairs(deckData.items) do
s = s .. '|' .. item
end
s = s .. '}}'
deckChampions
:tag('span')
:addClass('inline-image')
:wikitext(frame:preprocess(s))
:done()
:tag('span')
:addClass('inline-image')
:wikitext(' x' .. deckData.count .. '&nbsp;')
:done()
else
deckChampions
:tag('span')
:addClass('inline-image')
:wikitext('[[File:' .. deckData.code .. '.png|70px|link=LoR:'.. deckData.code .. ']]')
:done()
:tag('span')
:addClass('inline-image')
:wikitext('x' .. deckData.count .. '&nbsp;')
:done()
end
n = n+1
end
deckChampions:
done()
template
:node(deckChampions)
end
if items then
local deckItems = builder.create('div')
:addClass('deck-champions')
:css('position', 'absolute')
:css('top', '175px')
:css('left', '20px')
:css('font-size', '20px')
:css('color', '#FFE3B0')
:tag('span')
:addClass('inline-image')
:wikitext('[[File:PoC Relic icon.png|25px]]')
:done()
local n = 0
for _, itemList in ipairs(detailedItems) do
if (n == MAX_MOBILE_ITEMS and args['mobile']) or (n == MAX_ITEMS) then
deckItems
:tag('span')
:css('font-weight', 'bold')
:css('font-size', '30px')
:addClass('inline-image')
:wikitext(frame:preprocess(' ...'))
:done()
break
end
local count = 0;
local nonChampion = true
for _, data in pairs(championsItem) do
if data.code == itemList.code then
nonChampion = false
break
end
end
if nonChampion then
for _, data in pairs(deckSimple) do
if data.code == itemList.code then
count = data.count
break
end
end
local s = '{{PoCCardItems|size=70|' .. itemList.code
for _, item in ipairs(itemList.items) do
s = s .. '|' .. item
end
s = s .. '}}'
deckItems
:tag('span')
:addClass('inline-image')
:wikitext(frame:preprocess(s))
:done()
:tag('span')
:addClass('inline-image')
:wikitext(' x' .. count .. '&nbsp;')
:done()
n = n+1
end
end
deckItems:
done()
template
:node(deckItems)
end
local powerImage
local powerTitle
local powerInfo
if hasPower then
local image_leftOffset = 230
if args['mobile'] then image_leftOffset = 200 end
powerImage = builder.create('div')
:addClass('deck-info')
:css('position', 'absolute')
:css('top', '300px')
:css('left', tostring(image_leftOffset) .. 'px')
if powericon then
powerImage
:tag('span')
:css('display', 'inline-block')
:wikitext(frame:preprocess('{{PoCPowerIconOverlay|' .. powericon .. '|' .. powerrarity .. '|80}}'))
:done()
end
powerImage
:done()
powerTitle = builder.create('div')
:addClass('deck-info')
:css('position', 'absolute')
:css('top', '300px')
:css('left', tostring(image_leftOffset+100) .. 'px')
:css('color', '#FFE3B0')
:css('font-weight', 'bold')
:tag('span')
:css('display', 'inline-block')
:css('font-size', '16px')
:wikitext(powername)
:done()
powerTitle:done()
powerInfo = builder.create('div')
:addClass('deck-info')
:css('position', 'absolute')
:css('top', '330px')
:css('left', tostring(image_leftOffset+100) .. 'px')
:css('color', '#FFE3B0')
:tag('span')
:css('display', 'inline-block')
:css('max-width', '460px')
:css('font-size', '14px')
:wikitext(frame:preprocess(powerdesc))
:done()
powerInfo:done()
end
local health = foe.health or '?'
local mana = foe.mana or '?'
local hand = foe.hand or '?'
local vicious = foe.vicious or false
if hasPower then
template
:node(deckHeader)
:node(powerImage)
:node(powerTitle)
:node(powerInfo)
else
template
:node(deckHeader)
end

local color = '#FFE3B0'
if vicious then
color = '#FF7474'
if tonumber(health) then health = tostring(tonumber(health) + 10) end
if tonumber(mana) then mana = tostring(tonumber(mana) + 1) end
if tonumber(hand) then hand = tostring(tonumber(hand) + 1) end
end
template
:tag('div')
:addClass('deck-info')
:css('position', 'absolute')
:css('top', '320px')
:css('left', '15px')
:css('font-size', '20px')
:css('color', '#FFE3B0')
:tag('span')
:addClass('inline-image')
:wikitext('[[File:Follower card.png|25px|link=LoR:Follower]]' .. followerCount .. '&nbsp;')
:done()
:tag('span')
:addClass('inline-image')
:wikitext('[[File:Spell card.png|25px|link=LoR:Spell]]' .. spellCount .. '&nbsp;')
:done()
:tag('span')
:addClass('inline-image')
:wikitext('[[File:Keyword Landmark.png|25px|link=LoR:Landmark]]' .. landmarkCount .. '&nbsp;')
:done()
:tag('span')
:addClass('inline-image')
:wikitext('[[File:Keyword Equipment.png|25px|link=LoR:Equipment]]' .. equipmentCount .. '&nbsp;')
:done()
:done()
:tag('div')
:addClass('deck-info')
:css('position', 'absolute')
:css('top', '360px')
:css('left', '15px')
:css('font-size', '20px')
:css('color', color)
:tag('span')
:addClass('inline-image')
:wikitext('[[File:PoC Health icon.png|25px|link=LoR:Nexus Health]]' .. health .. '&nbsp;')
:done()
:tag('span')
:addClass('inline-image')
:wikitext('[[File:LoR mana icon alt.png|25px|link=LoR:Terminology#Mana]]' .. mana .. '&nbsp;')
:done()
:tag('span')
:addClass('inline-image')
:wikitext('[[File:Keyword Draw.png|25px|link=]]' .. hand .. '&nbsp;')
:done()
:tag('span')
:addClass('inline-image')
:wikitext(lib.ternary(vicious,frame:preprocess(' {{PoCPowerIconOverlay|04SI017-full.png|Special|30}}'),''))
:done()
:done()
template:allDone()
return tostring(template)
end

function p.pocDeckDecoder(frame)
local args = lib.frameArguments(frame)
local adventureData = require("Module:LoRPoCData/adventure")
local cmp = args['campaign'] or "World Adventures"
local groupBy = args['groupBy'] or 'none'
local groupByValues = {'region', 'type', 'none'}
if Utility.table_contains(groupByValues, groupBy) == false then
return 'Only support Group By "region", "type" or none'
end
if args['adventure'] == nil or not adventureData[cmp][args['adventure']] then
return 'Adventure missing or invalid'
end
local adventure = adventureData[cmp][args['adventure']]
if args['foe'] == nil or not adventure[args['foe']] then
return 'Foe missing or invalid'
end
local foe = adventure[args['foe']]
local items = foe.items or {}
local deckItems = {}
args['code'] = args['code'] or foe.deck or nil
if args['code'] == nil then
return 'Empty Code'
end
local header = args['header'] or true
if header == 'false' then
header = false
end
local result = {}
local deckList = p.deckDataFromCode{code = args['code']}
if type(deckList) ~= 'table' then
return deckList
end
for _, deckData in pairs(deckList) do
local groupByKey = ''
if groupBy == 'region' then
groupByKey = deckData.region
elseif groupBy == 'type' then
groupByKey = deckData.type .. 's'
else
groupByKey = 'List'
end
if result[groupByKey] == nil then
result[groupByKey] = {}
end
if items[deckData.code] then
table.insert(deckItems,deckData.code)
end
table.insert(
result[groupByKey],
{
code = deckData.code,
count = deckData.count,
name = deckData.name,
type = deckData.type
}
)
end

local sortedKeys = {}
for k in pairs(result) do
table.insert(sortedKeys, k)
end
table.sort(sortedKeys)
local template = ""
if header then
template = template .. p.pocHeaderDeck(frame)
end
local newline = "\n"
template = template .. "<tabber>" .. newline
template = template .. "Hide=" .. newline .. '|-|' .. newline
for i, groupByKey in ipairs(sortedKeys) do
if i ~= 1 then
template = template .. "|-|" .. newline
end
template = template .. groupByKey .. "=" .. newline .. "'''Code:''' <span style='word-wrap: break-word;'>" .. args['code'] .. '</span>' .. newline

local regionData = result[groupByKey]
table.sort(
regionData,
function(a, b)
if (a.type == b.type) then
return a.name < b.name
end
return a.type < b.type
end
)

local type = ""
local isFirst = true
for _, cardData in ipairs(regionData) do
if cardData.type ~= type then
if (type ~= "") then
template = template .. "|}" .. newline
end
template = template .. "{| class=\"wikitable\"" .. newline .. "! colspan=5 style=\"background-color: #374b65; text-align: left;\" |" .. cardData.type .. "s" .. newline .. "|-" .. newline
isFirst = true
type = cardData.type
end
local cardCodeTemplate = ""
if isFirst then
cardCodeTemplate = cardCodeTemplate .. '|-' .. newline
isFirst = false
else
cardCodeTemplate = cardCodeTemplate .. '|' .. newline
isFirst = true
end
cardCodeTemplate = cardCodeTemplate .."| {{LoR|" .. cardData.name
if cardData.type ~= "Champion" then
cardCodeTemplate = cardCodeTemplate .. "|code=" .. cardData.code
end
cardCodeTemplate = cardCodeTemplate .. "}}" .. " (x" .. cardData.count .. ")" .. newline
cardCodeTemplate = cardCodeTemplate .. "| "
if items[cardData.code] then
for _, item in ipairs(items[cardData.code]) do
if item:sub(1, 1) == "I" then
cardCodeTemplate = cardCodeTemplate .. "{{PoC|item|code=" .. item .. "}} "
else
cardCodeTemplate = cardCodeTemplate .. "{{PoC|relic|code=" .. item .. "}} "
end
end
end
template = template .. cardCodeTemplate .. newline
end
template = template .. "|}" .. newline
end
local extraItems = ""
local isFirst = true
for key, itemList in pairs(items) do
if true then
end
if not Utility.table_contains(deckItems,key) then
if isFirst then
extraItems = extraItems .. '|-' .. newline
isFirst = false
else
extraItems = extraItems .. '|' .. newline
isFirst = true
end
extraItems = extraItems .. "| {{LoR|code=" .. key .. "}}" .. newline .. "| "
for _, item in ipairs(itemList) do
if item:sub(1, 1) == "I" then
extraItems = extraItems .. "{{PoC|item|code=" .. item .. "}} "
else
extraItems = extraItems .. "{{PoC|relic|code=" .. item .. "}} "
end
end
extraItems = extraItems .. newline
end
end
if extraItems ~= "" then
if groupBy == 'region' or groupBy == 'type' then
template = template .. "|-|" .. newline .. "Non-deck=" .. newline .. "'''Code:''' " .. args['code'] .. newline
else
-- template = template .. ";Non-deck cards with items" .. newline
end
template = template .. "{| class=\"wikitable\"" .. newline .. "! colspan=5 style=\"background-color: #374b65; text-align: left;\" | Non-deck cards with items" .. newline .. "|-" .. newline .. extraItems .. "|}" .. newline
end
template = template .. "</tabber>"

return frame:preprocess(template)
end

function p.championRoster(frame)
local args = lib.frameArguments(frame)
local size = args["size"] or "120px"
local lorData = require('Module:LoRData/data')
local lorTable = {}
local s = ""
local REGION_CODES = {
DE = "Demacia",
FR = "Freljord",
IO = "Ionia",
NX = "Noxus",
PZ = "Piltover and Zaun",
SI = "Shadow Isles",
BW = "Bilgewater",
SH = "Shurima",
MT = "Targon",
BC = "Bandle City",
RU = "Runeterra"
}
local cardtable = {}
for cardcode in pairs(lorData) do
table.insert(cardtable, cardcode)
end
table.sort(cardtable)
local championtable = {}
for i, cardcode in pairs(cardtable) do
repeat
local t = lorData[cardcode]
if t.rarity ~= 'Champion' then
break
end
t['code'] = cardcode
table.insert(championtable, t)
break
until true
end
-- END
table.sort(championtable, function(a, b) return a['name'] < b['name'] end)
local rosterText = '' -- Temporarily will be class poc-roster
rosterText = rosterText .. '<div class="poc-roster-container" style="display: flex; flex-direction: column; margin: 0 auto; padding: 5px; text-align: center;">'
rosterText = rosterText .. '<div class="poc-roster" style="display: flex; justify-content: space-evenly; flex-wrap: wrap;">'
for _, card in pairs(championtable) do
rosterText = rosterText .. '<div class="poc-roster-champion" style="padding:0.5em;" data-champion="' .. card.name .. '" data-searchname="' .. card.name .. '" data-game="lor"'
if card.regions then
rosterText = rosterText .. ' data-region="' .. table.concat(card.regions, ", ") .. '">'
else
rosterText = rosterText .. ' data-region="' .. REGION_CODES[card.code:sub(3,4):upper()] .. '">'
end
rosterText = rosterText .. '[[File:' .. card.code .. '.png|' .. size .. '|link=LoR:' .. card.name .. ']] <br> [[LoR:' .. card.name .. '|' .. card.name .. ']]</div>'
end
rosterText = rosterText .. '</div>'
rosterText = rosterText .. '</div>'
return rosterText
end

function p.championRosterPoC(frame)
local args = lib.frameArguments(frame)
local size = args["size"] or "120px"
local pocData = require('Module:LoRPoCData/data')
local lorTable = {}
local s = ""
local rosterText = ''
rosterText = rosterText .. '<div class="poc-roster-container" style="display: flex; flex-direction: column; margin: 0 auto; padding: 5px; text-align: center;">'
rosterText = rosterText .. '<div class="poc-roster" style="display: flex; justify-content: space-evenly; flex-wrap: wrap;">'
pocData = pocData["Champion"]
local championtable = {}
for champion, data in pairs(pocData) do
if (data["playable"]) then
table.insert(championtable, data)
end
end
table.sort(championtable, function(a, b) return a.name < b.name end)
for _, data in pairs(championtable) do
rosterText = rosterText .. '<div class="poc-roster-champion" style="padding:0.5em;" data-champion="' .. data.name .. '" data-searchname="' .. data.name .. '" '
rosterText = rosterText .. 'data-game="lor" data-playstyle="' .. (data.playable.style or "no") .. '" data-difficulty="' .. (data.playable.difficulty or "no") .. '" '
rosterText = rosterText .. 'data-region="' .. table.concat(data.playable.region, ", ") .. '" '
if data.playable.constellationRegion then
rosterText = rosterText ..'data-constellation="' .. data.playable.constellationRegion .. ', hasConstellation" '
else
rosterText = rosterText ..'data-constellation="constellation-none" '
end
rosterText = rosterText .. '>[[File:' .. data.id .. '.png|' .. size .. '|link=LoR:' .. data.name .. '/PoC]] <br> [[LoR:' .. data.name .. '/PoC|' .. data.name .. ']]</div>'
end
rosterText = rosterText .. '</div>'
rosterText = rosterText .. '</div>'
return rosterText
end

function p.getPoCChampionGrid(frame)
-- Author: @Bladenite
local args = lib.frameArguments(frame)
local size = args["size"] or "120px"
local pocData = require('Module:LoRPoCData/data')
local gridText = ''
-- Creating outer container
gridText = gridText .. '<div class="poc-champions-flexbox-container" style="display: flex; flex-wrap: wrap; gap: 7.5px; justify-content: space-around;">'
-- Getting playable champions data
pocData = pocData["Champion"]
local championtable = {}
for champion, data in pairs(pocData) do
if (data["playable"]) then
table.insert(championtable, data)
end
end
table.sort(championtable, function(a, b) return a.name < b.name end)
for _, data in pairs(championtable) do
gridText = gridText .. '<div class="poc-champion-container" '
-- Adding data for search parameters
gridText = gridText .. 'data-champion="' .. data.name .. '" data-searchname="' .. data.name .. '" '
gridText = gridText .. 'data-game="lor" data-playstyle="' .. (data.playable.style or "no") .. '" data-difficulty="' .. (data.playable.difficulty or "no") .. '" '
gridText = gridText .. 'data-region="' .. table.concat(data.playable.region, ", ") .. '" '
if data.playable.constellationRegion then
gridText = gridText ..'data-constellation="' .. data.playable.constellationRegion .. ', hasConstellation" '
else
gridText = gridText ..'data-constellation="constellation-none" '
end
gridText = gridText .. '>' --closing div
-- Building champion board
gridText = gridText .. '<div class="poc-champion-circle"> [[File:' .. data.id .. '-circle.png|75px|link=LoR:' .. data.name .. '/PoC]]</div>'
gridText = gridText .. '<div class="poc-champion-name"> [[LoR:' .. data.name .. '/PoC|' .. data.name .. ']]</div>'
gridText = gridText .. '<div class="poc-champion-region">'
if #data.playable.region == 1 then
gridText = gridText .. '[[File:' .. data.playable.region[1] .. ' LoR Region.png|35px|link=]]</div>'
elseif #data.playable.region == 2 then
gridText = gridText .. '[[File:' .. data.playable.region[1] .. ' LoR Region.png|35px|link=]] '
gridText = gridText .. '[[File:' .. data.playable.region[2] .. ' LoR Region.png|35px|link=]]</div>'
end
if data.playable.style then
gridText = gridText .. '<div class="poc-champion-info"><span class="poc-' .. data.playable.style:lower() .. '">[[File:' .. data.playable.style .. ' LoR icon.png|20px|link=]] ' .. data.playable.style .. '</span> • '
end
if data.playable.difficulty then
gridText = gridText .. '<span class="poc-' .. data.playable.difficulty:lower() .. '"> ' .. data.playable.difficulty .. '</span></div>'
end
gridText = gridText .. '<div class="poc-champion-power" style="display: inline-flex; flex-wrap: wrap; justify-content: center;'
if data.name ~= 'Aurelion Sol' then
gridText = gridText .. 'width: 120px;' -- Controls the number of powers in one line (120px -> 3 powers per line)
end
gridText = gridText .. '>'
-- Ordering the powers correctly
for i, power in ipairs(data.playable.power) do
if power.code then
gridText = gridText .. '<span class="skin-icon" style="white-space: nowrap; order: ' .. tostring(i) .. ';"'
gridText = gridText .. ' data-game="lor" data-skin="PoC" data-champion="' .. power.code .. '"><span style="position:relative;text-indent:0;">'
gridText = gridText .. '[[File:' .. power.code .. '.png|30px|link=LoR:' .. data.name .. '/PoC]]&#8202;&#8202;</span></span>'
end
end
gridText = gridText .. '</div>'
if data.support then
gridText = gridText .. '<div class="poc-champion-reinforcement"><span class="lor-tooltip" data-param="' .. data.id .. ',' .. data.support[1] .. ',' .. data.support[2] .. ', 50%">[[File:LoR Card icon.png|17px|link=|alt=Reinforcements]]</span></div>'
end
-- Closing champion container
gridText = gridText .. '</div>'
end
-- Closing grid container
gridText = gridText .. '</div>'
return gridText
end

function p.pocChampionNavigation(frame)
local args = lib.frameArguments(frame)
local size = args["size"] or "80px"
local constellationOnly = args["constellationOnly"] or false
local pocData = require('Module:LoRPoCData/data')
local lorTable = {}
local s = ""
local navText = ""
pocData = pocData["Champion"]
local championtable = {}
for champion, data in pairs(pocData) do
if constellationOnly ~= false then
if (data["playable"]) and (data["playable"]["constellationRegion"]) then
table.insert(championtable, data)
end
else
if (data["playable"]) then
table.insert(championtable, data)
end
end
end
table.sort(championtable, function(a, b) return a.name < b.name end)
for _, data in pairs(championtable) do
navText = navText .. '[[File:' .. data.id .. '.png|' .. size .. '|link=LoR:' .. data.name .. '/PoC]]'
end
return navText
end

function p.pocWeekliesDateRange()
local today = os.date("*t")
local current_wday = today.wday
local days_to_add = (2 - current_wday) % 7 -- 2 corresponds to Monday
if days_to_add == 0 then
days_to_add = 7
end
days_to_add = days_to_add - 1 -- Last day is non-inclusive
local next_sunday_time = os.time(today) + days_to_add * 86400 -- 86400 seconds in a day
local next_sunday = os.date("*t", next_sunday_time)
local next_month_name = os.date("%B", next_sunday_time)
local prev_monday_time = next_sunday_time - 6 * 86400
local prev_monday = os.date("*t", prev_monday_time)
local prev_month_name = os.date("%B", prev_monday_time)
return string.format("%s %d – %s %d", prev_month_name, prev_monday.day, next_month_name, next_sunday.day)
end

function p.subtypeContent(frame)
local args = lib.frameArguments(frame)
local cardcode = args['code'] or args[1] or nil
if not cardcode then
return ''
end
local lorData = mw.loadData('Module:LoRData/data')
subtypetext = ''
for _, subtype in pairs(lorData[cardcode].subtype) do
subtypelink = '[[LoR:' .. subtype .. '|' .. subtype .. ']]'
if subtypetext ~= '' then
subtypetext = subtypetext .. ", " .. subtypelink
else
subtypetext = subtypetext .. subtypelink
end
subtypetext = subtypetext .. "[[" .. "Category:LoR " .. subtype .. "]]"
end
return frame:preprocess(subtypetext)
end

function p.regionContent(frame)
local args = lib.frameArguments(frame)
local cardcode = args['code'] or args[1] or nil
if not cardcode then
return ''
end
local lorData = mw.loadData('Module:LoRData/data')
if not lorData[cardcode] then
return ''
end
local regions = {}
if not lorData[cardcode].regions then
local regionCode = string.sub(cardcode, 3, 4)
for _, regionData in pairs(REGIONS) do
if regionData.code == regionCode then
table.insert(regions, regionData.name)
break
end
end
else
regions = lorData[cardcode].regions
end
regiontext = ''
for _, region in pairs(regions) do
regionlink = '[[File:' .. region .. ' LoR Region.png|20px]] '
regionlink = regionlink .. '[[LoR:' .. region .. '|' .. region .. ']]'
if regiontext ~= '' then
regiontext = regiontext .. ", " .. regionlink
else
regiontext = regiontext .. regionlink
end
regiontext = regiontext .. "[[" .. "Category:LoR " .. region .. "]]"
end
if regiontext == '' then
regiontext = 'N/A'
end
return frame:preprocess(regiontext)
end

function p.artworkContent(frame)
local args = lib.frameArguments(frame)
local cardcode = args['code'] or args[1] or nil
if not cardcode then
return ''
end
local lorData = mw.loadData('Module:LoRData/data')
local imageSize = '125px'
artworkText = "<ul style='margin-left:0;'>"
artworkText = artworkText .. "<li style='display:inline-block;text-indent:0px;'>[[File:" .. cardcode .. "-full.png|thumb|"
.. imageSize .. "|Primary|left]]</li>"

if lorData[cardcode].alternate then
artworkText = artworkText .. "<li style='display:inline-block;text-indent:0px;'>[[File:" .. cardcode
.. "-alt-full.png|thumb|" .. imageSize .. "|Censored|left]]"
end
for _, artwork in pairs(lorData[cardcode].artworks or {}) do
local extension = 'png'
local artworkParts = lib.split(artwork, "-")
local HD = false
local alternate = false
local display = false
local prerelease = false
local old = false
for k, v in pairs(artworkParts) do
if (v == 'hd') then
HD = true
end
if (v == 'alt') then
alternate = true
end
if (v == 'display') then
display = true
end
if (v == 'pre') then
prerelease = true
end
if (v == 'old') then
old = true
end
end
local artworkContents = {}
if HD then
table.insert(artworkContents, 'HD')
extension = 'jpg'
end
if prerelease then
table.insert(artworkContents, 'Pre-Release')
end
if alternate then
table.insert(artworkContents, '[[LoR:List of cards/Alternate|Censored]]')
end
if display then
table.insert(artworkContents, '[[League Displays]]')
extension = 'jpg'
end
if old then
table.insert(artworkContents, 'Old')
end
if #artworkContents >= 1 then
artworkContent = table.concat(artworkContents, " ")
else
artworkContent = 'Uncategorized'
end

artworkLink = "<li style='display:inline-block;text-indent:0px;'>[[File:" .. cardcode .. "-"
.. artwork .. "-full." .. extension .. "|thumb|" .. imageSize .. "|" .. artworkContent .. "|left]]</li>"

if artworkText ~= '' then
artworkText = artworkText .. " " .. artworkLink
else
artworkText = artworkText .. artworkLink
end
end

artworkText = artworkText .. "</ul>"
return frame:preprocess(artworkText)
end

function p.artworkTooltip(frame)
local args = lib.frameArguments(frame)
local artworkCode = args['code'] or args[1] or nil
if not artworkCode then
return ''
end
local artworkList = lib.split(artworkCode, ",")
local width = 250
if string.find(artworkList[1], '-full') then
width = 300
end

if string.find(artworkList[#artworkList], '%%') then
width = math.floor(width * (tonumber(string.match(artworkList[#artworkList], '%d+')/100) or 1))
table.remove(artworkList, #artworkList)
end
if (#artworkList > 4) then
width = width / 2
end
local artworkTooltip = '<div style="display:inline-flex; flex-wrap:wrap; width:' .. math.min(width * 4, width * #artworkList) .. 'px; box-shadow: rgb(1, 10, 19) 0px 0px 25px 15px;">'
for k, v in pairs(artworkList) do
artworkTooltip = artworkTooltip .. '<div style="display:inline-block; background-color: rgb(1, 10, 19); flex: 1 1;">'
artworkTooltip = artworkTooltip .. '[[File:' .. v .. '.png|' .. width .. 'px]]'
artworkTooltip = artworkTooltip .. '</div>'
end
artworkTooltip = artworkTooltip .. '</div>'
return artworkTooltip
end

function p.randomCard(frame)
local args = lib.frameArguments(frame)
local lorData = mw.loadData('Module:LoRData/data')
local keys = {}
for key, _ in pairs(lorData) do
keys[#keys+1] = key --Store keys in another table
end
local randomCode
-- Random
math.randomseed(os.time())
math.random(); math.random(); math.random()
for x = 1,10 do
randomCode = keys[math.random(1, #keys)]
end

local randomCard = lorData[randomCode]
local link = 'LoR:' .. randomCode
local text = '[[File:' .. randomCode .. '.png|250px|link=' .. link .. ']]'
text = text .. '[[' .. link .. '|' .. randomCard.name .. ']]'
local cardMode = randomCard.mode
if cardMode then
text = text .. ' ([[LoR:List of cards/' .. cardMode .. '|' .. cardMode .. ']])'
end
return frame:preprocess(text)
end
end


Line 1,940: Line 476:
bytesPopped = bytesPopped + 1
bytesPopped = bytesPopped + 1
local current = BitOperator.AND(bytes[i], VarInt.AllButMSB)
local current = BitOperator.AND(bytes[i], VarInt.AllButMSB)
result = BitOperator.OR(result, BitOperator.LEFT_SHIFT(current, currentShift))
result = BitOperator.OR(result, BitOperator.RIGHT_SHIFT(current, currentShift))


if BitOperator.AND(bytes[i], VarInt.JustMSB) ~= VarInt.JustMSB then
if BitOperator.AND(bytes[i], VarInt.JustMSB) ~= VarInt.JustMSB then
Please note that all contributions to League of Legends Wiki are considered to be released under the CC BY-SA 3.0 (see League of Legends Wiki:Copyrights for details). If you do not want your writing to be edited mercilessly and redistributed at will, then do not submit it here.
You are also promising us that you wrote this yourself, or copied it from a public domain or similar free resource. Do not submit copyrighted work without permission!
Cancel Editing help (opens in new window)
Preview page with this template
Below are some commonly used wiki markup codes. Simply click on what you want to use and it will appear in the edit box above.

View this template

Template used on this page: