Module:Infobox Item: Difference between revisions

From Discord Dungeons Wiki
Jump to navigation Jump to search
No edit summary
No edit summary
 
(48 intermediate revisions by the same user not shown)
Line 1: Line 1:
--------------------------
--------------------------
-- Module for [[Template:Infobox Item]]
-- Module for [[Template:Infobox Item]]
--
-- Todo:
-- * Text on drop
-- * Equipable
-- * Tool info (skill levels etc)
--
------------------------
------------------------
local p = {}
local p = {}


local infobox = require('Module:Infobox')
local infobox = require('Module:Experimental/Infobox')
local onmain = require('Module:Mainonly').on_main
local onmain = require('Module:Mainonly').on_main
local commas = require('Module:Addcommas')._add
local commas = require('Module:Addcommas')._add
Line 14: Line 20:


ret:defineParams{
ret:defineParams{
--- General  
--- General --
{ name = 'name', func = 'name' },
{ name = 'name', func = 'name' },
{ name = 'version', func = 'has_content' },
{ name = 'aka', func = 'has_content' },
{ name = 'image', func = 'image' },
{ name = 'image', func = 'image' },
{ name = 'image_smw', func = { name = image_smw, params = { 'image' }, flag = 'p' } },
{ name = 'release', func = 'release' },
{ name = 'id', func = 'number' },
{ name = 'description', func = 'has_content' },
{ name = 'members', func = 'yes_no' },
{ name = 'donator', func = 'yes_no' },
{ name = 'level', func = 'number' },
{ name = 'cost', func = 'has_content' }, -- Todo: Unbuyable
{ name = 'sell', func = 'has_content' }, -- Todo: Unsellable


{ name = 'release', func = 'release' },
-- Properties --
{ name = 'removal', func = 'removal' },
{ name = 'members', func = 'has_content' },
{ name = 'tradeable', func = 'yes_no' },
{ name = 'craftable', func = 'yes_no' },
{ name = 'brewable', func = 'yes_no' },
{ name = 'quest', func = 'has_content' },
{ name = 'quest', func = 'has_content' },


{ name = 'tradeable', func = tradeablearg },
-- Market values --
{ name = 'equipable', func = 'has_content' },
 
{ name = 'usable', func = 'has_content' },
{ name = 'market_sp_limit', func = 'has_content' }, -- sell price
{ name = 'market_bp_limit', func = 'has_content' }, -- buy price
-- Item type Properties --
 
{ name = 'type', func = 'has_content' }, -- Item type


{ name = 'buyvalue', func = 'has_content' },
-- Potion Params --
{ name = 'sellvalue', func = 'has_content' },


{ name = 'potion_type', func = 'has_content' },
{ name = 'potion_effect', func = 'has_content' },


-- css class name to hide rows on undefined versions
-- Book Params --
{ name = 'market_sell_limit', func = 'has_content'},
{ name = 'market_buy_limit', func = 'has_content' },


{ name = 'book_author', func = 'has_content' },
-- Armor Params --
{ name = 'damage_blocked', func = 'has_content' },
-- Rune Params --
{ name = 'rune_tp', func = 'has_content' },
-- Weapon Params --
{ name = 'damage', func = 'has_content' },
{ name = 'weapon_effect', func = 'has_content' },
-- Tool Params --
{ name = 'tool_type', func = 'has_content' },
{ name = 'skill_level', func = 'has_content' },
{ name = 'tool_effect', func = 'has_content' },
-- Side item --
{ name = 'forage_level', func = 'has_content' },
{ name = 'mine_level', func = 'has_content' },
{ name = 'fish_level', func = 'has_content' },
{ name = 'chop_level', func = 'has_content' },
{ name = 'ring_effect', func = 'has_content' },
{ name = 'necklace_effect', func = 'has_content' },


        { name = 'usesinfobox', func = { name = tostring, params = { 'Item' }, flag = 'r' } },
{ name = 'id', func = 'has_content' },
}
}


ret:setMaxButtons(7)
ret:setMaxButtons(7)
ret:create()
ret:create()
ret:cleanParams()
ret:cleanParams()
ret:customButtonPlacement(true)
ret:customButtonPlacement(true)
Line 54: Line 99:
ret:useSMWOne({
ret:useSMWOne({
members = 'All Is members only',
members = 'All Is members only',
id_smw = 'All Item ID',
id_smw = 'All Item id',
image_smw = 'All Image',
image_smw = 'All Image',
})
})


ret:useSMWSubobject({
ret:useSMWSubobject({
version = 'Version anchor',
image = 'Image',
release = 'Release date',
release = 'Release date',
id_smw = 'Item ID',
id = 'Item ID',
description = 'Description',
description = 'Description',
members = 'Is members only',
members = 'Is members only',
buyvalue = 'Buyable for',
donator = 'Is donator item',
sellvalue = 'Sellable for',
level = 'Item Level',
image_smw = 'Image',
cost = 'Buyable for',
market_buy_limit = 'Buy limits',
sell = 'Sellable for',
market_sell_limit = 'Sell limits',
usesinfobox = 'Uses infobox',
tradeable = 'Tradeable',
craftable = 'Craftable',
brewable = 'Brewabel',
market_sp_limit = 'Market sell limits',
market_bp_limit = 'Market buy limits',
type = 'Item Type',
potion_type = 'Potion type',
potion_effect = 'Potion effect',
 
book_author = 'Book author',
rune_tp = 'Rune teleport',
damage = 'Damage',
weapon_effect = 'Weapon effect',
tool_type = 'Tool type',
skill_level = 'Tool skill level',
tool_effect = 'Tool effect',
 
forage_level = 'Forage level',
mine_level = 'Mine level',
fish_level = 'Fish level',
chop_level = 'Chop level',
 
ring_effect = 'Ring effect',
necklace_effect = 'Necklace effect',
})
})


