FANDOM


-- <pre>
--[=[
-- 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',
	cape = 'cape',
	body = 'body',
	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',
	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 = '[[Category:Head slot items]]',
	neck = '[[Category:Neck slot items]]',
	cape = '[[Category:Cape slot items]]',
	body = '[[Category:Body slot items]]',
	legs = '[[Category:Legwear slot items]]',
	hands = '[[Category:Hand slot items]]',
	feet = '[[Category:Feet slot items]]',
	ammo = '[[Category:Ammunition slot items]]',
	ring = '[[Category:Rings]]',
	aura = '[[Category:Auras]]',
	pocket = '[[Category:Pocket slot items]]',
	sigil = '[[Category:Sigil slot items]]',
	['main-hand weapon'] = '[[Category:Weapon slot items]]',
	['2h weapon'] = '[[Category:Two-handed slot items]]',
	['off-hand'] = '[[Category:Off-hand slot items]]',
	['off-hand weapon'] = '[[Category:Off-hand slot weapon]]',
	e = ''
}
 
-- Images used for slot display
local slot_images = {
	head = '[[File:Head slot.png|link=Head slot]]',
	ammo = '[[File:Ammo slot.png|link=Ammunition slot]]',
	neck = '[[File:Neck slot.png|link=Neck slot]]',
	cape = '[[File:Cape slot.png|link=Cape slot]]',
	['main-hand weapon'] = '[[File:Weapon slot.png|link=Mainhand slot]]',
	['2h weapon'] = '[[File:2h slot.png|link=Two-handed slot]]',
	body = '[[File:Torso slot.png|link=Body slot]]',
	['off-hand'] = '[[File:Shield slot.png|link=Off-hand slot]]',
	['off-hand weapon'] = '[[File:Shield slot.png|link=Off-hand slot]]',
	legs = '[[File:Legs slot.png|link=Legwear slot]]',
	hands = '[[File:Gloves slot.png|link=Hands slot]]',
	feet = '[[File:Feet slot.png|link=Feet slot]]',
	ring = '[[File:Ring slot.png|link=Ring slot]]',
	aura = '[[File:Aura slot.png|link=Aura slot]]',
	pocket = '[[File:Pocket slot.png|link=Pocket slot]]',
	sigil = '[[File:Sigil slot.png|link=Sigil slot]]',
	e = 'None'
}
 
-- 'invention slots'
local inv_slots = {
	['main-hand weapon'] = 'mh',
	['2h weapon'] = '2h',
	['off-hand'] = 'oh',
	['off-hand weapon'] = 'oh',
	shield = 'shield',
	body = '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 = '[[File:Attack.png|x24px|link=Melee]]',
	ranged = '[[File:Ranged.png|x24px|link=Ranged]]',
	magic = '[[File:Magic.png|x24px|link=Magic]]',
	hybrid = '[[File:CombatSwords.png|x24px|link=Armour#Hybrid]]',
	all = '[[File:CombatSwords.png|x24px|link=Armour#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 = '[[Category:Stab weapons]]',
	slash = '[[Category:Slash weapons]]',
	crush = '[[Category:Crush weapons]]',
	thrown = '[[Category:Thrown weapons]]'
}
 
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'] = '[[Category:Power armour]]',
	['tank armour'] = '[[Category:Tank armour]]',
	['pvp armour'] = '[[Category:PvP armour]]',
	shieldbow = '[[Category:Shieldbows]]',
	bow = '[[Category:Bows]]',
	defender = '[[Category:Defenders]]',
	repriser = '[[Category:Defenders]]',
	rebounder = '[[Category:Defenders]]',
	halberd = '[[Category:Halberds]]',
	shield = '[[Category:Shields]]',
	['prevents attack'] = '[[Category:Items which prevent 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},
		body = {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},
		body = {pvm = 0, pvp = 0.06},
		legs = {pvm = 0, pvp = 0.0525}
	},
	other = { --power, hybrid, all
		head = {pvm = 0, pvp = 0.01875},
		body = {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 pack|Charge drain]]')
			:done()
		else
			row1:tag('th')
				:attr('colspan','3')
				:wikitext('[[Equipment degradation|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('[[Ability damage|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('[[Hit chance|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('[[Attack types|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('[[Attack range|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('[[Attack speed|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('[[Template:Infobox Bonuses/FAQ|&#91;FAQ&#93;]]'..
							' &bull; '..
							'[[Template:Infobox Bonuses|&#91;doc&#93;]]')
					: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 pack|Charge drain]]')
			:done()
		else
			row1:tag('th')
				:attr('colspan','3')
				:wikitext('[[Equipment degradation|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('[[Ability damage|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('[[Hit chance|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('[[Attack types|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('[[Attack range|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('[[Template:Infobox Bonuses/FAQ|&#91;FAQ&#93;]]'..
							' &bull; '..
							'[[Template:Infobox Bonuses|&#91;doc&#93;]]')
					: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 '[[File:'..file..']]'
end
 
-- Maintenance and equipment type categories
function categories(params)
	local cats = {'[[Category:Equipment]]'}
 
	-- 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, '[[Category:Pages with deprecated parameters]]')
			break
		end
	end
 
	if not tier then
		table.insert(cats,'[[Category:Missing equipment tier]]')
	elseif tier == 0 then
		table.insert(cats,'[[Category:Tierless equipment]]')
	else
		table.insert(cats,'[[Category:Tier '..tier..' equipment]]')
	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,'[[Category:Missing attack speed]]')
	end
 
	if weapon and params.attack_range == '-' and itype:lower() ~= 'cosmetic' and itype:lower() ~= 'prevents attack' then
		table.insert(cats,'[[Category:Missing attack range]]')
	end
 
	if not slot then
		table.insert(cats,'[[Category:Missing slot information]]')
	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,'[[Category:Off-hand slot weapons|'..key..']]')
		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,'[[Category:Degrading equipment]]')
		end
	end
 
	if class == 'melee' then
		if weapon then
			table.insert(cats,'[[Category:Melee weapons]]')
		else
			table.insert(cats,'[[Category:Melee armour]]')
		end
	elseif class == 'ranged' then
		if weapon then
			table.insert(cats,'[[Category:Ranged weapons]]')
		elseif slot == 'ammo' then
			-- Nothing
		else
			table.insert(cats,'[[Category:Ranged armour]]')
		end
	elseif class == 'magic' then
		if weapon then
			table.insert(cats,'[[Category:Magic weapons]]')
		else
			table.insert(cats,'[[Category:Magic armour]]')
		end
	elseif class == 'hybrid' or class == 'all' then
		if weapon then
			table.insert(cats,'[[Category:Typeless weapons]]')
		else
			table.insert(cats,'[[Category:Hybrid armour]]')
		end
	elseif class == 'none' then
		if weapon then
			table.insert(cats,'[[Category:Typeless weapons]]')
		else
			table.insert(cats,'[[Category:Typeless armour]]')
		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,'[[Category:Needs equipped image]]')
	end
 
	return table.concat(cats)
end
 
return p

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.