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')

-- Accepted slot names local slots = { head = 'head', neck = 'neck', cape = 'cape', body = 'body', legs = 'legs', hands = 'hands', feet = 'feet', ammo = 'ammo', ring = 'ring', aura = 'aura', pocket = 'pocket', main = '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 = '', cape = '', body = '', legs = '', hands = '', feet = '', ammo = '', ring = '', aura = '', pocket = '', ['main-hand weapon'] = '', ['2h weapon'] = '', ['off-hand'] = '', ['off-hand weapon'] = '', e = '' }

-- Images used for slot display local slot_images = { head = '', ammo = '', neck = '', cape = '', ['main-hand weapon'] = '', ['2h weapon'] = '', body = '', ['off-hand'] = '', ['off-hand weapon'] = '', legs = '', hands = '', feet = '', ring = '', aura = '', pocket = '', e = 'None' }

-- 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 = '' }

-- Acceptable speeds local speeds = { slowest = {'Slowest','7.2',''}, slow = {'Slow','4.2',''}, average = {'Average','3.6',''}, fast = {'Fast','3.0',''}, fastest = {'Fastest','2.4',''}, none = {'no'} }

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

-- Params and defaults local requirements, image,caption, image2,caption2 = paramtest.defaults{ {args.requirements,'Unknown '..editbutton}, {clean_image(args.image),nil}, {args.caption,''}, {clean_image(args.image2),nil}, {args.caption2,''} }

-- Class local class = classes[string.lower(args.class or '')] or ('Unknown '..editbutton) local classimg = class_img[class] or ''

-- Degradation local degrades = string.lower(args.degrades or 'no') == 'yes'

-- Main hand local mainD = clean(args.mainDamage) local mainA = clean(args.mainAccuracy)

-- Off hand local offD = clean(args.offDamage) local offA = clean(args.offAccuracy)

-- 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

-- Misc weapon stuff local style = styles[string.lower(paramtest.default_to(args.style,''))] or '-'

-- Slot local slot = slots[string.lower(args.slot or '')] local slotimg = slot_images[slot] or ('? '..editbutton)

-- Whether or not the item is a weapon -- Important distinction, comes up multiple times local weapon = slot and slot:find('weapon')

-- 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

-- Weapon speed local speed = speeds[string.lower(args.aspeed or '')]

-- Pack params for passing into function return p._main{ requirements = requirements, tier = tier, class = class, classimg = classimg or '', degrades = degrades, mainD = mainD, mainA = mainA, offD = offD, offA = offA, style = style, slot = slot, slotimg = slotimg, weapon = weapon, armour = armour, life = life, prayer = prayer, strength = strength, ranged = ranged, magic = magic, speed = speed, image = image, caption = caption, ['image2'] = image2, ['caption2'] = caption2 } end

function p._main(...) -- Unpacking parameters -- Only unpacking parameters called more than once -- Everything else will be called from params local params = ... local degrades = params.degrades local weapon = params.weapon local speed = params.speed local image = params.image local image2 = params.image2

-- Basic body of the table, CSS, and header local ret_table = mw.html.create('table') :addClass('infobox-bonuses') :css({ border = 'none',					['text-align'] = 'center'})

local row1 = ret_table:tag('tr') :tag('th') :attr('colspan','6') :wikitext('Combat Stats') :done

-- calc image rowspan local rowspan if speed and speed[1] ~= 'no' and weapon then rowspan = '17' else rowspan = '15' end