Line 76: Line 146:
ret:defineName('Infobox Item')
ret:defineName('Infobox Item')
ret:addClass('infobox-item')
ret:addClass('infobox-item')
 
ret:addRow{
ret:addRow{
{ tag = 'argh', content = 'name', class='infobox-header', colspan = '20' }
{ tag = 'argh', content = 'name', class = 'infobox-header', colspan = '20' }
}
:pad(20)
:addRow{
{ tag = 'argd', content = 'image', class = 'infobox-image infobox-full-width-content', colspan = '20' }
}
:addRow{
{ tag = 'argd', content = 'description', class = 'infobox-desription infobox-full-width-content', colspan = '20' }
}
}
:pad(20)
:pad(20)
:addRow{
:addRow{
{ tag = 'argd', content = 'image', class = 'infobox-image inventory-image infobox-full-width-content', colspan = '20' }
{ tag = 'th', content = 'ID', colspan = '7' },
{ tag = 'argd', content = 'id', colspan = '13' },
}
:pad(20)
:addRow{
{ tag = 'th', content = 'Type', colspan = '7' },
{ tag = 'argd', content = 'type', colspan = '13' },
}
}
:pad(20)
:pad(20)
:addRow{
:addRow{
{ tag = 'th', content = 'Released', colspan = '7' },
{ tag = 'th', content = 'Released', colspan = '7' },
{ tag = 'argd', content = 'release', colspan = '13' }
{ tag = 'argd', content = 'release', colspan = '13' },
}
}
 
:pad(20)
if ret:paramDefined('removal') then
:addRow{
ret:addRow{
{ tag = 'th', content = 'Removal', colspan = '7' },
{ tag = 'argd', content = 'removal', colspan = '13' }
}
end
 
if ret:paramDefined('aka') then
ret:addRow{
{ tag = 'th', content = 'Also called', colspan = '7' },
{ tag = 'argd', content = 'aka', colspan = '13' }
}
end
 
ret:addRow{
{ tag = 'th', content = '[[Members]]', colspan = '7' },
{ tag = 'th', content = '[[Members]]', colspan = '7' },
{ tag = 'argd', content = 'members', colspan = '13' }
{ tag = 'argd', content = 'members', colspan = '13' },
}
}
:pad(20)
:addRow{
:addRow{
{ tag = 'th', content = '[[Quest items|Quest item]]', colspan = '7' },
{ tag = 'th', content = 'Donator item', colspan = '7' },
{ tag = 'argd', content = 'quest', colspan = '13' }
{ tag = 'argd', content = 'donator', colspan = '13' },
}
}
:pad(20)
:pad(20)
:addRow{
:addRow{
{ tag = 'th', content = 'Properties', class = 'infobox-subheader', colspan = '20' }
{ tag = 'th', content = 'Level', colspan = '7' },
{ tag = 'argd', content = 'level', colspan = '13' },
}
}
:pad(20)
:pad(20)
:addRow{
:addRow{
{ tag = 'th', content = '[[Items#Tradeability|Tradeable]]', colspan = '7' },
{ tag = 'th', content = 'Buy Price', colspan = '7' },
{ tag = 'argd', content = 'tradeable', colspan = '13' }
{ tag = 'argd', content = 'cost', colspan = '13' },
}
}
 
:pad(20)
if ret:paramDefined('bankable') then
:addRow{
ret:addRow{
{ tag = 'th', content = 'Sell Price', colspan = '7' },
{ tag = 'th', content = '[[Bank]]able', colspan = '7' },
{ tag = 'argd', content = 'sell', colspan = '13' },
{ tag = 'argd', content = 'bankable', colspan = '13' }
}
end
 
ret:addRow{
{ tag = 'th', content = '[[Worn Equipment|Equipable]]', colspan = '7' },
{ tag = 'argd', content = 'equipable', colspan = '13' }
}
}
--[[
Add rows for properties
]]
:pad(20)
:addRow{
:addRow{
{ tag = 'th', content = '[[Stackable items|Stackable]]', colspan = '7' },
{ tag = 'th', content = 'Properties', class = 'infobox-subheader', colspan = '20' },
{ tag = 'argd', content = 'stackable', colspan = '13' }
}
}


:pad(20)
:addRow{
{ tag = 'th', content = 'Tradeable', colspan = '7' },
{ tag = 'argd', content = 'tradeable', colspan = '13' },
}
ret:pad(20)
:pad(20)
:addRow{
{ tag = 'th', content = 'Craftable', colspan = '7' },
{ tag = 'argd', content = 'craftable', colspan = '13' },
}


