mNo edit summary |
mNo edit summary |
||
Line 343: | Line 343: | ||
else |
else |
||
f = '' |
f = '' |
||
− | for w in string.gmatch( |
+ | for w in string.gmatch(v, '([^,]+)') do |
w = w:gsub("^%s*(.-)%s*$", "%1") |
w = w:gsub("^%s*(.-)%s*$", "%1") |
||
− | + | w2 = string.lower(w) |
|
+ | if w2 == 'passive' then |
||
f = f .. '\n* [[Passive effect]]' |
f = f .. '\n* [[Passive effect]]' |
||
− | elseif |
+ | elseif w2 == 'time' then |
f = f .. '\n* Time remaining' |
f = f .. '\n* Time remaining' |
||
− | elseif |
+ | elseif w2 == 'degrade' then |
f = f .. '\n* [[Degradation]]' |
f = f .. '\n* [[Degradation]]' |
||
− | elseif |
+ | elseif w2 == 'items' then |
f = f .. '\n* Items consumed' |
f = f .. '\n* Items consumed' |
||
− | elseif |
+ | elseif w2 == 'urn' then |
f = f .. '\n* Percentage filled' |
f = f .. '\n* Percentage filled' |
||
else |
else |
Revision as of 18:20, 13 November 2017
Documentation for this module may be created at Module:Infobox Item/doc
-- <pre>
-- ( ͡° ͜ʖ ͡°)
local p = {}
-- "imports"
local infobox = require('Module:Infobox')
local onmain = require('Module:Mainonly').on_main
local paramtest = require('Module:Paramtest')
local commas = require('Module:Addcommas')._add
local exchange = require('Module:Exchange')
-- Main function called with invokes
function p.main(frame)
local args = frame:getParent().args
local ret = infobox.new(args)
-- Parameter definitions
ret:defineParams{
{ name = 'name', func = 'name' },
{ name = 'aka', func = 'has_content' },
{ name = 'image', func = 'image' },
-- release and removal
-- removal only shown if it exists
{ name = 'release', func = 'release' },
{ name = 'removal', func = 'removal' },
{ name = 'removaldisp', func = { name = removaldisp, params = { 'removal' } }, dupes = true },
{ name = 'members', func = 'has_content' },
{ name = 'tooltip', func = tooltiparg },
{ name = 'examine', func = 'has_content' },
{ name = 'quest', func = 'has_content' },
{ name = 'tradeable', func = tradeablearg },
{ name = 'equipable', func = 'has_content' },
-- bankable; only show if "No"; default to "Yes"
{ name = 'bankable', func = { name = 'has_content', params = { 'bankable', 'Yes'}, flag = { 'd', 'r' } } },
{ name = 'bankabledisp', func = { name = yesnodisp, params = { 'bankable', 'no' }, flag = { 'd', 'r' } }, dupes = true },
-- stacksinbank; only show if "No"; default to "Yes"
{ name = 'stacksinbank', func = { name = 'has_content', params = { 'stacksinbank', 'Yes'}, flag = { 'd', 'r' } } },
{ name = 'stacksinbankdisp', func = { name = yesnodisp, params = { 'stacksinbank', 'no' }, flag = { 'd', 'r' } }, dupes = true },
-- lendable; only show if "Yes"; default to "No"
{ name = 'lendable', func = { name = 'has_content', params = { 'lendable', 'No'}, flag = { 'd', 'r' } } },
{ name = 'lendabledisp', func = { name = yesnodisp, params = { 'lendable' } }, dupes = true },
{ name = 'stackable', func = 'has_content' },
{ name = 'disassembly', func = disassemblyarg },
-- edible; only show if "Yes"; default to "No"
{ name = 'edible', func = { name = 'has_content', params = { 'edible', 'No'}, flag = { 'd', 'r' } } },
{ name = 'edibledisp', func = { name = yesnodisp, params = { 'edible' } }, dupes = true },
-- noteable; only show if "Yes"; default to "No"
{ name = 'noteable', func = { name = 'has_content', params = { 'noteable', 'No'}, flag = { 'd', 'r' } } },
{ name = 'noteabledisp', func = { name = yesnodisp, params = { 'noteable' } }, dupes = true },
{ name = 'destroy', func = 'has_content' },
{ name = 'store', func = storearg },
{ name = 'val', func = { name = valraw, params = { 'value' }, flag = 'p' }, dupes = true },
{ name = 'value', func = { name = valuearg, params = { 'val', 'convert' }, flag = { 'd', 'p' } } },
-- gemw prices
-- only displayed if they exist
--dupes must exist for individual prices to have them display properly
{ name = 'gemw', func = { name = gemwarg, params = { 'exchange', 'tradeable' }, flag = {'p', 'd'} } },
{ name = 'gemwname', func = { name = gemwnamearg, params = { 'name', 'gemwname' } } },
{ name = 'gemwprice', func = { name = gemwpricearg, params = { 'gemw', 'gemwname' } }, dupes = true },
{ name = 'exchange', func = { name = exchangearg, params = { 'gemwprice', 'gemwname' } }, dupes = true },
{ name = 'graph', func = { name = gemwgrapharg, params = { 'gemwprice', 'gemwname' } }, dupes = true },
{ name = 'buylimit', func = { name = buylimitarg, params = { 'gemwprice', 'gemwname' } }, dupes = true },
-- used for both exchange and graphs
{ name = 'gemwdisp', func = { name = gemwdisp, params = { 'gemwprice' } }, dupes = true },
{ name = 'kept', func = { name = keptondeatharg, params = { 'kept', 'ikod', 'reclaim', 'sacrifice', 'val', 'gemwprice' }, flag = { 'p', 'p', 'p', 'd', 'd' } } },
-- alchemy
{ name = 'alchable', func = { name = alchablearg, params = { 'alchable', 'high', 'low' }, flag = 'p' }, dupes = true },
{ name = 'alchmultiplier', func = multiplierarg },
{ name = 'high', func = { name = alchvalues, params = { 'val', 'high', 'alchmultiplier', 1, 'alchable' }, flag = { 'd', 'p', 'd', 'r', 'd' } } },
{ name = 'low', func = { name = alchvalues, params = { 'val', 'low', 'alchmultiplier', 2/3, 'alchable' }, flag = { 'd', 'p', 'd', 'r', 'd' } } },
{ name = 'weight', func = weightarg },
{ name = 'weightraw', func = { name = weightargraw, params = { 'weight' }, flag = 'p' } },
-- not used; only for categories
{ name = 'id', func = 'numbers' },
{ name = 'rscid', func = 'numbers' }
}
ret:setMaxButtons(7)
ret:create()
ret:cleanParams()
-- parameter linkings for hidden rows
ret:linkParams{
{ 'removal', 'removaldisp' },
{ 'exchange', 'gemwdisp' },
{ 'graph', 'gemwdisp' },
{ 'buylimit', 'gemwdisp' },
{ 'bankable', 'bankabledisp' },
{ 'stacksinbank', 'stacksinbankdisp' },
{ 'lendable', 'lendabledisp' },
{ 'noteable', 'noteabledisp' },
{ 'edible', 'edibledisp' }
}
ret:defineLinks({ { 'Template:%s/FAQ', 'FAQ' },
{ 'Template:%s/doc', 'doc' } })
ret:useSMW({
id = 'Item ID',
val = 'Value',
weightraw = 'Weight',
})
ret:caption()
ret:defineName('Infobox Item')
ret:addClass('infobox-item')
-- PARAMETER: image
ret:addRow{
{ tag = 'argd', content = 'image', class = 'infobox-image', colspan = '2' } }
-- PARAMETER: release
-- (update included automatically by infobox)
:addRow{ { tag = 'th', content = 'Release' },
{ tag = 'argd', content = 'release' } }
-- PARAMETER: removal
if ret:paramDefined('removal') then
ret:addRow{ { tag = 'th', content = 'Removal' },
{ tag = 'argd', content = 'removal' } }
end
-- PARAMETER: aka
-- add only if it exists
if ret:paramDefined('aka') then
ret:addRow{ { tag = 'th', content = '[[Slang dictionary|AKA]]' },
{ tag = 'argd', content = 'aka' } }
end
-- PARAMETER: members
ret:addRow{
{ tag = 'th', content = '[[Members]]' },
{ tag = 'argd', content = 'members' } }
-- PARAMETER: quest
:addRow{
{ tag = 'th', content = '[[Quest items|Quest item]]' },
{ tag = 'argd', content = 'quest' } }
-- PARAMETER: tradeable
:addRow{
{ tag = 'th', content = '[[Items#Tradeability|Tradeable]]' },
{ tag = 'argd', content = 'tradeable' } }
-- PARAMETER: bankable
if ret:paramGrep('bankable','no') then
ret:addRow{
{ tag = 'th', content = '[[Bank]]able' },
{ tag = 'argd', content = 'bankable' } }
end
-- PARAMETER: stacksinbank
if ret:paramGrep('stacksinbank','no') then
ret:addRow{
{ tag = 'th', content = 'Stacks in bank' },
{ tag = 'argd', content = 'stacksinbank' } }
end
-- PARAMETER: lendable
if ret:paramGrep('lendable','yes') then
ret:addRow{
{ tag = 'th', content = '[[Item Lending|Lendable]]' },
{ tag = 'argd', content = 'lendable' } }
end
-- PARAMETER: equipable
ret:addRow{
{ tag = 'th', content = '[[Equipment|Equipable]]' },
{ tag = 'argd', content = 'equipable' } }
-- PARAMETER: stackable
:addRow{
{ tag = 'th', content = '[[Stackable items|Stackable]]' },
{ tag = 'argd', content = 'stackable' } }
-- PARAMETER: disassembly
:addRow{
{ tag = 'th', content = '[[Disassemble|Disassembly]]' },
{ tag = 'argd', content = 'disassembly' } }
-- PARAMETER: noteable
if ret:paramGrep('noteable','yes') then
ret:addRow{
{ tag = 'th', content = '[[Note|Noteable]]' },
{ tag = 'argd', content = 'noteable' } }
end
-- PARAMETER: edible
if ret:paramGrep('edible','yes') then
ret:addRow{
{ tag = 'th', content = '[[Food|Edible]]' },
{ tag = 'argd', content = 'edible' } }
end
-- PARAMETER: value
ret:addRow{
{ tag = 'th', content = '[[Value]]' },
{ tag = 'argd', content = 'value' } }
-- PARAMETER: alchable | high | low
-- find if any version is alchable
local anyalchable = ret:paramGrep('alchable',true)
-- if any are alchable, add both rows
if anyalchable == true then
ret:addRow{
{ tag = 'th', content = '[[High Level Alchemy|High alch]]' },
{ tag = 'argd', content = 'high' } }
:addRow{
{ tag = 'th', content = '[[Low Level Alchemy|Low alch]]' },
{ tag = 'argd', content = 'low' } }
else
-- otherwise add a single "no alch" row
ret:addRow{
{ tag = 'th', content = '[[Alchemy]]' },
{ tag = 'td', content = 'Not alchemisable' } }
end
-- PARAMETER: destroy
ret:addRow{
{ tag = 'th', content = '[[Destroy (action)|Destroy]]' },
{ tag = 'argd', content = 'destroy', css = { ['max-width'] = '200px' } } }
-- PARAMETER: death
ret:addRow{
{ tag = 'th', content = '[[Items Kept on Death|On death]]' },
{ tag = 'argd', content = 'kept' } }
-- find if we have any exchange prices
local anygemw = ret:paramGrep('gemwprice', function(_arg) return _arg > 0 end)
-- if we have any on the ge, add the gemw row
if anygemw == true then
-- PARAMETER: exchange | gemwname
ret:addRow{
{ tag = 'th', content = '[[RuneScape:Grand Exchange Market Watch|Exchange]]' },
{ tag = 'argd', content = 'exchange' } }
:addRow{
{ tag = 'th', content = '[[Grand Exchange#Trade restrictions|Buy limit]]' },
{ tag = 'argd', content = 'buylimit' } }
end
-- PARAMETER: weight
ret:addRow{
{ tag = 'th', content = '[[Weight]]' },
{ tag = 'argd', content = 'weight' } }
-- PARAMETER: tooltip
if ret:paramDefined('tooltip') then
ret:addRow{
{ tag = 'th', content = 'Tooltip' },
{ tag = 'argd', content = 'tooltip' } }
end
-- PARAMETER: examine
ret:addRow{
{ tag = 'th', content = '[[Examine]]' },
{ tag = 'argd', content = 'examine', css = { ['max-width'] = '200px' } } }
-- PARAMETER: graph
if anygemw == true then
ret:addRow{ { tag = 'argd', content = 'graph', colspan = '2', css = { ['text-align'] = 'center', ['padding'] = '0', ['background-color'] = 'white' } },
meta = { addClass = 'hidden' } }
end
if onmain() then
local a1 = ret:param('all')
local a2 = ret:categoryData()
ret:wikitext(addcategories(a1,a2))
end
return ret:tostring()
end
-- Store price
function storearg(store, currency, seller)
-- remove any commas
store = string.gsub(store or '',',','')
-- no for not sold
if string.lower(store) == 'no' then
return 'Not sold'
else
store = tonumber(store,10)
end
if type(store) == 'number' then
return store
else
return nil
end
end
-- tradeable
-- tradeablearg(value)
function tradeablearg(v)
v = string.lower(v or '')
if v == 'yes' or v == 'no' then
v = mw.text.split(v,'')
v[1] = string.upper(v[1])
return table.concat(v,'')
elseif v == 'restricted' then
return '[[Restricted trade items|Restricted]]'
else
return nil
end
end
-- disassembly
-- disassemblyarg(yes/no)
function disassemblyarg(d)
d = string.lower(d or '')
if d == 'yes' then
return '[[#DisassemblyT|Yes]]' -- Unique anchor ID created by {{Disassembly}}
elseif d == 'no' then
return 'No'
elseif d == 'restricted' then
return '[[:Category:Location restricted disassembly|Restricted]]'
elseif d == 'na' or d == 'n/a' or d == 'discontinued' or d == 'irrelevant' then
return 'N/A'
else
return nil
end
end
-- tooltip
-- tooltiparg(v)
function tooltiparg(v)
d = string.lower(v or '')
if d == 'no' or d == '' then
return null
else
f = ''
for w in string.gmatch(v, '([^,]+)') do
w = w:gsub("^%s*(.-)%s*$", "%1")
w2 = string.lower(w)
if w2 == 'passive' then
f = f .. '\n* [[Passive effect]]'
elseif w2 == 'time' then
f = f .. '\n* Time remaining'
elseif w2 == 'degrade' then
f = f .. '\n* [[Degradation]]'
elseif w2 == 'items' then
f = f .. '\n* Items consumed'
elseif w2 == 'urn' then
f = f .. '\n* Percentage filled'
else
f = f .. '\n* ' .. w
end
end
if f == '' then
return null
else
return f
end
end
end
-- value
-- separate number storage for operation
-- valraw(value)
function valraw(v)
local _ v = v or ''
_v = string.gsub(v,',','')
return tonumber(v,10)
end
-- value
-- valuearg(value, convert)
-- actual value already parsed
function valuearg(v,c)
-- replace commas and turn into a number
if paramtest.has_content(c) then
c = string.gsub(c,',','')
c = tonumber(c,10)
else
c = nil
end
v = tonumber(v,10)
-- if both are defined, show both, value first
if v and c then
return string.format('%s<br/><b>Cash out:</b><br/>%s',plural('coin',v),plural('coin',c))
-- if only value is defined, show just that
elseif v and not c then
return plural('coin',v)
-- if only convert is defined, show just that
-- may need to change this so that value is requested
elseif c and not v then
return string.format('<b>Cash out:</b><br/>%s',plural('coin',c))
else
return nil
end
end
-- Alchables
-- alchablearg(alchable, high, low)
function alchablearg(a,h,l)
-- not alchable if both are false, or if "alchable" is false
if string.lower(a or '') == 'no' then
return false
elseif string.lower(h or '') == 'no' and string.lower(l or '') == 'no' then
return false
else
return true
end
end
-- alch multiplier arg
-- only accepts numbers
-- defaults to .6
function multiplierarg(v)
return tonumber(v) or .6
end
-- high/low alch
-- alchvalues(value, override value, multiplier, alchable)
-- actual value already parsed
-- value, template param, alch multiplier, override multiplier, not alchable bool
function alchvalues(v,_p,a,m,n)
-- remove commas and turn into a number
v = tonumber(v,10)
if paramtest.has_content(_p) then
_p = string.gsub(_p,',','')
_p = tonumber(_p,10)
else
_p = nil
end
-- return override always
if type(_p) == 'number' then
return plural('coin',_p)
end
-- if you can't alch it, return this
-- used in the case of 1 version being alchable and the other not
if n == false then
return 'Not alchemisable'
end
-- otherwise try the value and multiply it
if v then
local r = math.floor(killRoundingError(v * m * a))
return plural('coin',r)
end
return nil
end
-- weight
-- weightarg(weight)
function weightarg(w)
if paramtest.has_content(w) then
-- replace all "kg" and spaces here
w = string.gsub(w or '','[kg ]','')
-- replace hyphen with minus sign
w = string.gsub(w,'-','−')
-- use non-breaking spaces and html entities for display
-- still necessary to convert the "kg" to html?
return string.format('%s kg',w)
end
return nil
end
-- weightargraw(weight)
function weightargraw(w)
if paramtest.has_content(w) then
-- replace all "kg" and spaces here
w = string.gsub(w or '','[kg ]','')
return tonumber(w)
end
return nil
end
-- on ge or not
-- only accepts "gemw"
-- gemwarg(exchange,tradeable)
function gemwarg(arg,arg2)
g = string.lower(arg or '')
return arg2 == 'Yes' and g == 'gemw'
end
-- gemw names
-- gemwnamearg(name, override name)
function gemwnamearg(n,a)
-- return override
if a and a:find('%S') then
return string.gsub(a,'</?span>','')
-- otherwise use the "name" parameter
elseif n and n:find('%S') then
return string.gsub(n,'</?span>','')
-- default to page name
else
return mw.title.getCurrentTitle().fullText
end
end
-- separate thing to hold all the prices as raw numbers
-- gemwpricearg(gemw, name)
function gemwpricearg(g,n)
if g == true then
-- return price if page is found
-- -1 for errors
if exchange._exists(n) then
return tonumber(exchange._price(n),10) or -1
else
return -1
end
-- 0 for no price
else
return 0
end
end
-- exchange display
-- exchangearg(gemw price, name)
-- uses the already fetched ge price to operate
-- values less than 1 are used for parsing instructions
function exchangearg(g,n)
if type(g) ~= 'number' then
g = tonumber(g,10) or 0
end
-- 0 for not sold
if g == 0 then
return '<span class="infobox-quantity" data-val-each="0">Not sold</span>'
-- -1 for no page found
elseif g == -1 then
return badarg('exchange','was set to «gemw» but no page was found for «'..n..'».')
-- all other numbers
elseif g > 0 then
-- plural done in format because we need a span around the value
return string.format('<span class="infobox-quantity" data-val-each="%s"><span class="infobox-quantity-replace">%s</span> coin%s ([[Exchange:%s|info]])</span>',g,commas(g),g>1 and 's' or '',n)
-- not a number = nil
-- shouldn't be used, but it's a fallback
else
return 0
end
end
-- ge graphs
-- gemwgrapharg(gemw price, name)
-- uses the already fetched ge price to operate
-- values less than 1 are used for parsing instructions
function gemwgrapharg(g,n)
if type(g) ~= 'number' then
g = tonumber(g,10) or 0
end
-- 0 for not sold an
-- -1 for error
-- call to hide the graph
if g == 0 or g == -1 then
return 'No data to display'
-- all other numbers
elseif g > 0 then
-- TODO: Change Module:ExchangeData and give it a proper graph function
-- remove reliance on frame
return mw.getCurrentFrame():preprocess(string.format('{{GEChart|%s|size=small}}',n))
-- not a number = nil
-- shouldn't be used, but it's a fallback
else
return nil
end
end
-- ge buy limits
-- buylimitarg(gemw price, name)
-- uses the already fetched ge price to operate
-- values less than 1 are used for parsing instructions
function buylimitarg(g,n)
if type(g) ~= 'number' then
g = tonumber(g,10) or 0
end
-- 0 for not sold an
-- -1 for error
-- call to hide the graph
if g == 0 or g == -1 then
return '-'
-- all other numbers
elseif g > 0 then
local ret = exchange._limit(n)
if ret == nil then
return '-'
else
return commas(ret)
end
-- not a number = nil
-- shouldn't be used, but it's a fallback
else
return nil
end
end
-- class names based on value
-- gemwdisp(price)
function gemwdisp(_p)
if _p == 0 then
return ''
else
return 'infobox-cell-shown'
end
end
-- Shows if the param matches the alt
-- alt defaults to yes
-- Everything else = hide
function yesnodisp(arg, alt)
arg = string.lower(arg or '')
alt = string.lower(alt or 'yes')
if arg == alt then
return 'infobox-cell-shown'
else
return ''
end
end
-- Shows if has a date
function removaldisp(arg)
if string.find(arg or '','%[%[') then
return 'infobox-cell-shown'
else
return ''
end
end
-- death
-- keptondeatharg(death, override value, override reclaim, override sacrifice, value, gemwprice)
function keptondeatharg(d,_i,_r,_s,v,g)
d = string.lower(d or '')
v = tonumber(v,10)
-- items always lost
if d == 'never' then
return 'Always lost'
-- items always kept unless in the wilderness
elseif d == 'always' then
return 'Always kept outside [[Wilderness|Wild]]'
elseif d == 'alwaysinclwild' then
return 'Always kept'
elseif d == 'dropped' then
return 'Dropped on death'
elseif d == 'safe' then
return 'Always a safe death'
-- returns a nil value to force it to use gemw
elseif d == 'gemwdegrade' then
return nil
-- reclaimable items
elseif d == 'reclaimable' then
local i
-- all other items display reclaim and sacrifice
-- if overridden ikod value, display that as well
-- default is to show this
local ret = { 'Reclaimable' }
-- replace commas and convert to number
if paramtest.has_content(_i) then
i = string.gsub(_i,',','')
i = tonumber(i,10)
else
i = nil
end
-- if i is defined, show that value
if i then
table.insert(ret,string.format('<b>Value:</b> %s',commas(i)))
-- test geprice next
elseif (tonumber(g,10) or 0) > 0 then
i = g
-- test value next
elseif v then
i = v
end
-- otherwise give up
if not tonumber(i,10) then
return i
end
-- reclaim cost is based on the death value of an item
-- sacrifice is 4 x reclaim
-- sacrifice value is a function of reclaim and not the original number
-- this is evident by the fact that items with a death value of 1 have a sacrifice value of 4
-- reclaim, sacrifice
local r,s
-- test for overridden reclaim
if paramtest.has_content(_r) then
_r = string.gsub(_r,',','')
r = tonumber(_r)
end
-- if no number, use formula
if not r then
-- less than 10,000: .15x
if i < 10000 then
r = math.floor(i * .15)
-- all items cost at least 1 coin, so round back up if 0
if r == 0 then
r = 1
end
--[[
Death formula
]]
-- 10,000 to 49,999: 500 + 0.1x
elseif i >= 10000 and i < 50000 then
r = 500 + i * 0.1
-- 50,000 to 249,999: 3000 + 0.05x
elseif i >= 50000 and i < 250000 then
r = 3000 + i * 0.05
-- 250,000 to 999,999: 10500 + 0.02x
elseif i >= 250000 and i < 1000000 then
r = 10500 + i * 0.02
-- 1,000,000 to 9,999,999: 20500 + 0.01x
elseif i >= 1000000 and i < 10000000 then
r = 20500 + i * 0.01
-- 10,000,000 and greater: 70,500 + 0.005x
elseif i >= 10000000 then
r = 70500 + i * 0.005
-- this shouldn't happen, but fallback to 1
else
r = 1
end
end
r = math.floor(killRoundingError(r))
if paramtest.has_content(_s) then
_s = string.gsub(_s,',','')
_s = tonumber(_s,10)
end
-- if overridden, use _s for sacrifice
if tonumber(_s,10) then
s = _s
else
-- otherwise include sacrifice as 4r
s = r * 4
end
table.insert(ret,string.format('<b>Reclaim:</b> %s',commas(r)))
table.insert(ret,string.format('<b>Sacrifice:</b> %s',commas(s)))
return table.concat(ret,'<br/>')
end
-- otherwise unknown
return nil
end
-- red ERR span with title hover for explanation
function badarg(argname, argmessage)
return '<span '..
'title="The parameter «'..argname..'» '..argmessage..'" '..
'style="color:red; font-weight:bold; cursor:help; border-bottom:1px dotted red;">'..
'ERR</span>'
end
-- plural
-- returns number with the word
function plural(arg,n,alt)
local _n = commas(tonumber(n,10) or 1)
if tonumber(n,10) == 1 then
return string.format('%s %s',_n,arg)
elseif alt then
return string.format('%s %s',_n,alt)
else
return string.format('%s %ss',_n,arg)
end
end
-- Does exactly what's on the tin
function killRoundingError(n)
return math.floor(n*1000+0.0000099)/1000
end
-- Categories
-- oman this is still blatant copy pasta
function addcategories(args,catargs)
local ret = { 'Items' }
local cat_map = {
-- Added if the parameter has content
defined = {
aka = 'Pages with AKA',
tooltip = 'Items that have a tooltip'
},
-- Added if the parameter has no content
notdefined = {
image = 'Needs image',
members = 'Needs members status',
release = 'Needs release date',
examine = 'Needs examine added',
level = 'Needs combat level',
weight = 'Needs weight added',
value = 'Items missing value',
quest = 'Items missing quest',
destroy = 'Missing destroy text',
kept = 'Items missing death info',
disassembly = 'Items missing disassembly info'
},
-- Parameters that have text
-- map a category to a value
grep = {
members = { yes = 'Members\' items', no = 'Free-to-play items' },
stackable = { yes = 'Stackable items' },
lendable = { yes = 'Lendable items' },
equipable = { yes = 'Equipable items' },
gemw = { ['true'] = 'Grand Exchange items' },
tradeable = { yes = 'Tradeable items', no = 'Untradeable items', restricted = 'Restricted trade items' },
disassembly = { yes = 'Items that can be disassembled', no = 'Items that cannot be disassembled', restricted = 'Location restricted disassembly', ['n/a'] = 'Items with N/A disassembly' },
kept = { ['always lost'] = 'Items that are never kept on death', ['always kept outside'] = 'Items that are always kept outside the Wilderness on death', reclaimable = 'Items that are reclaimable on death' }
}
}
-- Run and add mapped categories
-- 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.grep) do
for m, w in pairs(v) do
if args[n] then
if string.find(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.find(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
-- extra func for death
-- searching for 'always kept' would match more than what we want
if args.kept.d == 'Always kept' then
table.insert(ret,'Items that are always kept on death')
elseif args.kept.switches then
for _, v in ipairs(args.kept.switches) do
if v == 'Always kept' then
table.insert(ret,'Items that are always kept on death')
break
end
end
end
-- ids
if not catargs.id.all_defined then
-- rsc ids have no id
if catargs.rscid.all_defined then
-- do nothing
else
table.insert(ret,'Needs ID')
end
end
-- store
if string.lower(args.store.d or '') ~= 'not sold' and not string.lower(args.store.d or 'edit'):find('edit') then
table.insert(ret,'Pages that use Store')
elseif args.store.switches then
for _, v in ipairs(args.store.switches) do
if string.lower(v or '') ~= 'not sold' and string.lower(v or '') ~= infobox.nil_param() and not string.lower(v or 'edit'):find('edit') then
table.insert(ret,'Pages that use Store')
end
end
end
-- alchemy
-- non alchable
if args.alchable.d == false then
table.insert(ret,'Items that cannot be alchemised')
elseif args.alchable.switches then
for _, v in ipairs(args.alchable.switches) do
if v == false then
table.insert(ret,'Items that cannot be alchemised')
break
end
end
end
-- gemw
-- if item is both (not untradeable) and (not GEMW) then add Non-GE items
if not args.gemw.d and string.lower(args.tradeable.d) ~= 'no' then
table.insert(ret, 'Non-GE items')
end
-- switches; if tradeable switches exist, if gemwX and tradeableX are as above, add Non-GE items
-- if no switches, gemwX and tradeable (default)
if args.gemw.switches then
if args.tradeable.switches then
for i, v in ipairs(args.gemw.switches) do
if not v and string.lower(args.tradeable.switches[i] or args.tradeable.d) ~= 'no' then
table.insert(ret, 'Non-GE items')
end
end
else
for i, v in ipairs(args.gemw.switches) do
if not v and string.lower(args.tradeable.d) ~= 'no' then
table.insert(ret, 'Non-GE items')
end
end
end
end
-- combine table and format category wikicode
for i, v in ipairs(ret) do
ret[i] = string.format('[[Category:%s]]',v)
end
return table.concat(ret,'')
end
return p