Module:Sandbox/User:Fjara/Sandbox/Rake
Documentation for this module may be created at Module:Sandbox/User:Fjara/Sandbox/Rake/doc
local p = {}
local buildOutput = require('Module:RuneReq').buildOutput
local paramTest = require('Module:Paramtest')
local yesNo = require('Module:Yesno')
local contains = require('Module:Array').contains
local jsonDecode = mw.text.jsonDecode
local ComboRunes = {
['Dust rune'] = {'Air rune', 'Earth rune'},
['Lava rune'] = {'Earth rune', 'Fire rune'},
['Mist rune'] = {'Air rune', 'Water rune'},
['Mud rune'] = {'Earth rune', 'Water rune'},
['Smoke rune'] = {'Air rune', 'Fire rune'},
['Steam rune'] = {'Fire rune', 'Water rune'},
}
local MemberRunes = { 'Astral rune', 'Blood rune', 'Dust rune', 'Lava rune', 'Mist rune', 'Mud rune', 'Smoke rune', 'Soul rune', 'Steam rune', 'Wrath rune' }
local Spellbooks = { 'Standard', 'Ancient', 'Lunar', 'Arceuus' }
function createRow(isRuneMemberOnly, spellbook, rowData)
local row = mw.html.create('tr')
:tag('td'):wikitext(rowData.image):done()
:tag('td'):wikitext(rowData.name):done()
:tag('td'):wikitext(rowData.magicLevel):done()
:tag('td'):wikitext(rowData.runes):done()
:tag('td'):wikitext(rowData.magicExperience):done()
:tag('td'):wikitext(rowData.spellType):done()
if(spellbook == nil) then
row:tag('td'):wikitext(rowData.spellbookType):done()
end
if(((spellbook == nil) or (spellbook == 'Standard')) and (not isRuneMemberOnly)) then
row:tag('td'):wikitext(rowData.members and '[[File:Member icon.png|center|link=Members]]' or '[[File:Free-to-play icon.png|center|link=Free-to-play]]'):done()
end
return row
end
function createHeader(isRuneMemberOnly, spellbook)
local ret = mw.html.create('table'):addClass('wikitable sortable mw-collapsible mw-collapsed')
:addClass('align-center-1 align-center-2 align-center-3 align-center-4 align-center-5 align-center-6 align-center-7')
local header = mw.html.create('tr')
:tag('th'):wikitext('Icon'):done()
:tag('th'):wikitext('Spell'):done()
:tag('th'):wikitext('[[File:Magic icon.png|link=|Magic]] level'):done()
:tag('th'):wikitext('[[Runes]]'):done()
:tag('th'):wikitext('[[File:Magic icon.png|link=|Magic]] [[Experience]]'):done()
:tag('th'):wikitext('Spell type'):done()
if(spellbook == nil) then
ret:addClass('align-center-8')
header:tag('th'):wikitext('[[Spellbook]]'):done()
end
if((spellbook == nil or spellbook == 'Standard') and (not isRuneMemberOnly)) then
ret:addClass('align-center-8 align-center-9')
header:tag('th'):wikitext('[[Members]]'):done()
end
return ret:node(header):done()
end
function loadData(rune, spellbook)
local query = {
offset = 0,
limit = 500,
}
local conditions = { '[[Spellbook::+]]' }
if(ComboRunes[rune]) then
table.insert(conditions, '[[Uses material::' .. ComboRunes[rune][1] .. ']]')
table.insert(conditions, '[[Uses material::' .. ComboRunes[rune][2] .. ']]')
else
table.insert(conditions, '[[Uses material::' .. rune .. ']]')
end
if(spellbook) then
table.insert(conditions, '[[Spellbook::' .. spellbook .. ' spellbook]]')
end
table.insert(query, table.concat(conditions))
table.insert(query, '?=#-')
table.insert(query, '?Image = image')
table.insert(query, '?Magic level = magicLevel')
table.insert(query, '?Spell JSON = json')
table.insert(query, '?Magic experience = magicExperience')
table.insert(query, '?Spell type = spellType')
table.insert(query, '?Spellbook = spellbookType')
table.insert(query, '?Is members only = members')
local t1 = os.clock()
local smwData = mw.smw.ask(query)
local t2 = os.clock()
assert(smwData ~= nil and #smwData > 0, 'No spells found with ' .. spellbook .. ' and ' .. rune)
mw.log(string.format('SMW: Found %i, offset %i, limit %i, time elapsed %.3f ms', #smwData, query.offset, query.limit, (t2 - t1) * 1000))
-- Format data in table to be usable elsewhere
for _, datum in ipairs(smwData) do
datum.name = '[[' .. datum[1] .. ']]'
datum[1] = nil
datum.image = datum.image:sub(1, datum.image:find('|') - 1) .. ']]'
-- Format rune quantities identically to buildOutput input parameters
local json = jsonDecode(datum.json)
local itemCount = {}
for _, runeData in ipairs(json.runes) do
table.insert(itemCount, { runeData.rune, runeData.quantity } )
end
datum.runes = buildOutput(itemCount, json.bolts, json.staff, json.prayer)
datum.spellType = datum.spellType:sub(4, datum.spellType:find(' ') - 1)
if(type(datum.spellbookType) == 'table') then
local bookConcat = ''
for i, book in ipairs(datum.spellbookType) do
bookConcat = bookConcat .. book:sub(4, book:find(' ') - 1)
if(i < #datum.spellbookType) then
bookConcat = bookConcat .. '<br/>'
end
end
datum.spellbookType = bookConcat
else
datum.spellbookType = datum.spellbookType:sub(4, datum.spellbookType:find(' ') - 1)
end
end
-- Sort the rows by Magic level
local sortOrder = {}
for _, rowData in ipairs(smwData) do
rowData.magicLevel = ''
end
table.sort(sortorder, function(a, b) return (a > b) end)
return smwData
end
function p._main(args)
local rune = paramTest.default_to(paramTest.ucflc(args.rune), nil)
local spellbook = paramTest.default_to(paramTest.ucflc(args.spellbook), nil)
assert(contains(Spellbooks, spellbook), 'Invalid spellbook: ' .. spellbook)
assert(contains(MemberRunes, rune), 'Invalid rune: ' .. rune)
local isRuneMemberOnly = contains(MemberRunes, rune)
local data = loadData(rune, spellbook)
local ret = createHeader(isRuneMemberOnly, spellbook)
for _, rowData in ipairs(data) do
ret:node(createRow(isRuneMemberOnly, spellbook, rowData))
end
return ret
end
function p.main(frame)
local args = frame:getParent().args
return p._main(args)
end
return p