ret:addRow{
:pad(20)
{ tag = 'th', content = 'Advanced data', class = 'infobox-subheader', colspan = '20' },
:addRow{
meta = {addClass = 'advanced-data'}
{ tag = 'th', content = 'Brewable', colspan = '7' },
{ tag = 'argd', content = 'brewable', colspan = '13' },
}
}
:pad(20, 'advanced-data')
 
:pad(20)
:addRow{
:addRow{
{ tag = 'th', content = 'Item ID', colspan = '7' },
{ tag = 'th', content = '[[Quests|Quest]]', colspan = '7' },
{ tag = 'argd', content = 'id', colspan = '13' },
{ tag = 'argd', content = 'quest', colspan = '13' },
meta = {addClass = 'advanced-data'}
}
}
:pad(20, 'advanced-data')


if onmain() then
--[[
local a1 = ret:param('all')
Add rows for Market stuff
local a2 = ret:categoryData()
]]
ret:wikitext(addcategories(a1, a2))
 
local hasMarketSPLimit = ret:paramDefined('market_sp_limit')
local hasMarketBPLimit = ret:paramDefined('market_bp_limit')
 
if hasMarketSPLimit or hasMarketBPLimit then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Market Limits', class = 'infobox-subheader', colspan = '20' },
}
 
if hasMarketSPLimit then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Sell Price', colspan = '7' },
{ tag = 'argd', content = 'market_sp_limit', colspan = '13' },
}
end
 
if hasMarketBPLimit then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Buy Price', colspan = '7' },
{ tag = 'argd', content = 'market_bp_limit', colspan = '13' },
}
end
end
 
--[[
Add rows for potion stuff
]]
 
local hasPotionType = ret:paramDefined('potion_type')
local hasPotionEffect = ret:paramDefined('potion_effect')
 
if hasPotionType or hasPotionEffect then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Potion Info', class = 'infobox-subheader', colspan = '20' },
}
 
if hasPotionType then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Type', colspan = '7' },
{ tag = 'argd', content = 'potion_type', colspan = '13' },
}
end
 
if hasPotionEffect then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Effect', colspan = '7' },
{ tag = 'argd', content = 'potion_effect', colspan = '13' },
}
end
end
 
--[[
Add rows for armor stuff
]]
 
if ret:paramDefined('damage_blocked') then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Armor', class = 'infobox-subheader', colspan = '20' },
}
:pad(20)
:addRow{
{ tag = 'th', content = 'Damage blocked', colspan = '7' },
{ tag = 'argd', content = 'damage_blocked', colspan = '13' },
}
end
 
--[[
Add rows for book stuff
]]
 
if ret:paramDefined('book_author') then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Book', class = 'infobox-subheader', colspan = '20' },
}
:pad(20)
:addRow{
{ tag = 'th', content = 'Author', colspan = '7' },
{ tag = 'argd', content = 'book_author', colspan = '13' },
}
end
 
--[[
Add rows for rune stuff
]]
 
if ret:paramDefined('rune_tp') then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Rune', class = 'infobox-subheader', colspan = '20' },
}
:pad(20)
:addRow{
{ tag = 'th', content = 'Teleports to', colspan = '7' },
{ tag = 'argd', content = 'rune_tp', colspan = '13' },
}
end
 
--[[
Add rows for weapon stuff
]]
 
if ret:paramDefined('damage') then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Weapon', class = 'infobox-subheader', colspan = '20' },
}
:pad(20)
:addRow{
{ tag = 'th', content = 'Damage', colspan = '7' },
{ tag = 'argd', content = 'damage', colspan = '13' },
}
 
if ret:paramDefined('weapon_effect') then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Effect', colspan = '7' },
{ tag = 'argd', content = 'weapon_effect', colspan = '13' },
}
end
end
end
--[[
Add rows for tool stuff
]]


return ret:tostring()
if ret:paramDefined('tool_type') and string.lower(ret:param('tool_type', 'd')) == "fishing rod" then
end
addToolRows(ret, 'Fishing Rod')
end


function tradeablearg(arg)
if ret:paramDefined('tool_type') and string.lower(ret:param('tool_type', 'd')) == "pickaxe" then
if not infobox.isDefined(arg) then
addToolRows(ret, 'Pickaxe')
return nil
end
end


arg = string.lower(arg)
if ret:paramDefined('tool_type') and string.lower(ret:param('tool_type', 'd')) == "axe" then
if arg == 'yes' then
addToolRows(ret, 'Axe')
return 'Yes'
elseif arg == 'no' then
return 'No'
end
end
return arg
end


-- Return raw value as a number, or nil if not defined
if ret:paramDefined('tool_type') and string.lower(ret:param('tool_type', 'd')) == "shears" then
function valraw(arg)
addToolRows(ret, 'Shears')
if not infobox.isDefined(arg) then
return nil
end
end


return tonumber(arg)
end


function valuearg(value)
--[[
if not infobox.isDefined(value) then
Add rows for ring stuff
return nil
]]
 
if ret:paramDefined('ring_effect') then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Ring', class = 'infobox-subheader', colspan = '20' },
}
:pad(20)
:addRow{
{ tag = 'th', content = 'Effect', colspan = '7' },
{ tag = 'argd', content = 'ring_effect', colspan = '13' },
}
end
end


return plural('coin', value)
--[[
end
Add rows for necklace stuff
]]