-- Adding images and captions if they exist -- Will span entirety of the remaining rows for their columns -- First image if image then row1:tag('td') :attr('rowspan',rowspan) :wikitext(image) :tag('p') :css({							['font-size'] = '.85em',							-- don't allow the caption width to exceed the maximum image width							['max-width'] = '160px'						}) :wikitext(params.caption) :done :done end

-- Second image if image2 then row1:tag('td') :attr('rowspan',rowspan) :wikitext(image2) :tag('p') :css({							['font-size'] = '.85em',							-- don't allow the caption width to exceed the maximum image width							['max-width'] = '160px'						}) :wikitext(params.caption2) :done :done end

-- "Requirements" will span 2 columns if item degrades, otherwise all 3 local reqwidth if degrades then reqwidth = '3' else reqwidth = '6' end

local row2 = ret_table:tag('tr') :tag('th') :addClass('combat-requirements') :attr('colspan',reqwidth) :wikitext('Skill requirements') :done

-- Only show degrades and the header if the item does indeed degrade if degrades then row2:tag('th') :attr('colspan','3') :wikitext('Degrades') :done end

local row3 = 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 if degrades then row3:tag('td') :attr('colspan','3') :wikitext('Yes') :done 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 :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') -- Attributes header :tag('th') :attr('colspan','6') :wikitext('Attributes') :done :done :tag('tr') -- Armour rating :tag('th') :addClass('combat-attributes') :attr('colspan','5') :css('text-align','left') :wikitext(skillpic('Defence')..'Armour') :done :tag('td') :css('text-align','right') :wikitext(params.armour) :done :done :tag('tr') -- Life points :tag('th') :addClass('combat-attributes') :attr('colspan','5') :css('text-align','left') :wikitext(skillpic('Constitution')..'Life points') :done :tag('td') :css('text-align','right') :wikitext(params.life) :done :done :tag('tr') -- Prayer bonus :tag('th') :addClass('combat-attributes') :attr('colspan',5) :css('text-align','left') :wikitext(skillpic('Prayer')..'Prayer') :done :tag('td') :css('text-align','right') :wikitext(params.prayer) :done :done :tag('tr') :tag('th') :attr('colspan',6) :wikitext('Strength bonuses') :done :done :tag('tr') -- 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

--	-- 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[1] ~= 'no' and weapon then ret_table:tag('tr') :tag('th') :attr('colspan',6) :wikitext('Attack speed') :done :done if speed then local speedname = speed[1] local interval = speed[2] local speedimg = speed[3] ret_table:tag('tr') :tag('td') :css({ ['line-height'] = '90%',							['font-size'] = '12px' }) :attr('colspan',6) :wikitext(speedname) :tag('div') :css('font-size','smaller') :wikitext('Interval: '..interval..' seconds') :done :tag('div') :wikitext(speedimg) :done :done :done else ret_table:tag('tr') :tag('td') :attr('colspan',6) :wikitext('Unknown '..editbutton) :done :done end end

-- View and discuss links local bottom_row = ret_table:tag('tr') :css('border','none') :tag('td') :attr('colspan',6) :css( { background = 'transparent',						border = 'none',						['text-align'] = 'left',						['font-size'] = 'smaller' }) :wikitext('&#91;view&#93;'..							' &bull; '..							'&#91;talk&#93;') :done

-- Required for extra formatting to hide backgrounds if image and image2 then bottom_row:tag('td') :attr('colspan',2) :css({ background = 'transparent',					border = 'none' }) :done elseif image or image2 then bottom_row:tag('td') :css({ background = 'transparent',					border = 'none' }) :done end

-- Clear-left content before the table local divclear = mw.html.create('div') :addClass('clear-left') :done

local infobox = tostring(divclear)..tostring(ret_table)

-- 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 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 = file[1]..'|160x350px' 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] = '160' end -- set max height whilst we're here dimen[2] = '350' else -- width, height if tonumber(dimen[1]) > 160 then dimen[1] = '160' end if tonumber(dimen[2]) > 350 then dimen[2] = '350' end end file[i] = table.concat(dimen, 'x')..'px' end end

file = table.concat( file, '|' ) if dimen == nil then file = file..'|160x350px' 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

if not tier then table.insert(cats,'') elseif tier == 0 then table.insert(cats,'') else table.insert(cats,'') end if weapon and not params.speed 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 table.insert(cats,'') 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') then table.insert(cats,'') end

return table.concat(cats) end

return p