Module:EmberFantasy/sandbox/Slottable: Difference between revisions
Jump to navigation
Jump to search
Content added Content deleted
No edit summary Tag: Reverted |
No edit summary Tag: Manual revert |
||
Line 1: | Line 1: | ||
-- <pre> |
|||
require('Module:Mw.html extension') |
|||
local p = {} |
local p = {} |
||
local format = require('Module:Format equipment stat').format --for formatting the stats with + and - symbols on output |
|||
require('Module:Mw.html extension') |
|||
local p2pIcon = '[[File:Member icon.png|frameless|link=Pay-to-play]]' --these icons are for the later members/f2p stars |
|||
local yesNo = require('Module:Yesno') |
|||
local f2pIcon = '[[File:Free-to-play icon.png|frameless|link=Free-to-play]]' |
|||
local paramTest = require('Module:Paramtest') |
|||
local contains = require('Module:Array').contains |
|||
local minimum = require('Module:Array').min |
|||
local pagesWithCats = require('Module:PageListTools').pageswithcats |
|||
local pagesWithConditions = require('Module:PageListTools').pageswithconditions |
|||
local editbtn = require('Module:Edit button') |
|||
local stats = {'astab', 'aslash', 'acrush', 'amagic', 'arange', 'dstab', 'dslash', 'dcrush', 'dmagic', 'drange', 'str', 'rstr', 'mdmg', 'prayer'} |
|||
local memberOptions = {'members', 'f2p', 'all'} |
|||
local slotOptions = {'head', 'cape', 'neck', 'ammo', 'weapon', 'shield', 'body', 'legs', 'hands', 'feet', 'ring', '2h'} |
|||
local statOptions = {'astab', 'aslash', 'acrush', 'amagic', 'arange', 'dstab', 'dslash', 'dcrush', 'dmagic', 'drange', 'str', 'rstr', 'mdmg', 'prayer'} |
|||
function |
function p.main(frame) |
||
local args = frame:getParent().args --get the input from the template |
|||
local arg = tonumber(_arg) |
|||
local slot = string.lower(tostring(args['slot'])) --take the slot input as the slot we want the table for |
|||
if(not arg) then return (default or _arg) end |
|||
local mems = args['mems'] |
|||
if(arg < 0) then return tostring(arg) end |
|||
local dmm = args['dmm'] |
|||
return '+' .. arg |
|||
local beta = args['beta'] |
|||
end |
|||
local data = getData(slot,mems,dmm,beta) --this takes the slot and sends it to our getData function (seen below) which gives us back a data table |
|||
local restbl = mw.html.create('table') --start making our results table, beginninig with the header |
|||
function buildRow(item, attackSpeedColumn, uim) |
|||
restbl:addClass('wikitable align-center-1 sortable align-center') |
|||
local row = mw.html.create('tr') |
|||
:tag('tr') |
|||
:tag('td'):wikitext(item.image and '[[' .. item.image .. '|link=|' .. item.name .. ']]' or ''):done() |
|||
:tag(' |
:tag('th'):addClass('unsortable'):wikitext(''):done() |
||
:tag(' |
:tag('th'):wikitext('Name'):done() |
||
:tag('th'):wikitext('Members'):done() |
|||
:tag('th'):wikitext('[[File:White dagger.png|Stab attack]]') :done() |
|||
for _, stat in ipairs(statOptions) do |
|||
:tag('th'):wikitext('[[File:White scimitar.png|Slash attack]]') :done() |
|||
local statNum = tonumber(item[stat]) |
|||
:tag('th'):wikitext('[[File:White warhammer.png|Crush attack]]') :done() |
|||
row:tag('td'):wikitext((statFormat(item[stat]) or editbtn("'''?''' (edit)", item.name)) .. (stat == 'mdmg' and '%' or '')) |
|||
:tag('th'):wikitext('[[File:Magic icon.png|Magic attack]]') :done() |
|||
:addClassIf(statNum and (statNum > 0), 'table-positive') |
|||
:tag('th'):wikitext('[[File:Ranged icon.png|Ranged attack]]') :done() |
|||
:addClassIf(statNum and (statNum < 0), 'table-negative') |
|||
:tag('th'):wikitext('[[File:White dagger.png|Stab defence]]<sup>[[File:Defence icon.png]]</sup>') :done() |
|||
end |
|||
:tag('th'):wikitext('[[File:White scimitar.png|Slash defence]]<sup>[[File:Defence icon.png]]</sup>') :done() |
|||
:tag('th'):wikitext('[[File:White warhammer.png|Crush defence]]<sup>[[File:Defence icon.png]]</sup>') :done() |
|||
local weightNum = tonumber(item.weight) |
|||
:tag('th'):wikitext('[[File:Magic icon.png|Magic defence]]<sup>[[File:Defence icon.png]]</sup>') :done() |
|||
row:tag('td'):wikitext(item.weight) |
|||
:tag('th'):wikitext('[[File:Ranged icon.png|Ranged defence]]<sup>[[File:Defence icon.png]]</sup>') :done() |
|||
:tag('th'):wikitext('[[File:Strength icon.png|Strength]]') :done() |
|||
:tag('th'):wikitext('[[File:Ranged Strength icon.png|Ranged Strength]]') :done() |
|||
:tag('th'):wikitext('[[File:Magic Damage icon.png|Magic Damage]]') :done() |
|||
:tag('th'):wikitext('[[File:Prayer icon.png|Prayer]]') :done() |
|||
:tag('th'):wikitext('Weight') :done() |
|||
:done() |
|||
-- Create the rows for the output table |
|||
if(attackSpeedColumn) then |
|||
for _, item in ipairs(data) do --for each row of data, we take it and split it up, then put it into our table row. We also format them with + and - symbols here |
|||
if((item.speed == nil) or (item.speed < 0)) then |
|||
local row = restbl:tag('tr') |
|||
row:tag('td'):addClass('table-na nohighlight'):css('text-align', 'center'):wikitext('<small>N/A</small>') |
|||
:tag('td'):wikitext(item.image):done() |
|||
else |
|||
:tag('td'):wikitext(item.name):done() |
|||
:tag('td'):wikitext(item.members):done() |
|||
for _, stat in ipairs(stats) do |
|||
local value = item[stat] |
|||
local value_num = tonumber(value) |
|||
row:tag('td'):wikitext(format(value)) |
|||
:addClassIf(value_num and (value_num > 0), 'table-positive') |
|||
:addClassIf(value_num and (value_num < 0), 'table-negative') |
|||
end |
end |
||
row:tag('td'):wikitext(item.weight):done() |
|||
end |
|||
if(uim) then |
|||
local storeability = 'Shop' |
|||
if(item.emote) then |
|||
storeability = 'STASH' |
|||
elseif(item.costume) then |
|||
storeability = 'POH' |
|||
end |
|||
row:tag('td'):wikitext(storeability):done() |
|||
end |
end |
||
return tostring(restbl) --returns the table back to the template to be put onto the page |
|||
return row |
|||
end |
end |
||
function getData(slotName,mems,dmm,beta) --so this is the function that takes the slot name and gets all the data for the items |
|||
function createHeader(slotName, attackSpeedColumn, uim) |
|||
--first we set up our SMW query |
|||
local tabl = mw.html.create('table'):addClass('wikitable lighttable sortable sticky-header align-center-1 align-left-2 align-center-3 align-right-4 align-right-5 align-right-6 align-right-7 align-right-8 align-right-9 align-right-10 align-right-11 align-right-12 align-right-13 align-right-14 align-right-15 align-right-16 align-right-17 align-center-18'):done() |
|||
local |
local q = { |
||
'[[Equipment slot::'..slotName..']]', --we want everything that matches the slot we called, and then all the attached data below |
|||
header:tag('th'):attr('colspan', '2'):wikitext('Name'):done() |
|||
'?Is members only', |
|||
:tag('th'):wikitext('[[File:Member icon.png|link=|Members]]'):done() |
|||
'?Stab attack bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:White dagger.png|link=|Stab attack]]'):done() |
|||
'?Slash attack bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:White scimitar.png|link=|Slash attack]]'):done() |
|||
'?Crush attack bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:White warhammer.png|link=|Crush attack]]'):done() |
|||
'?Magic attack bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:Magic icon.png|link=|Magic attack]]'):done() |
|||
'?Range attack bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:Ranged icon.png|link=|Ranged attack]]'):done() |
|||
'?Stab defence bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:White dagger.png|link=|Stab defence]]<sup>[[File:Defence icon.png|link=]]</sup>'):done() |
|||
'?Slash defence bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:White scimitar.png|link=|Slash defence]]<sup>[[File:Defence icon.png|link=]]</sup>'):done() |
|||
'?Crush defence bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:White warhammer.png|link=|Crush defence]]<sup>[[File:Defence icon.png|link=]]</sup>'):done() |
|||
'?Magic defence bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:Magic icon.png|link=|Magic defence]]<sup>[[File:Defence icon.png|link=]]</sup>'):done() |
|||
'?Range defence bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:Ranged icon.png|link=|Ranged defence]]<sup>[[File:Defence icon.png|link=]]</sup>'):done() |
|||
'?Strength bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:Strength icon.png|link=|Strength]]'):done() |
|||
'?Ranged Strength bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:Ranged Strength icon.png|link=|Ranged Strength]]'):done() |
|||
'?Magic Damage bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:Magic Damage icon.png|link=|Magic Damage]]'):done() |
|||
'?Prayer bonus', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:Prayer icon.png|link=|Prayer]]'):done() |
|||
'?Category', |
|||
:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:Weight icon.png|link=|Weight]]'):done() |
|||
'?Image', |
|||
'?Weight', |
|||
if(attackSpeedColumn) then |
|||
limit = 1000, |
|||
header:tag('th'):attr('data-sort-type', 'number'):wikitext('[[File:Watch.png|link=|Speed]]'):done() |
|||
order = 'ascending' |
|||
end |
|||
if(uim) then |
|||
header:tag('th'):wikitext('[[File:Marble magic wardrobe icon.png|link=]]Stored/Buy'):done() |
|||
end |
|||
return tabl |
|||
end |
|||
function filterData(data, slotName, options) |
|||
if(slotName == 'ammo') then slotName = 'Ammunition' end -- hacky shit until ammo/ammunition is resolved |
|||
slotCat = '[[Category:' .. paramTest.ucfirst(slotName) .. ' slot items]]' |
|||
if slotName == '2h' then |
|||
slotCat = '[[Category:Two-handed slot items]]' |
|||
end |
|||
local exclusionListCategories = { |
|||
{ options.beta, slotCat .. '[[Category:Beta items]]' }, |
|||
{ options.discontinued, slotCat .. '[[Category:Discontinued content]]' }, |
|||
{ options.dmm, slotCat .. '[[Category:Deadman seasonal items]]' }, |
|||
{ options.emir, slotCat .. '[[Category:Emir\'s Arena]]' }, |
|||
{ options.failedPoll, slotCat .. '[[Category:Pages containing information from failed polls]]' }, |
|||
{ options.gauntlet, slotCat .. '[[Category:The Gauntlet]]' }, |
|||
{ options.lms, slotCat .. '[[Category:Last Man Standing]]' }, |
|||
{ options.quest, slotCat .. '[[Category:Quest items]]' }, |
|||
} |
} |
||
local smwdata = mw.smw.ask(q) --this now asks the smw for all the data, and saves all of it in smwdata |
|||
local data = {} --setting this table up to insert processed data into |
|||
for _, item in ipairs(smwdata) do --for each item we found with our smw query |
|||
local exclusionList = { } |
|||
local process = true |
|||
for _, excl in ipairs(exclusionListCategories) do |
|||
local dmmcat = false |
|||
if(not excl[1]) then |
|||
local betacat = false |
|||
table.insert(exclusionList, excl[2]) |
|||
if type(item['Category']) == 'table' then |
|||
for _, category in ipairs(item['Category']) do |
|||
if category == "[[:Category:Deadman seasonal items|Deadman seasonal items]]" then |
|||
dmmcat = true |
|||
elseif category == "[[:Category:Beta items|Beta items]]" then |
|||
betacat = true |
|||
end |
|||
end |
|||
end |
end |
||
if mems == 'Members' then |
|||
end |
|||
if not item['Is members only'] then |
|||
local pagesToExclude = #exclusionList > 0 and pagesWithCats(exclusionList) or {} |
|||
process = false |
|||
local emotePagesToInclude, costumePagesToInclude |
|||
end |
|||
if(options.uim) then |
|||
emotePagesToInclude = pagesWithCats({ slotCat .. '[[Category:Items needed for an emote clue]]' }) or {} |
|||
costumePagesToInclude = pagesWithCats({ slotCat .. '[[Category:Items storable in the costume room]]' }) or {} |
|||
end |
|||
-- Filter the data |
|||
local retData = {} |
|||
for _, item in ipairs(data) do |
|||
local keep = true |
|||
if(((options.members == 'members') and (item['members'] == false)) or |
|||
((options.members == 'f2p') and (item['members'] == true)) or |
|||
((contains(pagesToExclude, item['variantof'])) or (contains(pagesToExclude, item['name'])))) then |
|||
keep = false |
|||
end |
end |
||
if mems == 'F2P' then |
|||
if |
if item['Is members only'] then |
||
process = false |
|||
if((not (contains(emotePagesToInclude, item['variantof']) or (contains(emotePagesToInclude, item['name'])))) and |
|||
(not (contains(costumePagesToInclude, item['variantof']) or (contains(costumePagesToInclude, item['name'])))) and |
|||
(next(pagesWithConditions('[[Sells item::' .. item.name .. ']]')) == nil)) then |
|||
keep = false |
|||
elseif(contains(costumePagesToInclude, item['variantof']) or (contains(costumePagesToInclude, item['name']))) then |
|||
item.costume = true |
|||
elseif(contains(emotePagesToInclude, item['variantof']) or (contains(emotePagesToInclude, item['name']))) then |
|||
item.emote = true |
|||
end |
end |
||
end |
end |
||
if dmm == 'No' then |
|||
if |
if dmmcat == true then |
||
process = false |
|||
table.insert(retData, item) |
|||
end |
|||
end |
end |
||
if beta == 'No' then |
|||
if betacat == true then |
|||
end |
|||
process = false |
|||
mw.log(string.format('Filter: exclusion list size: %i, start size: %i, end size: %i, removed %i.', #pagesToExclude, #data, #retData, #data - #retData)) |
|||
return retData |
|||
end |
|||
function loadData(slotName, attackSpeed, members) |
|||
local query = { |
|||
'[[Equipment slot::' .. slotName .. ']]', |
|||
'?=#-', |
|||
'?Stab attack bonus#-=astab', |
|||
'?Slash attack bonus#-=aslash', |
|||
'?Crush attack bonus#-=acrush', |
|||
'?Magic attack bonus#-=amagic', |
|||
'?Range attack bonus#-=arange', |
|||
'?Stab defence bonus#-=dstab', |
|||
'?Slash defence bonus#-=dslash', |
|||
'?Crush defence bonus#-=dcrush', |
|||
'?Magic defence bonus#-=dmagic', |
|||
'?Range defence bonus#-=drange', |
|||
'?Strength bonus#-=str', |
|||
'?Magic Damage bonus#-=mdmg', |
|||
'?Ranged Strength bonus#-=rstr', |
|||
'?Prayer bonus#-=prayer', |
|||
'?Weight#-=weight', |
|||
'?Is members only#-=members', |
|||
'?Image#-=image', |
|||
'?Is variant of#-=variantof', |
|||
offset = 0, |
|||
limit = 1000, |
|||
} |
|||
if(attackSpeed) then |
|||
table.insert(query, '?Weapon attack speed#-=speed') |
|||
end |
|||
local t1 = os.clock() |
|||
local smwData = mw.smw.ask(query) |
|||
local t2 = os.clock() |
|||
assert(smwData ~= nil and #smwData > 0, 'SMW query failed') |
|||
for _, item in ipairs(smwData) do |
|||
-- Rename the first parameter to name for clarity and ease of use |
|||
item['name'] = item[1] |
|||
item[1] = nil |
|||
if(item['image'] == nil) then |
|||
local hasDefaultFile = mw.title.new(item['name'] .. '.png', 'File'):getContent() |
|||
item['image'] = hasDefaultFile and 'File:' .. item['name'] .. '.png' or '' |
|||
elseif(type(item['image']) == 'table') then |
|||
item['image'] = item['image'][1] |
|||
end |
|||
-- Fix members values by defaulting when running into issue |
|||
if(type(item.members) == 'boolean') then |
|||
-- Short circuit |
|||
elseif(item.members == nil) then |
|||
item.members = false |
|||
elseif(type(item.members) == 'table') then |
|||
for _, mems in ipairs(item.members) do |
|||
if(mems == false) then |
|||
item.members = false |
|||
break |
|||
end |
|||
end |
end |
||
end |
end |
||
if process then |
|||
-- Fix weights with multiple values (Max cape), this may do nothing and is precautionary |
|||
local dataline = processData(item) --we process it (seen below) and then save it as a line |
|||
if(item.weight == nil) then |
|||
table.insert(data, dataline) --and then we insert that line into our data table to be returned |
|||
item.weight = 0 |
|||
elseif(type(item.weight) == 'table') then |
|||
item.weight, _ = minimum(item.weight) |
|||
end |
end |
||
end |
end |
||
return data --and once we've processed all the data we send the data table back up to main for the formatting |
|||
mw.log(string.format('SMW: entries %d, time elapsed: %.3f ms.', #smwData, (t2 - t1) * 1000)) |
|||
return smwData |
|||
end |
end |
||
function processData(item) --this breaks up the smwdata bit into manageable little bites |
|||
-- JSON data dump entry-point |
|||
local name = item[1] or '' --this gets the item name, which by default is in the first position of the query results (lua starts at 1, not 0) |
|||
function p.dumpData(frame) |
|||
local |
local _name = string.match(name, '|(.-)%]') |
||
return p._dumpData(args) |
|||
local members = item['Is members only'] --members we have to do a bit extra for |
|||
end |
|||
if members == true then --if it is members, we use the members star |
|||
members = p2pIcon |
|||
function p._dumpData(args) |
|||
elseif members == false then --if not, use f2p star |
|||
local slot = args.slot |
|||
members = f2pIcon |
|||
assert(contains(slotOptions, slot), 'Invalid slot specified') |
|||
else |
|||
members = '' |
|||
local data = loadData(slot, true) |
|||
-- Tests indicate that JSON pretty-printing increases the size by a factor of 1.78. |
|||
-- Removing indenting results in an increase in size by a factor of 1.15. |
|||
-- The latter is a very reasonable trade-off to make the files more wiki-friendly. |
|||
local prefix = string.format('-- Data for item slot \'%s\' @ %s.\n-- Generated by Module:Slottable, function dumpData()\nreturn mw.text.jsonDecode([=[\n', slot, os.date('%F %T', os.time())) |
|||
local rawjson = mw.text.jsonEncode(data, mw.text.JSON_PRETTY) |
|||
local jsondata, subst = rawjson:gsub('\n%s+', '\n') |
|||
local postfix = '\n]=])\n' |
|||
mw.log(string.format('Dumping JSON data for item slot \'%s\'. Raw size: %d bytes, formatted size: %d bytes (factor: %.2f).', slot, rawjson:len(), jsondata:len(), jsondata:len() / rawjson:len())) |
|||
return prefix .. jsondata .. postfix |
|||
end |
|||
-- Turtle data dump entry-point |
|||
function p.dumpDataTTL(frame) |
|||
local args = frame:getParent().args |
|||
return p._dumpDataTTL(args) |
|||
end |
|||
function p._dumpDataTTL(args) |
|||
local slot = args.slot |
|||
assert(contains(slotOptions, slot), 'Invalid slot specified') |
|||
local data = loadData(slot, true) |
|||
local slot_ |
|||
if(slot == "2h") then |
|||
slot_ = "zweihander" |
|||
else |
|||
slot_ = slot |
|||
end |
|||
local prefix = string.format('# Data for item slot \'%s\' @ %s.\n# Generated by Module:Slottable, function dumpDataTTL()\n\n', slot, os.date('%F %T', os.time())) |
|||
prefix = prefix .. "@prefix " .. slot_ .. ": <http://oldschool.runescape.wiki/rdf/" .. slot_ .. "/> .\n" |
|||
prefix = prefix .. "@prefix prop: <http://oldschool.runescape.wiki/rdf/prop/> .\n\n" |
|||
local ttlData = "" |
|||
for _, i in ipairs(data) do |
|||
ttlData = ttlData .. slot_ .. ":" .. _ .. " " .. "prop:slot \"" .. slot_ .. "\"; " |
|||
local outl = {} |
|||
for k, v in pairs(i) do |
|||
if((k == "image") or (k == "name") or (k == "variantof")) then |
|||
table.insert(outl, "prop:" .. k .. " \"" .. tostring(v) .. "\"") |
|||
else |
|||
table.insert(outl, "prop:" .. k .. " " .. tostring(v)) |
|||
end |
|||
end |
|||
ttlData = ttlData .. table.concat(outl, "; ") .. " .\n" |
|||
end |
end |
||
local |
local image = item['Image'] or '' |
||
if type(image) == 'table' then |
|||
mw.log(string.format('Dumping Turtle data for item slot \'%s\'. Size: %d bytes.', slot, ttlData:len())) |
|||
image = image[1] -- take the first image available |
|||
end |
|||
return prefix .. ttlData .. postfix |
|||
image = string.match(image, '[Ff]ile:.-%.png') or '' |
|||
end |
|||
if image ~= '' then |
|||
image = string.format('[[%s|link=%s]]', image, _name) |
|||
function p._main(args) |
|||
local slot = string.lower(paramTest.default_to(args.slot, '')) |
|||
local members = string.lower(paramTest.default_to(args.members, 'all')) |
|||
assert(contains(slotOptions, slot), 'Invalid slot specified') |
|||
assert(contains(memberOptions, members), 'Invalid members status specified') |
|||
local beta = yesNo(paramTest.default_to(args.beta, false), false) |
|||
local discontinued = yesNo(paramTest.default_to(args.discontinued, false), false) |
|||
local dmm = yesNo(paramTest.default_to(args.dmm, false), false) |
|||
local emir = yesNo(paramTest.default_to(args.emir, false), false) |
|||
local failedPoll = yesNo(paramTest.default_to(args.failedpoll, false), false) |
|||
local gauntlet = yesNo(paramTest.default_to(args.beta, false), false) |
|||
local lms = yesNo(paramTest.default_to(args.lms, false), false) |
|||
local quest = yesNo(paramTest.default_to(args.quest, true), true) |
|||
-- UIM specific tables, that only display items that can be: |
|||
-- purchased, stored in the POH, or stored in STASH untsi |
|||
local uim = yesNo(paramTest.default_to(args.uim, false), false) |
|||
local attackSpeed = false |
|||
if((slot == '2h') or (slot == 'weapon')) then |
|||
attackSpeed = true |
|||
end |
end |
||
local data = loadData(slot, attackSpeed, members, uim) |
|||
data = filterData(data, slot, {members = members, uim = uim, beta = beta, discontinued = discontinued, dmm = dmm, emir = emir, failedPoll = failedPoll, gauntlet = gauntlet, lms = lms, quest = quest }) |
|||
local keyset="" |
|||
local ret = createHeader(slot, attackSpeed, uim) |
|||
local n=0 |
|||
for _, item in ipairs(data) do |
|||
ret:node(buildRow(item, attackSpeed, uim)) |
|||
for k,v in pairs(item) do |
|||
n=n+1 |
|||
keyset = keyset .. k .. " (" .. tostring(v) ..")" .. ":" |
|||
end |
end |
||
return { --now we return the processed data for this item back to the getData function, which sends us another item and repeats until we've done them all |
|||
return ret |
|||
name = name, |
|||
image = image, |
|||
members = members, |
|||
astab = item['Stab attack bonus'] or '', |
|||
aslash = item['Slash attack bonus'] or '', |
|||
acrush = item['Crush attack bonus'] or '', |
|||
amagic = item['Magic attack bonus'] or '', |
|||
arange = item['Range attack bonus'] or '', |
|||
dstab = item['Stab defence bonus'] or '', |
|||
dslash = item['Slash defence bonus'] or '', |
|||
dcrush = item['Crush defence bonus'] or '', |
|||
dmagic = item['Magic defence bonus'] or '', |
|||
drange = item['Range defence bonus'] or '', |
|||
str = item['Strength bonus'] or '', |
|||
rstr = item['Ranged Strength bonus'] or '', |
|||
mdmg = item['Magic Damage bonus'] or keyset, |
|||
prayer = item['Prayer bonus'] or '', |
|||
weight = item['Weight'] or '', |
|||
} |
|||
end |
end |
||
p.getData = getData |
|||
function p.main(frame) |
|||
local args = frame:getParent().args |
|||
return p._main(args) |
|||
end |
|||
--[[ DEBUG |
|||
mw.logObject(p.getData('weapon')) |
|||
p._main({slot='weapon', members='all'}) |
|||
p._dumpData({slot='weapon'}) |
|||
p._dumpDataTTL({slot='weapon'}) |
|||
--]] |
|||
return p |
return p |
Latest revision as of 11:22, 17 October 2024
Documentation for this module may be created at Module:EmberFantasy/sandbox/Slottable/doc
-- <pre>
require('Module:Mw.html extension')
local p = {}
local format = require('Module:Format equipment stat').format --for formatting the stats with + and - symbols on output
local p2pIcon = '[[File:Member icon.png|frameless|link=Pay-to-play]]' --these icons are for the later members/f2p stars
local f2pIcon = '[[File:Free-to-play icon.png|frameless|link=Free-to-play]]'
local stats = {'astab', 'aslash', 'acrush', 'amagic', 'arange', 'dstab', 'dslash', 'dcrush', 'dmagic', 'drange', 'str', 'rstr', 'mdmg', 'prayer'}
function p.main(frame)
local args = frame:getParent().args --get the input from the template
local slot = string.lower(tostring(args['slot'])) --take the slot input as the slot we want the table for
local mems = args['mems']
local dmm = args['dmm']
local beta = args['beta']
local data = getData(slot,mems,dmm,beta) --this takes the slot and sends it to our getData function (seen below) which gives us back a data table
local restbl = mw.html.create('table') --start making our results table, beginninig with the header
restbl:addClass('wikitable align-center-1 sortable align-center')
:tag('tr')
:tag('th'):addClass('unsortable'):wikitext(''):done()
:tag('th'):wikitext('Name'):done()
:tag('th'):wikitext('Members'):done()
:tag('th'):wikitext('[[File:White dagger.png|Stab attack]]') :done()
:tag('th'):wikitext('[[File:White scimitar.png|Slash attack]]') :done()
:tag('th'):wikitext('[[File:White warhammer.png|Crush attack]]') :done()
:tag('th'):wikitext('[[File:Magic icon.png|Magic attack]]') :done()
:tag('th'):wikitext('[[File:Ranged icon.png|Ranged attack]]') :done()
:tag('th'):wikitext('[[File:White dagger.png|Stab defence]]<sup>[[File:Defence icon.png]]</sup>') :done()
:tag('th'):wikitext('[[File:White scimitar.png|Slash defence]]<sup>[[File:Defence icon.png]]</sup>') :done()
:tag('th'):wikitext('[[File:White warhammer.png|Crush defence]]<sup>[[File:Defence icon.png]]</sup>') :done()
:tag('th'):wikitext('[[File:Magic icon.png|Magic defence]]<sup>[[File:Defence icon.png]]</sup>') :done()
:tag('th'):wikitext('[[File:Ranged icon.png|Ranged defence]]<sup>[[File:Defence icon.png]]</sup>') :done()
:tag('th'):wikitext('[[File:Strength icon.png|Strength]]') :done()
:tag('th'):wikitext('[[File:Ranged Strength icon.png|Ranged Strength]]') :done()
:tag('th'):wikitext('[[File:Magic Damage icon.png|Magic Damage]]') :done()
:tag('th'):wikitext('[[File:Prayer icon.png|Prayer]]') :done()
:tag('th'):wikitext('Weight') :done()
:done()
-- Create the rows for the output table
for _, item in ipairs(data) do --for each row of data, we take it and split it up, then put it into our table row. We also format them with + and - symbols here
local row = restbl:tag('tr')
:tag('td'):wikitext(item.image):done()
:tag('td'):wikitext(item.name):done()
:tag('td'):wikitext(item.members):done()
for _, stat in ipairs(stats) do
local value = item[stat]
local value_num = tonumber(value)
row:tag('td'):wikitext(format(value))
:addClassIf(value_num and (value_num > 0), 'table-positive')
:addClassIf(value_num and (value_num < 0), 'table-negative')
end
row:tag('td'):wikitext(item.weight):done()
end
return tostring(restbl) --returns the table back to the template to be put onto the page
end
function getData(slotName,mems,dmm,beta) --so this is the function that takes the slot name and gets all the data for the items
--first we set up our SMW query
local q = {
'[[Equipment slot::'..slotName..']]', --we want everything that matches the slot we called, and then all the attached data below
'?Is members only',
'?Stab attack bonus',
'?Slash attack bonus',
'?Crush attack bonus',
'?Magic attack bonus',
'?Range attack bonus',
'?Stab defence bonus',
'?Slash defence bonus',
'?Crush defence bonus',
'?Magic defence bonus',
'?Range defence bonus',
'?Strength bonus',
'?Ranged Strength bonus',
'?Magic Damage bonus',
'?Prayer bonus',
'?Category',
'?Image',
'?Weight',
limit = 1000,
order = 'ascending'
}
local smwdata = mw.smw.ask(q) --this now asks the smw for all the data, and saves all of it in smwdata
local data = {} --setting this table up to insert processed data into
for _, item in ipairs(smwdata) do --for each item we found with our smw query
local process = true
local dmmcat = false
local betacat = false
if type(item['Category']) == 'table' then
for _, category in ipairs(item['Category']) do
if category == "[[:Category:Deadman seasonal items|Deadman seasonal items]]" then
dmmcat = true
elseif category == "[[:Category:Beta items|Beta items]]" then
betacat = true
end
end
end
if mems == 'Members' then
if not item['Is members only'] then
process = false
end
end
if mems == 'F2P' then
if item['Is members only'] then
process = false
end
end
if dmm == 'No' then
if dmmcat == true then
process = false
end
end
if beta == 'No' then
if betacat == true then
process = false
end
end
if process then
local dataline = processData(item) --we process it (seen below) and then save it as a line
table.insert(data, dataline) --and then we insert that line into our data table to be returned
end
end
return data --and once we've processed all the data we send the data table back up to main for the formatting
end
function processData(item) --this breaks up the smwdata bit into manageable little bites
local name = item[1] or '' --this gets the item name, which by default is in the first position of the query results (lua starts at 1, not 0)
local _name = string.match(name, '|(.-)%]')
local members = item['Is members only'] --members we have to do a bit extra for
if members == true then --if it is members, we use the members star
members = p2pIcon
elseif members == false then --if not, use f2p star
members = f2pIcon
else
members = ''
end
local image = item['Image'] or ''
if type(image) == 'table' then
image = image[1] -- take the first image available
end
image = string.match(image, '[Ff]ile:.-%.png') or ''
if image ~= '' then
image = string.format('[[%s|link=%s]]', image, _name)
end
local keyset=""
local n=0
for k,v in pairs(item) do
n=n+1
keyset = keyset .. k .. " (" .. tostring(v) ..")" .. ":"
end
return { --now we return the processed data for this item back to the getData function, which sends us another item and repeats until we've done them all
name = name,
image = image,
members = members,
astab = item['Stab attack bonus'] or '',
aslash = item['Slash attack bonus'] or '',
acrush = item['Crush attack bonus'] or '',
amagic = item['Magic attack bonus'] or '',
arange = item['Range attack bonus'] or '',
dstab = item['Stab defence bonus'] or '',
dslash = item['Slash defence bonus'] or '',
dcrush = item['Crush defence bonus'] or '',
dmagic = item['Magic defence bonus'] or '',
drange = item['Range defence bonus'] or '',
str = item['Strength bonus'] or '',
rstr = item['Ranged Strength bonus'] or '',
mdmg = item['Magic Damage bonus'] or keyset,
prayer = item['Prayer bonus'] or '',
weight = item['Weight'] or '',
}
end
p.getData = getData
return p