-- split items with multiple images for smw (e.g. [[File:Arrow 1.png]] [[File:Arrow 2.png]])
if ret:paramDefined('necklace_effect') then
function image_smw(arg)
ret:pad(20)
local _img = {}
:addRow{
for i in string.gmatch(arg, "[Ff]ile:.-%.png") do
{ tag = 'th', content = 'Necklace', class = 'infobox-subheader', colspan = '20' },
table.insert(_img, i)
}
:pad(20)
:addRow{
{ tag = 'th', content = 'Effect', colspan = '7' },
{ tag = 'argd', content = 'necklace_effect', colspan = '13' },
}
end
end
if #_img == 0 then
 
return nil
 
 
--[[
Add rows for sides
]]
 
if ret:paramDefined('forage_level') then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Forage', class = 'infobox-subheader', colspan = '20' },
}
:pad(20)
:addRow{
{ tag = 'th', content = 'Level', colspan = '7' },
{ tag = 'argd', content = 'forage_level', colspan = '13' },
}
end
end
return table.concat(_img, '&&SPLITPOINT&&')
end


if ret:paramDefined('mine_level') then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Mine', class = 'infobox-subheader', colspan = '20' },
}
:pad(20)
:addRow{
{ tag = 'th', content = 'Level', colspan = '7' },
{ tag = 'argd', content = 'mine_level', colspan = '13' },
}
end


function idsmw(id)
if ret:paramDefined('fish_level') then
if not infobox.isDefined(id) then
ret:pad(20)
return nil
:addRow{
{ tag = 'th', content = 'Fish', class = 'infobox-subheader', colspan = '20' },
}
:pad(20)
:addRow{
{ tag = 'th', content = 'Level', colspan = '7' },
{ tag = 'argd', content = 'fish_level', colspan = '13' },
}
end
end
return string.gsub(id, ',', '&&SPLITPOINT&&')
end


-- red ERR span with title hover for explanation
if ret:paramDefined('chop_level') then
function badarg(argname, argmessage)
ret:pad(20)
return '<span '..
:addRow{
'title="The parameter «'..argname..'» '..argmessage..'" '..
{ tag = 'th', content = 'Chop', class = 'infobox-subheader', colspan = '20' },
'style="color:red; font-weight:bold; cursor:help; border-bottom:1px dotted red;">'..
}
'ERR</span>'
:pad(20)
end
:addRow{
{ tag = 'th', content = 'Level', colspan = '7' },
{ tag = 'argd', content = 'chop_level', colspan = '13' },
}
end


function plural(word, amount, alt_plural_word)
if onmain() then
local output_amount = commas(tonumber(amount) or 1)
local a1 = ret:param('all')
if tonumber(amount) == 1 then
local a2 = ret:categoryData()
return string.format('%s %s', output_amount, word)
ret:wikitext(addcategories(a1, a2))
elseif alt_plural_word then
return string.format('%s %s', output_amount, alt_plural_word)
else
return string.format('%s %ss', output_amount, word)
end
end
ret:finish()
return ret:tostring()
end
end


function has_three_decimals(weight)
function addToolRows(ret, title)
local decimals = string.match(weight, "%.(.*)")
ret:pad(20)
if not decimals then
:addRow{
return false
{ tag = 'th', content = title, class = 'infobox-subheader', colspan = '20' },
}
:pad(20)
:addRow{
{ tag = 'th', content = 'Type', colspan = '7' },
{ tag = 'argd', content = 'tool_type', colspan = '13' },
}
:pad(20)
:addRow{
{ tag = 'th', content = 'Skill Level', colspan = '7' },
{ tag = 'argd', content = 'skill_level', colspan = '13' },
}
 
if ret:paramDefined('tool_effect') then
ret:pad(20)
:addRow{
{ tag = 'th', content = 'Tool Effect', colspan = '7' },
{ tag = 'argd', content = 'tool_effect', colspan = '13' },
}
end
end
return string.len(decimals) == 3
end
end


