Module:EmberFantasy/sandbox/Slottable: Difference between revisions

From RuneRealm Wiki
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 statFormat(_arg, default)
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('td'):wikitext('[[' .. item.name .. ']]'):done()
:tag('th'):addClass('unsortable'):wikitext(''):done()
:tag('td'):wikitext(item.members and '[[File:Member icon.png|link=|Members]]' or '[[File:Free-to-play icon.png|link=|Free-to-play]]'):done()
: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
row:tag('td'):wikitext(item.speed):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
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 header = tabl:tag('tr')
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(options.uim) then
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(keep) then
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 args = frame:getParent().args
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 postfix = '\n\n'
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