Module:Infobox bonuses

--[=[ -- Implements Template:Infobox Bonuses --]=] local p = {} local mainspace = require('Module:Mainonly').on_main local paramtest = require('Module:Paramtest') local skillpic = require('Module:Skill clickpic')._main local editbutton = require('Module:Edit button') local commas = require('Module:Addcommas')._add local chargedrain = require('Module:Augmented degrade') local attack_speed_bar = require('Module:Attack speed bar').weapon -- deprecated parameters that should be fixed local deprecated_params = { 'caption', -- does nothing 'mainType', -- does nothing 'offType', -- does nothing 'mainAccuracy', -- replaced with the single 'accuracy' param 'offAccuracy', 'mainDamage', -- replaced with the single 'damage' param 'offDamage' } -- Accepted slot names local slots = { head = 'head', neck = 'neck', back = 'back', cape = 'back', torso = 'torso', body = 'torso', legs = 'legs', hands = 'hands', feet = 'feet', ammo = 'ammo', ring = 'ring', aura = 'aura', pocket = 'pocket', sigil = 'sigil', main = 'main hand weapon', ['main hand'] = 'main hand weapon', ['main-hand'] = 'main hand weapon', mainhand = 'main hand weapon', weapon = 'main hand weapon', ['2h'] = '2h weapon', ['off-hand'] = 'off-hand', offhand = 'off-hand', shield = 'off-hand', ['off-hand weapon'] = 'off-hand weapon', ['offhand weapon'] = 'off-hand weapon', ohw = 'off-hand weapon', set = 'e', none = 'e' } -- Categories for slots local slot_cats = { head = '', neck = '', back = '', torso = '', legs = '', hands = '', feet = '', ammo = '', ring = '', aura = '', pocket = '', sigil = '', ['main hand weapon'] = '', ['2h weapon'] = '', ['off-hand'] = '', ['off-hand weapon'] = '', e = '' } -- Images used for slot display local slot_images = { head = '', ammo = '', neck = '', back = '', ['main hand weapon'] = '', ['2h weapon'] = '', torso = '', ['off-hand'] = '', ['off-hand weapon'] = '', legs = '', hands = '', feet = '', ring = '', aura = '', pocket = '', sigil = '', e = 'None' } -- 'invention slots' local inv_slots = { ['main hand weapon'] = 'mh', ['2h weapon'] = '2h', ['off-hand'] = 'oh', ['off-hand weapon'] = 'oh', shield = 'shield', torso = 'body', legs = 'legs', tool = 'tool', t = 'tool' } -- Accepted class names local classes = { melee = 'melee', ranged = 'ranged', ranging = 'ranged', range = 'ranged', magic = 'magic', mage = 'magic', all = 'all', hybrid = 'hybrid', none = 'none', ['n/a'] = 'none' } -- Classes with images local class_img = { melee = '', ranged = '', magic = '', hybrid = '', all = '' } -- Accepted style names local styles = { stab = 'stab', stabbing = 'stab', slash = 'slash', slashing = 'slash', crush = 'crush', crushing = 'crush', arrow = 'arrows', arrows = 'arrows', bolt = 'bolts', bolts = 'bolts', thrown = 'thrown', throwing = 'thrown', magic = 'spell-casting', spell = 'spell-casting', spells = 'spell-casting', none = 'none', ['n/a'] = 'none' } -- Categories for styles local style_cats = { stab = '', slash = '', crush = '', thrown = '' } local types = { power = 'Power armour', ['power armour'] = 'Power armour', tank = 'Tank armour', ['tank armour'] = 'Tank armour', pvp = 'PvP armour', ['pvp armour'] = 'PvP armour', shieldbow = 'Shieldbow', shortbow = 'Bow', bow = 'Bow', defender = 'Defender', repriser = 'Repriser', rebounder = 'Rebounder', halberd = 'Halberd', shield = 'Shield', cosmetic = 'Cosmetic', ['prevents attack'] = 'Prevents attack' } local type_cats = { ['power armour'] = '', ['tank armour'] = '', ['pvp armour'] = '', shieldbow = '', bow = '', defender = '', repriser = '', rebounder = '', halberd = '', shield = '', ['prevents attack'] = '' } local reduction_types = { -- accepts type or class ['tank armour'] = 'tank', ['power armour'] = 'other', ['pvp armour'] = 'pvp', ['shield'] = 'shield', ['shieldbow'] = 'shield', ['hybrid'] = 'other', ['all'] = 'other' } local reductions = { -- type -> slot -> pvm, pvp multipliers tank = { head = {pvm = 0.02, pvp = 0.0375}, torso = {pvm = 0.02, pvp = 0.06}, legs = {pvm = 0.02, pvp = 0.0525}, hands = {pvm = 0.02, pvp = 0}, feet = {pvm = 0.02, pvp = 0} },	pvp = { head = {pvm = 0, pvp = 0.0375}, torso = {pvm = 0, pvp = 0.06}, legs = {pvm = 0, pvp = 0.0525} },	other = { --power, hybrid, all head = {pvm = 0, pvp = 0.01875}, torso = {pvm = 0, pvp = 0.03}, legs = {pvm = 0, pvp = 0.02625} },	shield = { --because hybrid shields are a thing -- for consistency to continue allowing reduction.type.slot.pvx ['off-hand'] = {pvm = 0.1, pvp = 0}, ['2h weapon'] = {pvm = 0.1, pvp = 0}, --shieldbows pls } } function p.main(frame) local args = frame:getParent.args -- Params and defaults local requirements, image, altimage = paramtest.defaults{ {args.requirements,'Unknown '..editbutton}, {clean_image(args.image),nil}, {clean_image(args.altimage) or clean_image(args.image2),nil} }	local noimgcat = args.image and args.image:lower == 'no' -- Class local class = classes[string.lower(args.class or '')] or ('Unknown '..editbutton) local classimg = class_img[class] or '' -- equipment tier local tier = string.lower(args.tier or '') if tier == 'no' or tier == 'none' or tier == 'n/a' then tier = 0 else tier = clean(args.tier) end -- type local itype = types[string.lower(args.type or '')] -- implicit 'or nil' -- Slot local slot = slots[string.lower(args.slot or '')] local slotimg = slot_images[slot] or ('? '..editbutton) -- Degradation local charges = clean(args.degrades) local invtier = clean(args.invtier) local invslot = args.invslot local degrades = false if invtier then degrades = true invslot = inv_slots[invslot] if not inv_slots[invslot] then invslot = inv_slots[slot] end else if charges and charges > 0 or string.lower(args.degrades or 'no') == 'yes' then degrades = true end end -- Whether or not the item is a weapon -- Important distinction, comes up multiple times local weapon = slot and slot:find('weapon') -- Misc weapon stuff local style = styles[string.lower(paramtest.default_to(args.style,) or )] or '-' local attack_range = clean(args.attack_range) or clean(args['attack range']) or '-' if weapon and itype ~= 'Prevents attack' and attack_range == '-' then attack_range = editbutton("? (edit)") end -- damage and accuracy local damage = clean(args.damage) or 0 local accuracy = clean(args.accuracy) local mainD, mainA, offD, offA = nil,nil,nil,nil -- if both new params are specified, then take precedence if damage and accuracy then if slot == 'off-hand weapon' then offA = accuracy offD = damage else -- enforce slot? mainA = accuracy mainD = damage end else -- support old params mainD = clean(args.mainDamage) mainA = clean(args.mainAccuracy) offD = clean(args.offDamage) offA = clean(args.offAccuracy) end -- Defensive stats local armour = clean(args.armour or args.defence) or 0 local life = clean(args.life) or 0 local prayer = clean(args.prayer) or 0 -- Damage stats local strength = clean(args.strength) or 0 local ranged = clean(args.ranged) or 0 local magic = clean(args.magic) or 0 -- Damage reduction local reductionlevel = clean(args.reductionlevel) or tier -- manual overrides local reduction_pvm, reduction_pvp = clean(args.pvmReduction), clean(args.pvpReduction) if reductionlevel and not reduction_pvm or not reduction_pvp then -- attempt to automatically generate reduction values local red_tbl, red_type = nil, nil if itype then red_type = reduction_types[itype:lower] if red_type then red_tbl = reductions[red_type][slot] end end if not red_tbl and class then red_type = reduction_types[class:lower] if red_type then red_tbl = reductions[red_type][slot] end end if red_tbl then if not reduction_pvm then reduction_pvm = red_tbl.pvm * tier end if not reduction_pvp then reduction_pvp = red_tbl.pvp * tier end end end reduction_pvm = (reduction_pvm or '0') .. '%'	reduction_pvp = (reduction_pvp or '0') .. '%'	-- Weapon speed local speed = string.lower(args.speed or args.aspeed or '') -- IF image IS DEFINED AND altimage IS NOT, USE INFOBOX TYPE A (1 image inset into box) -- ELSE USE INFOBOX TYPE B (equal rows each side, images on top if present) local infoboxtype = 'B'	if image and not altimage then infoboxtype = 'A'	end -- Pack params for passing into function return p['_main' .. infoboxtype]{ _raw_args_ = args, requirements = requirements, tier = tier, class = class, classimg = classimg or '', degrades = degrades, charges = charges, invtier = invtier, invslot = invslot, type = itype, mainD = mainD, mainA = mainA, offD = offD, offA = offA, style = style, attack_range = attack_range, speed = speed, slot = slot, slotimg = slotimg, weapon = weapon, armour = armour, life = life, prayer = prayer, strength = strength, ranged = ranged, magic = magic, reduction_pvm = reduction_pvm, reduction_pvp = reduction_pvp, image = image, altimage = altimage, noimgcat = noimgcat } end --- -- TYPE A --- function p._mainA(...) -- Unpacking parameters -- Only unpacking parameters called more than once -- Everything else will be called from params local params = ... local degrades = params.degrades local charges = params.charges local invtier = params.invtier local invslot = params.invslot local weapon = params.weapon local speed = params.speed local image = params.image local altimage = params.altimage local tier = params.tier local itype = params.type -- Basic body of the table, CSS, and header local ret_table = mw.html.create('table') :addClass('infobox-bonuses') :css({ border = 'none',					['text-align'] = 'center'}) ret_table:tag('caption') :wikitext("Combat Stats") :done -- "Requirements" will span 2 columns if item degrades, otherwise all 3 local reqwidth if degrades then reqwidth = '3' else reqwidth = '6' end local row1 = ret_table:tag('tr') :tag('th') :addClass('combat-requirements') :attr('colspan',reqwidth) :wikitext('Requirements') :done -- Only show degrades and the header if the item does indeed degrade if degrades then if invtier then row1:tag('th') :attr('colspan','3') :wikitext('Charge drain') :done else row1:tag('th') :attr('colspan','3') :wikitext('Degrades') :done end end -- Adding images if they exist -- Will span entirety of the remaining rows for their columns -- First image if image then local speed_img_rowspan if speed and speed ~= 'no' and weapon then speed_img_rowspan = 12 else speed_img_rowspan = 11 end row1:tag('td') :attr({rowspan=speed_img_rowspan, colspan=6}) :wikitext(image) :done end local row2 = ret_table:tag('tr') :tag('td') :attr('colspan',reqwidth) -- to stop skill reqs getting too wide :css('max-width', '240px') :wikitext(mw.getCurrentFrame						:preprocess(params.requirements) ) :done -- Only show if item does indeed degrade local div = '' if degrades then if invtier then local span span, div = chargedrain.get_tooltip(invtier,invslot) row2:tag('td') :attr('colspan','3') :wikitext(chargedrain.get_base(invtier, invslot) .. '/s '..tostring(span)) :done else local degstr = 'Yes' if charges then degstr = commas(charges) .. ' charges' end row2:tag('td') :attr('colspan','3') :wikitext(degstr) :done end end -- Large flurry of table creation with tags ret_table:tag('tr') -- Class header :tag('th') :attr('colspan','3') :css('width','50%') :wikitext('Class') :done -- Slot header :tag('th') :attr('colspan','3') :css('width','50%') :wikitext('Slot') :done :done :tag('tr') -- Class parameter :tag('td') :attr('colspan','3') :wikitext(params.classimg..' '..paramtest.ucfirst(params.class)) :done -- Slot parameter as image :tag('td') :attr('colspan','3') :wikitext(params.slotimg) :done :done if itype then reqwidth = '3' else reqwidth = '6' end local row5 = ret_table:tag('tr') :tag('th') :attr('colspan', reqwidth) :wikitext('Tier') :done if itype then row5:tag('th') :attr('colspan', '3') :wikitext('Type') :done end if tier then if tier == 0 then tier = "None" end else tier = 'Unknown ' .. editbutton end local row6 = ret_table:tag('tr') :tag('td') :attr('colspan', reqwidth) :wikitext(tier) :done if itype then row6:tag('td') :attr('colspan', '3') :wikitext(itype) :done end ret_table:tag('tr') -- Weapons header :tag('th') :attr('colspan',2) :css('width','33%') :wikitext('Weapons') :done -- Main hand :tag('th') :attr('colspan','2') :css('width','33%') :wikitext('Main') :done -- Off-hand :tag('th') :attr('colspan','2') :css('width','33%') :wikitext('Off') :done :done :tag('tr') -- Weapon's damage :tag('th') :attr('colspan','2') :wikitext('Damage') :done -- Main hand damage, "-" if 0 or nil :tag('td') :attr('colspan','2') :wikitext(formatzero(params.mainD)) :done -- Off-hand damage, "-" if 0 or nil :tag('td') :attr('colspan','2') :wikitext(formatzero(params.offD)) :done :done :tag('tr') -- Weapon's accuracy :tag('th') :attr('colspan','2') :wikitext('Accuracy') :done -- Main hand accuracy, "-" if 0 or nil :tag('td') :attr('colspan','2') :wikitext(formatzero(params.mainA)) :done -- Off-hand accuracy, "-" if 0 or nil :tag('td') :attr('colspan','2') :wikitext(formatzero(params.offA)) :done :done :tag('tr') -- Weapon's style -- Will apply to both main and off-hand -- Instead of separate values like before :tag('th') :attr('colspan','2') :wikitext('Style') :done :tag('td') :attr('colspan','4') :wikitext(paramtest.ucfirst(params.style)) :done :done :tag('tr') -- Weapon's attack range -- as above :tag('th') :attr('colspan','2') :wikitext('Range') :done :tag('td') :attr('colspan','4') :wikitext(params.attack_range) :done :done --		-- If the item is a weapon and has a valid speed defined		-- Create a header for it and add a speed bar		-- If speed is 'no' for weapons or nil		-- Create a blank cell to keep format pretty		-- if speed and speed ~= 'no' and weapon then ret_table:tag('th') :attr('colspan','2') :wikitext('Speed') :done if speed then ret_table:tag('td') :attr('colspan','4') :css('padding','0.2em') :node(attack_speed_bar(speed)) :done else ret_table:tag('td') :attr('colspan','4') :wikitext('Unknown '..editbutton) :done end end ret_table:tag('tr') -- Attributes header :tag('th') :attr('colspan','6') :wikitext('Attributes') :done -- damage reduction header :tag('th') :attr('colspan','6') :css('min-width', '225px') -- force as wide as other side (3x th = 210 from css, + paddings and borders = 225) :wikitext('Damage reduction') :done :done :tag('tr') -- Armour rating :tag('th') :addClass('combat-attributes') :attr('colspan','4') :css('text-align','left') :wikitext(skillpic('Defence')..'Armour') :done :tag('td') :attr('colspan', 2) :css('text-align','right') :wikitext(params.armour) :done -- both damage reductions :tag('td') :attr('colspan',3) :tag('span') :css('float','left') :wikitext("PvM: ") :done :tag('span') :css('float','right') :wikitext(params.reduction_pvm) :done :done :tag('td') :attr('colspan',3) :tag('span') :css('float','left') :wikitext("PvP: ") :done :tag('span') :css('float','right') :wikitext(params.reduction_pvp) :done :done :done :tag('tr') -- Life points :tag('th') :addClass('combat-attributes') :attr('colspan','4') :css('text-align','left') :wikitext(skillpic('Constitution')..'Life points') :done :tag('td') :attr('colspan', 2) :css('text-align','right') :wikitext(params.life) :done -- style bonuses header :tag('th') :attr('colspan',6) :wikitext('Style bonuses') :done :done :tag('tr') -- Prayer bonus :tag('th') :addClass('combat-attributes') :attr('colspan',4) :css('text-align','left') :wikitext(skillpic('Prayer')..'Prayer') :done :tag('td') :attr('colspan', 2) :css('text-align','right') :wikitext(params.prayer) :done -- Melee damage bonus :tag('td') :attr('colspan',2) :tag('span') :css('float','left') :wikitext(skillpic('strength')) :done :tag('span') :css('float','right') :wikitext(params.strength) :done :done -- Ranged damage bonus :tag('td') :attr('colspan',2) :tag('span') :css('float','left') :wikitext(skillpic('ranged')) :done :tag('span') :css('float','right') :wikitext(params.ranged) :done :done -- Magic damage bonus :tag('td') :attr('colspan',2) :tag('span') :css('float','left') :wikitext(skillpic('magic')) :done :tag('span') :css('float','right') :wikitext(params.magic) :done :done :done -- FAQ and documentation links local bottom_row = ret_table:tag('tr') :css('border','none') :tag('td') :attr('colspan',12) :css( { background = 'transparent !important',						border = 'none !important',						['text-align'] = 'left',						['font-size'] = 'smaller' }) :wikitext('[FAQ]'..							' • '..							'[doc]') :done -- Clear-left content before the table local divclear = mw.html.create('div') :addClass('clear-left') :done local infobox = tostring(divclear)..tostring(ret_table)..tostring(div) -- Only bother even looking at categories if infobox is in mainspace if mainspace then infobox = infobox..categories(params) end return infobox end --- -- TYPE B --- function p._mainB(...) -- Unpacking parameters -- Only unpacking parameters called more than once -- Everything else will be called from params local params = ... local degrades = params.degrades local charges = params.charges local invtier = params.invtier local invslot = params.invslot local weapon = params.weapon local speed = params.speed local image = params.image local altimage = params.altimage local tier = params.tier local itype = params.type -- Basic body of the table, CSS, and header local ret_table = mw.html.create('table') :addClass('infobox-bonuses') :css({ border = 'none',					['text-align'] = 'center'}) ret_table:tag('caption') :wikitext("Combat Stats") :done --images if image and altimage then ret_table :tag('tr') :tag('td') :attr('colspan', '6') :wikitext(image) :done :tag('td') :attr('colspan', '6') :wikitext(altimage) :done :done end -- "Requirements" will span 2 columns if item degrades, otherwise all 3 local reqwidth, reqwidth2 if degrades then reqwidth = '3' else reqwidth = '6' end if itype then reqwidth2 = '3' else reqwidth2 = '6' end local row1 = ret_table:tag('tr') :tag('th') :addClass('combat-requirements') :attr('colspan',reqwidth) :wikitext('Requirements') :done -- Only show degrades and the header if the item does indeed degrade if degrades then if invtier then row1:tag('th') :attr('colspan','3') :wikitext('Charge drain') :done else row1:tag('th') :attr('colspan','3') :wikitext('Degrades') :done end end row1:tag('th') :attr('colspan', reqwidth2) :wikitext('Tier') :done if itype then row1:tag('th') :attr('colspan', '3') :wikitext('Type') :done end local row2 = ret_table:tag('tr') :tag('td') :attr('colspan',reqwidth) -- to stop skill reqs getting too wide :css('max-width', '240px') :wikitext(mw.getCurrentFrame						:preprocess(params.requirements) ) :done -- Only show if item does indeed degrade local div = '' if degrades then if invtier then local span span, div = chargedrain.get_tooltip(invtier,invslot) row2:tag('td') :attr('colspan','3') :wikitext(chargedrain.get_base(invtier, invslot) .. '/s '..tostring(span)) :done else local degstr = 'Yes' if charges then degstr = commas(charges) .. ' charges' end row2:tag('td') :attr('colspan','3') :wikitext(degstr) :done end end if tier then if tier == 0 then tier = "None" end else tier = 'Unknown ' .. editbutton end row2:tag('td') :attr('colspan', reqwidth2) :wikitext(tier) :done if itype then row2:tag('td') :attr('colspan', '3') :wikitext(itype) :done end ret_table:tag('tr') -- Class header :tag('th') :attr('colspan','3') :css('width','50%') :wikitext('Class') :done -- Slot header :tag('th') :attr('colspan','3') :css('width','50%') :wikitext('Slot') :done :tag('th') :attr('colspan', '6') :wikitext('Attributes') :done :done :tag('tr') -- Class parameter :tag('td') :attr('colspan','3') :attr('rowspan', '2') :wikitext(params.classimg..' '..paramtest.ucfirst(params.class)) :done -- Slot parameter as image :tag('td') :attr('colspan','3') :attr('rowspan', '2') :wikitext(params.slotimg) :done -- armour value :tag('th') :addClass('combat-attributes') :attr('colspan','4') :css('text-align','left') :	wikitext(skillpic('Defence')..'Armour') :done :tag('td') :attr('colspan', 2) :css('text-align','right') :wikitext(params.armour) :done :done :tag('tr') -- left bit of row covered by rowspan -- lifepoints :tag('th') :addClass('combat-attributes') :attr('colspan','4') :css('text-align','left') :wikitext(skillpic('Constitution')..'Life points') :done :tag('td') :attr('colspan', 2) :css('text-align','right') :wikitext(params.life) :done :done :tag('tr') -- Weapons header :tag('th') :attr('colspan',2) :css('width','33%') :wikitext('Weapons') :done -- Main hand :tag('th') :attr('colspan','2') :css('width','33%') :wikitext('Main') :done -- Off-hand :tag('th') :attr('colspan','2') :css('width','33%') :wikitext('Off') :done -- prayer bonus :tag('th') :addClass('combat-attributes') :attr('colspan',4) :css('text-align','left') :wikitext(skillpic('Prayer')..'Prayer') :done :tag('td') :attr('colspan', 2) :css('text-align','right') :wikitext(params.prayer) :done :done :tag('tr') -- Weapon's damage :tag('th') :attr('colspan','2') :wikitext('Damage') :done -- Main hand damage, "-" if 0 or nil :tag('td') :attr('colspan','2') :wikitext(formatzero(params.mainD)) :done -- Off-hand damage, "-" if 0 or nil :tag('td') :attr('colspan','2') :wikitext(formatzero(params.offD)) :done :tag('th') :attr('colspan', '6') :wikitext('Damage reduction') :done :done :tag('tr') -- Weapon's accuracy :tag('th') :attr('colspan','2') :wikitext('Accuracy') :done -- Main hand accuracy, "-" if 0 or nil :tag('td') :attr('colspan','2') :wikitext(formatzero(params.mainA)) :done -- Off-hand accuracy, "-" if 0 or nil :tag('td') :attr('colspan','2') :wikitext(formatzero(params.offA)) :done -- both damage reductions :tag('td') :attr('colspan',3) :tag('span') :css('float','left') :wikitext("PvM: ") :done :tag('span') :css('float','right') :wikitext(params.reduction_pvm) :done :done :tag('td') :attr('colspan',3) :tag('span') :css('float','left') :wikitext("PvP: ") :done :tag('span') :css('float','right') :wikitext(params.reduction_pvp) :done :done :done :tag('tr') :tag('th') :attr('colspan','2') :wikitext('Style') :done :tag('td') :attr('colspan','4') :wikitext(paramtest.ucfirst(params.style)) :done :tag('th') :attr('colspan', '6') :wikitext('Style bonuses') :done :done :tag('tr') -- Weapon's attack range -- as above :tag('th') :attr('colspan','2') :wikitext('Range') :done :tag('td') :attr('colspan','4') :wikitext(params.attack_range) :done -- Melee damage bonus :tag('td') :attr('colspan',2) :css('width', '70px') :tag('span') :css('float','left') :wikitext(skillpic('strength')) :done :tag('span') :css('float','right') :wikitext(params.strength) :done :done -- Ranged damage bonus :tag('td') :attr('colspan',2) :css('width', '70px') :tag('span') :css('float','left') :wikitext(skillpic('ranged')) :done :tag('span') :css('float','right') :wikitext(params.ranged) :done :done -- Magic damage bonus :tag('td') :attr('colspan',2) :css('width', '70px') :tag('span') :css('float','left') :wikitext(skillpic('magic')) :done :tag('span') :css('float','right') :wikitext(params.magic) :done :done :done -- FAQ and documentation links local bottom_row = ret_table:tag('tr') :css('border','none') :tag('td') :attr('colspan',12) :css( { background = 'transparent !important',						border = 'none !important',						['text-align'] = 'left',						['font-size'] = 'smaller' }) :wikitext('[FAQ]'..							' • '..							'[doc]') :done -- Clear-left content before the table local divclear = mw.html.create('div') :addClass('clear-left') :done local infobox = tostring(divclear)..tostring(ret_table)..tostring(div) -- Only bother even looking at categories if infobox is in mainspace if mainspace then infobox = infobox..categories(params) end return infobox end -- Removes all plus signs, commas, and percent signs function clean(number) if not number then return nil else return tonumber(number:gsub('[+,%%]',''),10) end end -- For some parameters, non numbers and 0 are changed to '-' function formatzero(num) if not tonumber(num) or num == 0 then return '-' else return num end end -- Removes 'File:' prefix, just in case -- Replace | with | instead of preprocessing -- Turn into a nice wiki file link function clean_image(file) if not file or (file and (file:lower == 'no' or file == '')) then return nil end local height, width = '280', '220' file = file:gsub('[Ff]ile:',''):gsub('|','|') -- enforce max height and width file = mw.text.split(file, '|') if #file == 1 then -- no extra parameters, just the file link file = string.format('%s|%sx%spx',file[1], width, height) else -- cap width at 160px, height at 350px -- first param will always be the filename local dimen = nil for i = 2, #file do			-- look for string ending with px			if mw.ustring.find( file[i], 'px$' ) then -- strip px				dimen = mw.ustring.gsub(file[i], 'px$', '') dimen = mw.text.split(dimen, 'x') if #dimen == 1 then -- width if tonumber(dimen[1]) > 160 then dimen[1] = width end -- set max height whilst we're here dimen[2] = height else -- width, height if tonumber(dimen[1]) > 160 then dimen[1] = width end if tonumber(dimen[2]) > 350 then dimen[2] = height end end file[i] = table.concat(dimen, 'x')..'px' end end file = table.concat( file, '|' ) if dimen == nil then file = string.format('%s|%sx%spx',file, width, height) end end return '' end -- Maintenance and equipment type categories function categories(params) local cats = {''} -- Unpacking params local weapon = params.weapon local slot = params.slot local style = params.style local class = params.class local tier = params.tier local itype = params.type or '' for _,v in ipairs(deprecated_params) do		if params._raw_args_[v] ~= nil then table.insert(cats, '') break end end if not tier then table.insert(cats,'') elseif tier == 0 then table.insert(cats,'') else table.insert(cats,'') end if itype and type_cats[itype:lower] then table.insert(cats, type_cats[itype:lower]) end if weapon and itype:lower ~= 'prevents attack' and not params.speed then table.insert(cats,'') end if weapon and params.attack_range == '-' and itype:lower ~= 'cosmetic' and itype:lower ~= 'prevents attack' then table.insert(cats,'') end if not slot then table.insert(cats,'') else if slot == 'off-hand weapon' then local pagename = mw.title.getCurrentTitle.fullText local key = paramtest.ucfirst(					pagename:match('^Off%-?hand (.*)$') or					pagename ) table.insert(cats,'') else table.insert(cats,slot_cats[slot]) end end if style_cats[style] then table.insert(cats,style_cats[style]) end if params.degrades then if not params.invtier then table.insert(cats,'') end end if class == 'melee' then if weapon then table.insert(cats,'') else table.insert(cats,'') end elseif class == 'ranged' then if weapon then table.insert(cats,'') elseif slot == 'ammo' then -- Nothing else table.insert(cats,'') end elseif class == 'magic' then if weapon then table.insert(cats,'') else table.insert(cats,'') end elseif class == 'hybrid' or class == 'all' then if weapon then table.insert(cats,'') else table.insert(cats,'') end elseif class == 'none' then if weapon then table.insert(cats,'') else table.insert(cats,'') end end if not params.image and not (slot == 'ammo' or					slot == 'pocket' or					slot == 'ring' or					slot == 'sigil') and not params.noimgcat then table.insert(cats,'') end return table.concat(cats) end return p