Line 245: Line 512:
-- Added if the parameter has content
-- Added if the parameter has content
defined = {
defined = {
aka = 'Pages with AKA'
aka = 'Pages with AKA',
forage_level = 'Forageable Items',
mine_level = 'Mineable Items',
fish_level = 'Fishable Items',
chop_level = 'Choppable Items',
},
},
-- Added if the parameter has no content
-- Added if the parameter has no content
notdefined = {
notdefined = {
image = 'Needs image',
image = 'Needs image',
release = 'Needs release date',
id = 'Needs ID',
description = 'Needs description',
members = 'Needs members status',
members = 'Needs members status',
release = 'Needs release date',
description = 'Needs description added',
level = 'Needs level',
level = 'Needs level',
buyvalue = 'Items missing buy price',
cost = 'Items missing cost',
sellvalue = 'Items missing sell price',
sell = 'Items missing sell',
 
value = 'Items missing value',
quest = 'Items missing quest',
quest = 'Items missing quest',
id = 'Needs ID',
craftable = 'Needs craftable status',
market_sell_limit = 'Needs sell limit',
brewable = 'Needs brewable status',
market_buy_limit = 'Needs buy limit',
type = 'Needs Type',
},
},
-- Parameters that have text
-- Parameters that have text
Line 265: Line 539:
matches = {
matches = {
members = { yes = 'Members\' items', no = 'Free-to-play items' },
members = { yes = 'Members\' items', no = 'Free-to-play items' },
equipable = { yes = 'Equipable items' },
donator = { yes = 'Donator items' },
edible = { yes = 'Edible items' },
rune_tp = { yes = 'Runes'},
tradeable = { yes = 'Tradeable items', no = 'Untradeable items' },
tradeable = { yes = 'Tradeable items', no = 'Untradeable items' },
craftable = { yes = 'Craftable items', no = 'Uncraftable items' },
brewable = { yes = 'Brewable items' },
type = {
['book'] = 'Books',
['boots'] = {'Armor', 'Boots'},
['chest'] = {'Armor', 'Chestplates'},
['chestplate'] = {'Armor', 'Chestplates'},
['dummy'] = 'Dummy Items',
['fish'] = 'Fishes',
['gem'] = 'Gems',
['gemstone'] = 'Gems',
['helm'] = {'Armor', 'Helmets'},
['helmet'] = {'Armor', 'Helmets'},
['log'] = 'Logs',
['necklace'] = 'Necklaces',
['ore'] = 'Ores',
['potion'] = 'Potions',
['ring'] = 'Rings',
['rune'] = 'Runes',
['sapling'] = 'Saplings',
['seed'] = 'Saplings',
['tool'] = 'Tools',
['trap'] = 'Traps',
['weapon'] = 'Weapons',
},
tool_type = {
['fishing_rod'] = 'Fishing Rods',
['fishing rod'] = 'Fishing Rods',
['rod'] = 'Fishing Rods',
['fishingRod'] = 'Fishing Rods',
['axe'] = 'Axes',
['pickaxe'] = 'Pickaxes',
['shears'] = 'Shears',
},
potion_type = {
['healing'] = {'Healing Potions', 'Healing Items'},
['effect'] = {'Effect Potions'},
}
}
}
}
}
Line 320: Line 640:
table.insert(ret, 'Needs ID')
table.insert(ret, 'Needs ID')
end
end


-- combine table and format category wikicode
-- combine table and format category wikicode
for i, v in ipairs(ret) do
for i, v in ipairs(ret) do
ret[i] = string.format('[[Category:%s]]', v)
if type(v) == 'string' then
ret[i] = string.format('[[Category:%s]]', v)
else
local catString = ''
 
for i2, v2 in ipairs(v) do
catString = catString .. string.format('[[Category:%s]]', v2)
end
 
ret[i] = catString
end
end
end


return table.concat(ret, '')
return table.concat(ret, '')
end
end


return p
return p

Latest revision as of 11:21, 6 April 2022

Documentation for this module may be created at Module:Infobox Item/doc

--------------------------
-- Module for [[Template:Infobox Item]]
--
-- Todo:
-- * Text on drop
-- * Equipable
-- * Tool info (skill levels etc)
--
------------------------
local p = {}

local infobox = require('Module:Experimental/Infobox')
local onmain = require('Module:Mainonly').on_main
local commas = require('Module:Addcommas')._add
VariablesLua = mw.ext.VariablesLua

function p.main(frame)
	local args = frame:getParent().args
	local ret = infobox.new(args)

	ret:defineParams{
		--- General --
		{ name = 'name', func = 'name' },
		{ name = 'image', func = 'image' },
		{ name = 'release', func = 'release' },
		{ name = 'id', func = 'number' },
		{ name = 'description', func = 'has_content' },
		{ name = 'members', func = 'yes_no' },
		{ name = 'donator', func = 'yes_no' },
		{ name = 'level', func = 'number' },
		{ name = 'cost', func = 'has_content' }, -- Todo: Unbuyable
		{ name = 'sell', func = 'has_content' }, -- Todo: Unsellable

		-- Properties --
		
		{ name = 'tradeable', func = 'yes_no' },
		{ name = 'craftable', func = 'yes_no' },
		{ name = 'brewable', func = 'yes_no' },
		{ name = 'quest', func = 'has_content' },

		-- Market values --

		{ name = 'market_sp_limit', func = 'has_content' }, -- sell price
		{ name = 'market_bp_limit', func = 'has_content' }, -- buy price
		
		-- Item type Properties --

		{ name = 'type', func = 'has_content' }, -- Item type

		-- Potion Params --

		{ name = 'potion_type', func = 'has_content' },
		{ name = 'potion_effect', func = 'has_content' },

		-- Book Params --

		{ name = 'book_author', func = 'has_content' },

		-- Armor Params --

		{ name = 'damage_blocked', func = 'has_content' },

		-- Rune Params --

		{ name = 'rune_tp', func = 'has_content' },
		-- Weapon Params --

		{ name = 'damage', func = 'has_content' },
		{ name = 'weapon_effect', func = 'has_content' },
		
		-- Tool Params --
		
		{ name = 'tool_type', func = 'has_content' },
		{ name = 'skill_level', func = 'has_content' },
		{ name = 'tool_effect', func = 'has_content' },

		-- Side item --

		{ name = 'forage_level', func = 'has_content' },
		{ name = 'mine_level', func = 'has_content' },
		{ name = 'fish_level', func = 'has_content' },
		{ name = 'chop_level', func = 'has_content' },

		{ name = 'ring_effect', func = 'has_content' },
		{ name = 'necklace_effect', func = 'has_content' },

	}

	ret:setMaxButtons(7)
	ret:create()
	
	ret:cleanParams()
	ret:customButtonPlacement(true)
	ret:setDefaultVersionSMW(true)


	ret:defineLinks({ hide = true })

	ret:useSMWOne({
		members = 'All Is members only',
		id_smw = 'All Item id',
		image_smw = 'All Image',
	})

	ret:useSMWSubobject({
		image = 'Image',
		release = 'Release date',
		id = 'Item ID',
		description = 'Description',
		members = 'Is members only',
		donator = 'Is donator item',
		level = 'Item Level',
		cost = 'Buyable for',
		sell = 'Sellable for',
		
		tradeable = 'Tradeable',
		craftable = 'Craftable',
		brewable = 'Brewabel',
		
		market_sp_limit = 'Market sell limits',
		market_bp_limit = 'Market buy limits',
		type = 'Item Type',
	
		potion_type = 'Potion type',
		potion_effect = 'Potion effect',

		book_author = 'Book author',
		rune_tp = 'Rune teleport',
		damage = 'Damage',
		weapon_effect = 'Weapon effect',
		tool_type = 'Tool type',
		skill_level = 'Tool skill level',
		tool_effect = 'Tool effect',

		forage_level = 'Forage level',
		mine_level = 'Mine level',
		fish_level = 'Fish level',
		chop_level = 'Chop level',

		ring_effect = 'Ring effect',
		necklace_effect = 'Necklace effect',
	})

	ret:addButtonsCaption()

	ret:defineName('Infobox Item')
	ret:addClass('infobox-item')
	
	ret:addRow{
		{ tag = 'argh', content = 'name', class = 'infobox-header', colspan = '20' }
	}
	:pad(20)
	:addRow{
		{ tag = 'argd', content = 'image', class = 'infobox-image infobox-full-width-content', colspan = '20' }
	}
	:addRow{
		{ tag = 'argd', content = 'description', class = 'infobox-desription infobox-full-width-content', colspan = '20' }
	}
	:pad(20)
	:addRow{
		{ tag = 'th', content = 'ID', colspan = '7' },
		{ tag = 'argd', content = 'id', colspan = '13' },
	}
	:pad(20)
	:addRow{
		{ tag = 'th', content = 'Type', colspan = '7' },
		{ tag = 'argd', content = 'type', colspan = '13' },
	}
	:pad(20)
	:addRow{
		{ tag = 'th', content = 'Released', colspan = '7' },
		{ tag = 'argd', content = 'release', colspan = '13' },
	}
	:pad(20)
	:addRow{
		{ tag = 'th', content = '[[Members]]', colspan = '7' },
		{ tag = 'argd', content = 'members', colspan = '13' },
	}
	:pad(20)
	:addRow{
		{ tag = 'th', content = 'Donator item', colspan = '7' },
		{ tag = 'argd', content = 'donator', colspan = '13' },
	}
	:pad(20)
	:addRow{
		{ tag = 'th', content = 'Level', colspan = '7' },
		{ tag = 'argd', content = 'level', colspan = '13' },
	}
	:pad(20)
	:addRow{
		{ tag = 'th', content = 'Buy Price', colspan = '7' },
		{ tag = 'argd', content = 'cost', colspan = '13' },
	}
	:pad(20)
	:addRow{
		{ tag = 'th', content = 'Sell Price', colspan = '7' },
		{ tag = 'argd', content = 'sell', colspan = '13' },
	}
	
	--[[
		Add rows for properties
	]]
	:pad(20)
	:addRow{
		{ tag = 'th', content = 'Properties', class = 'infobox-subheader', colspan = '20' },
	}

	:pad(20)
	:addRow{
		{ tag = 'th', content = 'Tradeable', colspan = '7' },
		{ tag = 'argd', content = 'tradeable', colspan = '13' },
	}
	
	:pad(20)
	:addRow{
		{ tag = 'th', content = 'Craftable', colspan = '7' },
		{ tag = 'argd', content = 'craftable', colspan = '13' },
	}

	:pad(20)
	:addRow{
		{ tag = 'th', content = 'Brewable', colspan = '7' },
		{ tag = 'argd', content = 'brewable', colspan = '13' },
	}

	:pad(20)
	:addRow{
		{ tag = 'th', content = '[[Quests|Quest]]', colspan = '7' },
		{ tag = 'argd', content = 'quest', colspan = '13' },
	}

	--[[
		Add rows for Market stuff
	]]

	local hasMarketSPLimit = ret:paramDefined('market_sp_limit')
	local hasMarketBPLimit = ret:paramDefined('market_bp_limit')

	if hasMarketSPLimit or hasMarketBPLimit then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Market Limits', class = 'infobox-subheader', colspan = '20' },
		}

		if hasMarketSPLimit then
			ret:pad(20)
			:addRow{
				{ tag = 'th', content = 'Sell Price', colspan = '7' },
				{ tag = 'argd', content = 'market_sp_limit', colspan = '13' },
			}
		end

		if hasMarketBPLimit then
			ret:pad(20)
			:addRow{
				{ tag = 'th', content = 'Buy Price', colspan = '7' },
				{ tag = 'argd', content = 'market_bp_limit', colspan = '13' },
			}
		end
	end

	--[[
		Add rows for potion stuff
	]]

	local hasPotionType = ret:paramDefined('potion_type')
	local hasPotionEffect = ret:paramDefined('potion_effect')

	if hasPotionType or hasPotionEffect then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Potion Info', class = 'infobox-subheader', colspan = '20' },
		}

		if hasPotionType then
			ret:pad(20)
			:addRow{
				{ tag = 'th', content = 'Type', colspan = '7' },
				{ tag = 'argd', content = 'potion_type', colspan = '13' },
			}
		end

		if hasPotionEffect then
			ret:pad(20)
			:addRow{
				{ tag = 'th', content = 'Effect', colspan = '7' },
				{ tag = 'argd', content = 'potion_effect', colspan = '13' },
			}
		end
	end

	--[[
		Add rows for armor stuff
	]]

	if ret:paramDefined('damage_blocked') then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Armor', class = 'infobox-subheader', colspan = '20' },
		}
		:pad(20)
		:addRow{
			{ tag = 'th', content = 'Damage blocked', colspan = '7' },
			{ tag = 'argd', content = 'damage_blocked', colspan = '13' },
		}
	end

	--[[
		Add rows for book stuff
	]]

	if ret:paramDefined('book_author') then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Book', class = 'infobox-subheader', colspan = '20' },
		}
		:pad(20)
		:addRow{
			{ tag = 'th', content = 'Author', colspan = '7' },
			{ tag = 'argd', content = 'book_author', colspan = '13' },
		}
	end

	--[[
		Add rows for rune stuff
	]]

	if ret:paramDefined('rune_tp') then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Rune', class = 'infobox-subheader', colspan = '20' },
		}
		:pad(20)
		:addRow{
			{ tag = 'th', content = 'Teleports to', colspan = '7' },
			{ tag = 'argd', content = 'rune_tp', colspan = '13' },
		}
	end

	--[[
		Add rows for weapon stuff
	]]

	if ret:paramDefined('damage') then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Weapon', class = 'infobox-subheader', colspan = '20' },
		}
		:pad(20)
		:addRow{
			{ tag = 'th', content = 'Damage', colspan = '7' },
			{ tag = 'argd', content = 'damage', colspan = '13' },
		}

		if ret:paramDefined('weapon_effect') then
			ret:pad(20)
			:addRow{
				{ tag = 'th', content = 'Effect', colspan = '7' },
				{ tag = 'argd', content = 'weapon_effect', colspan = '13' },
			}
		end
	end
	
	--[[
		Add rows for tool stuff
	]]

	if ret:paramDefined('tool_type') and string.lower(ret:param('tool_type', 'd')) == "fishing rod" then
		addToolRows(ret, 'Fishing Rod')
	end

	if ret:paramDefined('tool_type') and string.lower(ret:param('tool_type', 'd')) == "pickaxe" then
		addToolRows(ret, 'Pickaxe')
	end

	if ret:paramDefined('tool_type') and string.lower(ret:param('tool_type', 'd')) == "axe" then
		addToolRows(ret, 'Axe')
	end

	if ret:paramDefined('tool_type') and string.lower(ret:param('tool_type', 'd')) == "shears" then
		addToolRows(ret, 'Shears')
	end
	


	--[[
		Add rows for ring stuff
	]]

	if ret:paramDefined('ring_effect') then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Ring', class = 'infobox-subheader', colspan = '20' },
		}
		:pad(20)
		:addRow{
			{ tag = 'th', content = 'Effect', colspan = '7' },
			{ tag = 'argd', content = 'ring_effect', colspan = '13' },
		}
	end

	--[[
		Add rows for necklace stuff
	]]

	if ret:paramDefined('necklace_effect') then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Necklace', class = 'infobox-subheader', colspan = '20' },
		}
		:pad(20)
		:addRow{
			{ tag = 'th', content = 'Effect', colspan = '7' },
			{ tag = 'argd', content = 'necklace_effect', colspan = '13' },
		}
	end



	--[[
		Add rows for sides
	]]

	if ret:paramDefined('forage_level') then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Forage', class = 'infobox-subheader', colspan = '20' },
		}
		:pad(20)
		:addRow{
			{ tag = 'th', content = 'Level', colspan = '7' },
			{ tag = 'argd', content = 'forage_level', colspan = '13' },
		}
	end

	if ret:paramDefined('mine_level') then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Mine', class = 'infobox-subheader', colspan = '20' },
		}
		:pad(20)
		:addRow{
			{ tag = 'th', content = 'Level', colspan = '7' },
			{ tag = 'argd', content = 'mine_level', colspan = '13' },
		}
	end

	if ret:paramDefined('fish_level') then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Fish', class = 'infobox-subheader', colspan = '20' },
		}
		:pad(20)
		:addRow{
			{ tag = 'th', content = 'Level', colspan = '7' },
			{ tag = 'argd', content = 'fish_level', colspan = '13' },
		}
	end

	if ret:paramDefined('chop_level') then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Chop', class = 'infobox-subheader', colspan = '20' },
		}
		:pad(20)
		:addRow{
			{ tag = 'th', content = 'Level', colspan = '7' },
			{ tag = 'argd', content = 'chop_level', colspan = '13' },
		}
	end
	

	if onmain() then
		local a1 = ret:param('all')
		local a2 = ret:categoryData()
		ret:wikitext(addcategories(a1, a2))
	end

	ret:finish()

	return ret:tostring()
end

function addToolRows(ret, title)
	ret:pad(20)
	:addRow{
		{ tag = 'th', content = title, class = 'infobox-subheader', colspan = '20' },
	}
	:pad(20)
	:addRow{
		{ tag = 'th', content = 'Type', colspan = '7' },
		{ tag = 'argd', content = 'tool_type', colspan = '13' },
	}
	:pad(20)
	:addRow{
		{ tag = 'th', content = 'Skill Level', colspan = '7' },
		{ tag = 'argd', content = 'skill_level', colspan = '13' },
	}

	if ret:paramDefined('tool_effect') then
		ret:pad(20)
		:addRow{
			{ tag = 'th', content = 'Tool Effect', colspan = '7' },
			{ tag = 'argd', content = 'tool_effect', colspan = '13' },
		}
	end
end

function addcategories(args, catargs)
	local ret = { 'Items' }
	local cat_map = {
		-- Added if the parameter has content
		defined = {
			aka = 'Pages with AKA',
			forage_level = 'Forageable Items',
			mine_level = 'Mineable Items',
			fish_level = 'Fishable Items',
			chop_level = 'Choppable Items',
		},
		-- Added if the parameter has no content
		notdefined = {
			image = 'Needs image',
			release = 'Needs release date',
			id = 'Needs ID',
			description = 'Needs description',
			members = 'Needs members status',
			level = 'Needs level',
			cost = 'Items missing cost',
			sell = 'Items missing sell',

			value = 'Items missing value',
			quest = 'Items missing quest',
			craftable = 'Needs craftable status',
			brewable = 'Needs brewable status',
			type = 'Needs Type',
		},
		-- Parameters that have text
		-- map a category to a value
		matches = {
			members = { yes = 'Members\' items', no = 'Free-to-play items' },
			donator = { yes = 'Donator items' },
			rune_tp = { yes = 'Runes'},
			tradeable = { yes = 'Tradeable items', no = 'Untradeable items' },
			craftable = { yes = 'Craftable items', no = 'Uncraftable items' },
			brewable = { yes = 'Brewable items' },
			type = {
				['book'] = 'Books',

				['boots'] = {'Armor', 'Boots'},
				['chest'] = {'Armor', 'Chestplates'},
				['chestplate'] = {'Armor', 'Chestplates'},

				['dummy'] = 'Dummy Items',
				
				['fish'] = 'Fishes',
				
				['gem'] = 'Gems',
				['gemstone'] = 'Gems',
				
				['helm'] = {'Armor', 'Helmets'},
				['helmet'] = {'Armor', 'Helmets'},
				
				['log'] = 'Logs',
				['necklace'] = 'Necklaces',
				['ore'] = 'Ores',
				['potion'] = 'Potions',
				['ring'] = 'Rings',
				['rune'] = 'Runes',
				['sapling'] = 'Saplings',
				['seed'] = 'Saplings',

				['tool'] = 'Tools',
				['trap'] = 'Traps',

				['weapon'] = 'Weapons',
			},
			tool_type = {
				['fishing_rod'] = 'Fishing Rods',
				['fishing rod'] = 'Fishing Rods',
				['rod'] = 'Fishing Rods',
				['fishingRod'] = 'Fishing Rods',
				['axe'] = 'Axes',
				['pickaxe'] = 'Pickaxes',
				['shears'] = 'Shears',
			},
			potion_type = {
				['healing'] = {'Healing Potions', 'Healing Items'},
				['effect'] = {'Effect Potions'},
			}
		}
	}

	-- defined categories
	for n, v in pairs(cat_map.defined) do
		if catargs[n] and catargs[n].one_defined then
			table.insert(ret, v)
		end
	end

	-- undefined categories
	for n, v in pairs(cat_map.notdefined) do
		if catargs[n] and catargs[n].all_defined == false then
			table.insert(ret, v)
		end
	end

	-- searches
	for n, v in pairs(cat_map.matches) do
		for m, w in pairs(v) do
			if args[n] then
				if string.lower(tostring(args[n].d) or '') == m then
					table.insert(ret, w)
				end
				if args[n].switches then
					for _, x in ipairs(args[n].switches) do
						if string.lower(tostring(x)) == m then
							table.insert(ret, w)
						end
					end
				end
			end
		end
	end

	-- quest items
	-- just look for a link
	if args.quest.d:find('%[%[') then
		table.insert(ret, 'Quest items')
	elseif args.quest.switches then
		for _, v in ipairs(args.quest.switches) do
			if v:find('%[%[') then
				table.insert(ret, 'Quest items')
				break
			end
		end
	end

	-- ids
	if not catargs.id.all_defined then
		table.insert(ret, 'Needs ID')
	end

	-- combine table and format category wikicode
	for i, v in ipairs(ret) do
		if type(v) == 'string' then
			ret[i] = string.format('[[Category:%s]]', v)
		else
			local catString = ''

			for i2, v2 in ipairs(v) do
				catString = catString .. string.format('[[Category:%s]]', v2)
			end

			ret[i] = catString
		end
	end

	return table.concat(ret, '')
end


return p