FANDOM


-- <pre>
--------------------------
-- Module for [[Template:Infobox Monster new]]
-- Please test changes to this module at [[Module:Infobox Monster/sandbox]] first
------------------------
local p = {}
 
-- "imports"
local onmain = require('Module:Mainonly').on_main
local paramtest = require('Module:Paramtest')
local yesno = require('Module:Yesno')
local commas = require('Module:Addcommas')._add
local infobox = require('Module:Infobox')
 
--[[
 -- Mapping
--]]
local attack_styles = {
	melee = { image = 'Attack-icon', link = 'Melee' },
	ranged = { image = 'Ranged-icon', link = 'Ranged' },
	magic = { image = 'Magic-icon', link = 'Magic' },
	dragonfire = { image = 'Dragonfire icon', link = 'Dragonfire' },
	na = { image = 'Zero weakness icon', link = '' },
	typeless = { image = 'Zero weakness icon', link = '' }
}
 
local styles_map = {
	melee = 'melee',
	magic = 'magic',
	mage = 'magic',
	range = 'ranged',
	ranged = 'ranged',
	ranging = 'ranged',
	dragonfire = 'dragonfire',
	['dragon fire'] = 'dragonfire',
	dragonbreath = 'dragonfire',
	['dragon breath'] = 'dragonfire',
	['n/a'] = 'na',
	na = 'na',
	none = 'na'
}
 
local slay_masters = {
	turael = { text = '[[Turael]] or [[Spria]]', chathead = 'turael chathead', category = 'Monsters assigned by Turael or Spria' },
	mazchna = { text = '[[Mazchna]] or [[Achtryn]]', chathead = 'mazchna chathead', category = 'Monsters assigned by Mazchna or Achtryn' },
	chaeldar = { text = '[[Chaeldar]]', chathead = 'chaeldar chathead', category = 'Monsters assigned by Chaeldar' },
	sumona = { text = '[[Sumona]]', chathead = 'sumona chathead', category = 'Monsters assigned by Sumona' },
	vannaka = { text = '[[Vannaka]]', chathead = 'vannaka chathead', category = 'Monsters assigned by Vannaka' },
	duradel = { text = '[[Duradel]] or [[Lapalok]]', chathead = 'duradel chathead', category = 'Monsters assigned by Duradel or Lapalok' },
	kuradal = { text = '[[Kuradal]]', chathead = 'kuradal chathead', category = 'Monsters assigned by Kuradal' },
	morvran = { text = '[[Morvran]]', chathead = 'morvran chathead', category = 'Monsters assigned by Morvran' },
}
 
local slay_masters_map = {
	turael = 'turael',
	spria = 'turael',
	mazchna = 'mazchna',
	achtryn = 'mazchna',
	chaeldar = 'chaeldar',
	sumona = 'sumona',
	vannaka = 'vannaka',
	duradel = 'duradel',
	lapalok = 'duradel',
	kuradal = 'kuradal',
	morvran = 'morvran',
	no = 'none',
	none = 'none',
	['n/a'] = 'none'
}
 
local speeds = {
	[0] = 'N/A',
	[1] = '1 tick (0.6s)',
	[2] = '2 ticks (1.2s)',
	[3] = '3 ticks (1.8s)',
	[4] = '4 ticks (2.4s)',
	[5] = '5 ticks (3.0s)',
	[6] = '6 ticks (3.6s)',
	[7] = '7 ticks (4.2s)',
	[8] = '8 ticks (4.8s)',
	[9] = '9 ticks (5.4s)',
	[10] = '10 ticks (6s)'
}
 
local speed_map = {
	['1'] = 1,
	['2'] = 2,
	['3'] = 3,
	['4'] = 4,
	['5'] = 5,
	['6'] = 6,
	['7'] = 7,
	['8'] = 8,
	['9'] = 9,
	['10'] = 10,
	['n/a'] = 0,
	['0'] = 0
}
 
-- load weaknesses instead of remapping
local weaknesses = mw.loadData('Module:Weakness clickpic/data')
 
-- Main function called with invokes
function p.main(frame)
	local args = frame:getParent().args
	local ret = infobox.new(args)
	local yn_args = {
		'aggressive', 'immune_to_poison', 'immune_to_deflect',
		'immune_to_stun', 'immune_to_drain'
	}
	local num_args = {
		'slaylvl', 'slayxp',
		'attack', 'strength', 'defence', 'ranged', 'magic',
		'max_melee', 'max_ranged', 'max_magic', 'max_spec',
		'acc_melee', 'acc_ranged', 'acc_magic', 'armour',
		'aff_melee', 'aff_ranged', 'aff_magic' } --aff_weakness has a special func
 
	for _, v in ipairs(yn_args) do
		ret:defineParams{ { name = v, func = { name = boolargs, params = { v, v }, flag = { 'p', 'r' } } }}
	end
 
	for _, v in ipairs(num_args) do
		ret:defineParams{ { name = v, func = { name = numberargs, params = { v, v }, flag = { 'p', 'r' } } }}
	end
	ret:defineParams{
		{ name = 'poisonous', func = { name = poisonarg, params = { 'poisonous' }, flag = 'p' } },
		{ name = 'level', func = combatarg },
		{ name = 'style', func = stylearg },
		{ name = 'lifepoints', func = numargcommas },
		{ name = 'experience', func = numargcommas },
		{ name = 'xpraw', func = { name = numargraw, params = { 'experience' },  flag = 'p' } },
		{ name = 'hpxp', func = { name = hpxparg, params = { 'experience' } } },
		{ name = 'wepxp', func = { name = wepxparg, params = { 'experience' } } },
		{ name = 'weakness', func = weaknessarg },
		{ name = 'explicit_weakness', func = { name = explicitwkarg, params = { 'weakness' }, flag = 'p' } },
		{ name = 'aff_weakness', func = { name = aff_weakness_arg , params = { 'aff_weakness', 'aff_weakness', 'weakness' }, flag = { 'p', 'r', 'p' } } },
		{ name = 'abilities', func = abilarg },
		{ name = 'assigned_by', func = slayerarg },
		{ name = 'not_assigned', func = { name = notassarg, params = { 'assigned_by' }, flag = 'p' } },
		{ name = 'release', func = 'release' },
		{ name = 'removal', func = 'removal' },
		{ name = 'members', func = 'has_content' },
		{ name = 'examine', func = 'has_content' },
		{ name = 'speed', func = speedarg },
		{ name = 'name', func = 'name' },
		{ name = 'aka', func = 'has_content' },
		{ name = 'image', func = 'image' },
		{ name = 'slayercat', func = 'has_content' }
	}
 
	ret:useSMW({
		id = 'NPC ID',
		level = 'Combat level',
		xpraw = 'Combat experience',
	})
 
	ret:defineLinks({ { 'Template:%s/FAQ', 'FAQ' },
			{ 'Template:%s/doc', 'doc' } })
	ret:create()
	ret:cleanParams()
	ret:caption()
	ret:addClass('infobox-monster')
	ret:defineName('Infobox Monster')
	-- PARAMETER: image
	ret:addRow{
		{ tag = 'argd', content = 'image', class='infobox-image', colspan = '4' } }
 
	-- PARAMETER: release
	-- (update included automatically by infobox)
		:addRow{ { tag = 'th', content = 'Release' },
				{ tag = 'argd', content = 'release', css = { ['text-align'] = 'left' }, colspan = '3' } }
 
	-- PARAMETER: removal
	if ret:paramDefined('removal') then
		ret:addRow{ { tag = 'th', content = 'Removal' },
				{ tag = 'argd', content = 'removal', css = { ['text-align'] = 'left' }, colspan = '3' } }
	end
 
	-- PARAMETER: aka
	-- add only if it exists
	if ret:paramDefined('aka') then
		   ret:addRow{ { tag = 'th', content = 'AKA' },
					{ tag = 'argd', content = 'aka', css = { ['text-align'] = 'left' }, colspan = '3' } }
	end
	-- PARAMETER: members
	ret:addRow{ { tag = 'th', content = 'Members' },
				{ tag = 'argd', content = 'members', css = { ['text-align'] = 'left' }, colspan = '3' } }
		:addRow{ { tag = 'th', content = 'Examine', colspan = '4' } }
	-- PARAMETER: examine
		:addRow{ { tag = 'argd', content = 'examine', css = { ['text-align'] = 'left', ['max-width'] = '250px' }, colspan = '4' } }
 
	-- COMBAT INFO
		:addRow{ { tag = 'th', content = 'Combat info', css = { ['font-variant'] = 'small-caps' }, colspan = '4' } }
		-- PARAMETER: level | lifepoints | experience | hpxp
		:addRow{ { tag = 'th', content = '[[Combat level|Level]]', css = { width = '25%' } },
				{ tag = 'th', content = '[[Life points|LP]]', css = { width = '25%' } },
				{ tag = 'th', content = '[[File:Multicombat.png|link=|20px]] XP', css = { width = '25%' }, title = 'Combat style experience' },
				{ tag = 'th', content = '[[File:Constitution-icon.png|link=|20px]] XP', css = { width = '25%' }, title = 'Constitution experience' } }
 
		:addRow{ { tag = 'argd', content = 'level' },
				{ tag = 'argd', content = 'lifepoints' },
				{ tag = 'argd', content = 'experience' },
				{ tag = 'argd', content = 'hpxp' } }
		-- PARAMETER: wepxp
		:addRow{ { tag = 'th', content = '[[Equipment level|Equipment XP]] (2H/MH & Armour/OH)', colspan = '4' } }
		:addRow{ { tag = 'argd', content = 'wepxp', colspan = '4' } }
		-- PARAMETER: aggressive | poisonous
		:addRow{ { tag = 'th', content = '[[Aggressiveness|Aggressive]]', colspan = '2' },
				{ tag = 'th', content = 'Poisonous', colspan = '2' } }
		:addRow{ { tag = 'argd', content = 'aggressive', colspan = '2' },
				{ tag = 'argd', content = 'poisonous', colspan = '2' } }
	-- Slayer information
	-- dynamic size, dependent on whether or not the monster is assigned
	local slayer_level = ret:paramDefined('slaylvl','all')
	local not_assigned = ret:param('not_assigned','f')
	local _not_assigned = true
	if not_assigned.d == false then
		_not_assigned = false
	elseif not_assigned.switches then
		for _, v in ipairs(not_assigned.switches) do
			if v == false then
				_not_assigned = false
				break
			end
		end
	end
	-- do slayer row if a monster is assigned, or has a required level
	if _not_assigned == false or slayer_level == true then
		-- PARAMETER: slaylvl | slayxp | slayercat
		ret:addRow{ { tag = 'th', content = 'Slayer', class = 'slayer-header', colspan = '4' } }
			:addRow{ { tag = 'th', content = 'Level' },
					{ tag = 'th', content = 'XP' },
					{ tag = 'th', content = 'Category', colspan = '2' } }
			:addRow{ { tag = 'argd', content = 'slaylvl' },
					{ tag = 'argd', content = 'slayxp' },
					{ tag = 'argd', content = 'slayercat', colspan = '2' } }
			:addRow{ { tag = 'th', content = 'Assigned by', colspan = '4' } }
			:addRow{ { tag = 'argd', content = 'assigned_by',colspan = '4' } }
	end
 
	----------------
	-- OFFENSIVE STATS
	local max_disc = 'This value is the standard, non-legacy value. The number reflects the BASE maximum hit used by the monster in damage calculations. Damage-boosting mechanics such as enrage are not taken into consideration.'
	ret:addRow{ { tag = 'th', content = 'Offensive', class = 'offensive-header', colspan = '4' } }
 
		:addRow{ { tag = 'th', content = '[[Maximum hit|Max hit]]', class = 'offensive-subheader', colspan = '4' } }
	-- PARAMETER: max_melee | max_ranged | max_magic | max_spec
		:addRow{ { tag = 'th', content = '[[File:Attack-icon.png|20px|link=]]', title = 'Maximum melee hit' },
				{ tag = 'th', content = '[[File:Ranged-icon.png|20px|link=]]', title = 'Maximum ranged hit' },
				{ tag = 'th', content = '[[File:Magic-icon.png|20px|link=]]', title = 'Maximum magic hit' },
				{ tag = 'th', content = '[[File:Special attack icon.png|20px|link=]]', title = 'Maximum typeless/special hit' } }
		:addRow{ { tag = 'argd', content = 'max_melee', title = max_disc },
				{ tag = 'argd', content = 'max_ranged', title = max_disc },
				{ tag = 'argd', content = 'max_magic', title = max_disc },
				{ tag = 'argd', content = 'max_spec', title = max_disc } }
 
	-- PARAMETER: style | speed
		:addRow{ { tag = 'th', content = 'Style', class = 'offensive-subheader', colspan = '2' },
				{ tag = 'th', content = '[[Attack speed|Speed]]', class = 'offensive-subheader', colspan = '2' } }
 
		:addRow{ { tag = 'argd', content = 'style', colspan = '2' },
				{ tag = 'argd', content = 'speed', colspan = '2' } }
 
	-- PARAMETER: acc_melee | acc_ranged | acc_magic
		:addRow{ { tag = 'th', content = 'Combat levels', class = 'offensive-subheader', colspan = '4' } }
 
	--[[
		Accuracy parameters
		It's a big job because we need to have a nested table, so it's very hacky
	--]]
	local acc_melee,
		acc_ranged,
		acc_magic = ret:param('acc_melee','r') ,
					ret:param('acc_ranged','r'),
					ret:param('acc_magic','r')
	local lv_attack,
		lv_ranged,
		lv_magic = ret:param('attack','r') ,
					ret:param('ranged','r'),
					ret:param('magic','r')
	local levels_disc = "This is the monster's level in this combat skill. It functions in the same way a player's does - it affects the accuracy or armour in the same way (but not damage)."
 
		ret:tag('tr')
			:addClass('nestedinfo')
			:tag('td')
				:attr('colspan','4')
				:tag('table')
					:addClass('wikitable')
					:tag('tr')
						:tag('th')
							:attr('title','Attack level')
							:css('width','33%')
							:wikitext('[[File:Attack-icon.png|20px|link=]]')
						:done()
						:tag('th')
							:attr('title','Ranged level')
							:css('width','33%')
							:wikitext('[[File:Ranged-icon.png|20px|link=]]')
						:done()
						:tag('th')
							:attr('title','Magic level')
							:css('width','33%')
							:wikitext('[[File:Magic-icon.png|20px|link=]]')
						:done()
					:done()
					:tag('tr')
						-- PARAMETER: attack level
						:tag('td')
							:css('width','33%')
							:attr('title', levels_disc)
							:wikitext(lv_attack)
							:attr('data-attr-param','attack')
						:done()
						-- PARAMETER: ranged level
						:tag('td')
							:css('width','33%')
							:attr('title', levels_disc)
							:wikitext(lv_ranged)
							:attr('data-attr-param','ranged')
						:done()
						-- PARAMETER: magic level
						:tag('td')
							:css('width','33%')
							:attr('title', levels_disc)
							:wikitext(lv_magic)
							:attr('data-attr-param','magic')
						:done()
					:done()
					:tag('tr')
						:tag('th')
							:attr('colspan', 3)
							:addClass('offensive-subheader')
							:wikitext('[[Hit chance|Accuracy]]')
						:done()
					:done()
					:tag('tr')
						:tag('th')
							:attr('title','Melee accuracy as a function of 2.5 * f(x)')
							:css('width','33%')
							:wikitext('[[File:Attack-icon.png|20px|link=]]')
						:done()
						:tag('th')
							:attr('title','Ranged accuracy as a function of 2.5 * f(x)')
							:css('width','33%')
							:wikitext('[[File:Ranged-icon.png|20px|link=]]')
						:done()
						:tag('th')
							:attr('title','Magic accuracy as a function of 2.5 * f(x)')
							:css('width','33%')
							:wikitext('[[File:Magic-icon.png|20px|link=]]')
						:done()
					:done()
					:tag('tr')
						-- PARAMETER: melee accuracy
						:tag('td')
							:css('width','33%')
							:wikitext(acc_melee)
							:attr('data-attr-param','acc_melee')
						:done()
						-- PARAMETER: ranged accuracy
						:tag('td')
							:css('width','33%')
							:wikitext(acc_ranged)
							:attr('data-attr-param','acc_ranged')
						:done()
						-- PARAMETER: magic accuracy
						:tag('td')
							:css('width','33%')
							:wikitext(acc_magic)
							:attr('data-attr-param','acc_magic')
						:done()
					:done()
				:done()
			:done()
		:done()
	-- ACCURACY DONE (thank god!)
	-- PARAMETER: abilities
	-- only add if they exist
	local abilities = ret:param('abilities','f')
	local _abilities = false
	if abilities.d and abilities.d ~= 'None' then
		_abilities = true
	end
	if abilities.switches then
		for _, v in ipairs(abilities.switches) do
			if v ~= _nil then
				_abilities = true
				break
		   end
		end
	end
	if _abilities then
		ret:addRow{ { tag = 'th', content = 'Abilities used', class = 'offensive-subheader', colspan = '4' } }
			:addRow{ { tag = 'argd', content = 'abilities', colspan = '4' } }
 
	end
	-- DEFENSIVE STATS
	ret:addRow{ { tag = 'th', content = 'Defensive', class = 'defensive-header', colspan = '4' } }
	-- PARAMETER: armour | defence | weakness
		:addRow{ { tag = 'th', content = 'Armour', class = 'defensive-subheader' },
				{ tag = 'th', content = '[[File:Defence-icon.png|link=]]', class = 'defensive-subheader', title = 'Defence level' },
				{ tag = 'th', content = '[[Weakness]]', class = 'defensive-subheader', colspan = '2' } }
		:addRow{ { tag = 'argd', content = 'armour' },
				{ tag = 'argd', content = 'defence', title = levels_disc },
				{ tag = 'argd', content = 'weakness', colspan = '2' } }
 
	-- PARAMETER: explicit_weakness
	-- PARAMETER: aff_weakness | aff_melee | aff_ranged | aff_magic
		:addRow{ { tag = 'th', content = '[[Affinity|Affinities]]', class = 'defensive-subheader', colspan = '4' } }
		:addRow{ { tag = 'argh', content = 'explicit_weakness', title = 'Affinity value of the monster\'s explicit weakness' },
				{ tag = 'th', content = '[[File:Attack-icon.png|20px|link=]]', title = 'Affinity value of the monster against melee attacks' },
				{ tag = 'th', content = '[[File:Ranged-icon.png|20px|link=]]', title = 'Affinity value of the monster against ranged attacks' },
				{ tag = 'th', content = '[[File:Magic-icon.png|20px|link=]]', title = 'Affinity value of the monster against magic attacks' } }
		:addRow{ { tag = 'argd', content = 'aff_weakness' },
				{ tag = 'argd', content = 'aff_melee' },
				{ tag = 'argd', content = 'aff_ranged' },
				{ tag = 'argd', content = 'aff_magic' } }
 
	-- PARAMETER: immune_to_poison | immune_to_deflect | immune_to_stun | immune_to_drain
		:addRow{ { tag = 'th', content = 'Immunities', class = 'defensive-subheader', colspan = '4' } }
		:addRow{ { tag = 'th', content = '[[File:Immune to poison.png|link=]]', title = 'Immune to poison' },
				{ tag = 'th', content = '[[File:Immune to deflect.png|link=]]', title = 'Immune to deflect' },
				{ tag = 'th', content = '[[File:Immune to stun.png|link=]]', title = 'Immune to stun' },
				{ tag = 'th', content = '[[File:Immune to drain.png|link=]]', title = 'Immune to stat drain' } }
		:addRow{ { tag = 'argd', content = 'immune_to_poison' },
				{ tag = 'argd', content = 'immune_to_deflect' },
				{ tag = 'argd', content = 'immune_to_stun' },
				{ tag = 'argd', content = 'immune_to_drain' } }
	ret:finish()
	if onmain() then
		local a1 = ret:param('all')
		local a2 = ret:categoryData()
		ret:wikitext(addcategories(a1,a2))
	end
	return ret:tostring()
end
 
-- For numerical args
function numberargs(arg,v)
	local arg_v = (arg or ''):find('%S') and string.gsub(arg,',','') or -1
	local arg_i
	if arg_v == -1 then
		arg_i = nil
	elseif string.lower(arg_v) == 'n/a' then
		arg_i = 'N/A'
	elseif string.lower(arg_v) == 'varies' then
		arg_i = 'Varies'
	else
		arg_i = tonumber(arg_v:gsub(',',''),10)
		if not arg_i then
			arg_i = badarg(v,'should be a single numerical value.')
		end
	end
	return arg_i
end
 
-- For combat level
function combatarg(arg)
	local arg_v = (arg or ''):find('%S') and string.gsub(arg,',','') or -1
	local arg_i
	if arg_v == -1 then
		arg_i = nil
	elseif string.lower(arg_v) == 'n/a' or tonumber(arg_v) == 0 then
		arg_i = 'N/A'
	else
		arg_i = tonumber(arg_v:gsub(',',''),10)
		if not arg_i then
			arg_i = badarg('level','should be a single numerical value.')
		end
	end
	return arg_i
end
 
-- For numbers (adds commas)
function numargcommas(arg)
	local ret = numberargs(arg)
	if type(ret) == 'number' then
		return commas(ret)
	else
		return ret
	end
end
 
-- For numbers
function numargraw(arg)
	return tonumber(arg) or 0
end
 
-- For hp xp
function hpxparg(arg)
	local xp = string.gsub(arg or '',',','')
	if string.lower(xp) == 'n/a' then
		return 'N/A'
	else
		xp = tonumber(xp)
	end
	if type(xp) == 'number' then
		return commas(math.floor(xp*3.3)/10)
	else
		return nil
	end
end
 
-- weapon xp
function wepxparg(arg)
	local xp = string.gsub(arg or '',',','')
	if string.lower(xp) == 'n/a' then
		return 'N/A'
	else
		xp = tonumber(xp)
	end
	if type(xp) == 'number' then
		local th,mh,oh
		th = math.floor(xp * .06)
		mh = math.floor(xp * .04)
		oh = math.floor(xp * .02)
		return string.format('%s / %s / %s',th,mh,oh)
	else
		return nil
	end
end
-- For true/false
function boolargs(arg,argr)
	local arg_v = (arg or ''):find('%S') and arg or -1
 
	local arg_ret
 
	if arg_v == -1 then
		arg_ret = nil
	else
		arg_v = yesno(arg_v)
		local argf = '<span title="This monster is%s %s.">%s</span>'
		local f1,f3
		local f2 = string.gsub(argr,'_',' ')
 
		if arg_v then
			f1 = ''
			f3 = '[[File:Yes check.svg|20px|alt=Yes|link=]]'
		else
			f1 = ' not'
			f3 = '[[File:X mark.svg|20px|alt=No|link=]]'
		end
 
		arg_ret = string.format(argf,f1,f2,f3)
	end
 
	return arg_ret
end
 
-- Poison
function poisonarg(arg)
	arg = string.gsub(arg or '',',','')
	arg = string.lower(arg)
 
	if arg == 'yes' then
		arg = '<span title="This monster is poisonous but has no base value defined. Change the |poisonous parameter to a number.">[[File:Yes check.svg|20px|alt=Yes|link=]] ???</span>'
	elseif tonumber(arg) then
		arg = '<span title="This monster is poisonous. The number shown is the base value at which poison damage starts.">[[File:Yes check.svg|20px|alt=Yes|link=]] '..tonumber(arg)..'</span>'
	else
		arg = '<span title="This monster is not poisonous.">[[File:X mark.svg|20px|alt=No|link=]]</span>'
	end
 
	return arg
end
 
-- style
function stylearg(arg)
	-- split by commas
	local atts = mw.text.split(string.lower(arg or ''),'%s*,%s*')
	local _atts = {}
	-- remake the list as a table, remove anything that's blank/doesn't exist
	for _, v in ipairs(atts) do
		local att_x = styles_map[v]
		if att_x then
			table.insert(_atts,attack_styles[att_x])
		end
	end
	local p_att
	if #_atts == 0 then
		p_att = nil
	else
		p_att = {}
		for _, v in ipairs(_atts) do
			table.insert(p_att,string.format('[[File:%s.png|25px|link=%s]]',v.image,v.link))
		end
		p_att = table.concat(p_att,' ')
	end
	return p_att
end
 
-- weakness
function weaknessarg(arg)
	-- split by commas
	local wk = mw.text.split(string.lower(arg or ''),'%s*,%s*')
	local _wk = {}
 
	-- remake the list as a table, remove anything that's blank/doesn't exist
	for _, v in ipairs(wk) do
		local wk_x = weaknesses[v]
		if wk_x then
			table.insert(_wk,wk_x)
		end
	end
	local p_wk
	if #_wk == 0 then
		p_wk = nil
	else
		p_wk = {}
		for _, v in ipairs(_wk) do
			table.insert(p_wk,string.format('[[File:%s|25px|link=%s]]',v.image,v.link))
		end
		p_wk = table.concat(p_wk,' ')
	end
	return p_wk
end
 
-- Explicit weakness
-- weakness / explicit weakness
function explicitwkarg(arg)
	-- split by commas
	local wk = mw.text.split(string.lower(arg or ''),'%s*,%s*')
	local _wk = weaknesses[wk[1]]
	if _wk then
		return string.format('[[File:%s|20px|link=]]',_wk.image)
	else
		return nil
	end
end
 
function aff_weakness_arg(aff,aff_r,weakness)
	-- split by commas
	local wk = mw.text.split(string.lower(weakness or ''),'%s*,%s*')
	local _wk = weaknesses[wk[1]]
	if _wk and _wk.text == 'Nothing' then
		return '-'
	else
		return numberargs(aff,aff_r)
	end
end
 
 
function wkcats(arg,tbl)
	for _, v in pairs(weaknesses) do
		if arg:find(v.image) then
			if v.category then
				table.insert(tbl,v.category)
			end
		end
	end
end
 
function slaycats(arg,tbl)
	for _, v in pairs(slay_masters) do
		if arg:find(v.chathead) then
			if v.category then
				table.insert(tbl,v.category)
			end
		end
	end
end
 
-- Slayer assigners
function slayerarg(_arg)
	local arg = _arg
	if arg then
		arg = mw.text.split(string.lower(arg),'%s*,%s*')
		local slayer_master_list = {
			turael = false,
			spria = false,
			mazchna = false,
			achtryn = false,
			vannaka = false,
			chaeldar = false,
			sumona = false,
			duradel = false,
			lapalok = false,
			kuradal = false,
			morvran = false,
			none = false
		}
		for _, v in ipairs(arg) do
			if slay_masters_map[v] then
				slayer_master_list[slay_masters_map[v]] = true
			end
		end
		if slayer_master_list.none then
			arg = 'Not assigned'
		else
			arg = {}
			for n, v in pairs(slayer_master_list) do
				if v then
					--table.insert(params.assigned_by, slay_masters[n].text)
					table.insert(arg, 1, string.format('[[File:%s.png|30px|link=%s]]',slay_masters[n].chathead,n))
				end
			end
			arg = table.concat(arg,' ')
		end			
	else
		arg = nil
	end
	return arg
end
 
-- Not assigned
function notassarg(arg)
	if arg then
		if arg:find('%?action=edit') or not arg:find('%S') then
			return true
		end
		arg = mw.text.split(string.lower(arg),'%s*,%s*')
		for _, v in ipairs(arg) do
			if slay_masters_map[v] == 'none' then
				return true
			end
		end
	end
	return false
end
 
-- Abilities used
function abilarg(arg)
	arg = paramtest.default_to(arg,false)
	if not arg then
		arg = 'None'
	elseif arg:find('clickpic') then
		arg = mw.getCurrentFrame():preprocess(arg)
	else
		arg = 'None'
	end
	return arg
end
 
-- Attacks speed
function speedarg(arg)
	if paramtest.is_empty(arg) then
		return nil
	end
	_,_,arg = string.find(arg:lower()..' ','^(.-)%s')
	arg = speeds[speed_map[arg]] or badarg('speed',' is not a valid attack speed')
	return arg
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
 
function addcategories(args,catargs)
	local ret = { 'Bestiary' }
	local cat_map = {
		-- Added if the parameter has content
		defined = {
			aka = 'Pages with AKA',
			},
		-- 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',
			experience = 'Needs XP per kill',
			immune_to_stun = 'Missing immunity information',
			immune_to_poison = 'Missing immunity information',
			immune_to_deflect = 'Missing immunity information',
			immune_to_drain = 'Missing immunity information',
			attack = 'Missing combat skill levels',
			magic = 'Missing combat skill levels',
			ranged = 'Missing combat skill levels',
			defence = 'Missing combat skill levels',
			},
		-- Parameters that are either true or false
		-- map a category to a boolean value
		--[=[ yesno = {
			members = { [true] = '', [false] = 'F2P bestiary' },
			abilities = { [true] = 'Monsters that use abilities', [false] = '' },
			immune_to_stun = { [true] = 'Stun-immune', [false] = '' },
		},-- ]=]
		-- regex
		grep = {
			poisonous = { ['yes check%.svg'] = 'Poisonous monsters' },
			aggressive = { ['yes check%.svg'] = 'Aggressive monsters' },
		},
	}
 
	-- Run and add mapped 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
 
	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
 
 
	local levels = { args.level.d }
	if args.level.switches then
		for _, v in ipairs(args.level.switches) do
			if v ~= infobox.nilParam() then
				table.insert(levels,v)
			end
		end
	end
 
	for _, v in ipairs(levels) do
		if v == 'N/A' then
			table.insert(ret,'Monsters with no combat level')
		elseif tonumber(v) then
			table.insert(ret,string.format('Combat level %s monsters',v))
		end
	end
 
	if args.members.d:find('[Nn]o') then
		table.insert(ret,'F2P bestiary')
	elseif args.members.switches then
		for _, v in ipairs(args.members.switches) do
			if v:find('[Nn]o') then
				table.insert(ret,'F2P bestiary')
				break
			end
		end
	end
	if args.abilities.d:find('clickpic') then
		table.insert(ret,'Monsters that use abilities')
	elseif args.abilities.switches then
		for _, v in ipairs(args.abilities.switches) do
			if v:find('clickpic') then
				table.insert(ret,'Monsters that use abilities')
				break
			end
		end
	end
	if args.weakness.d then
		wkcats(args.weakness.d,ret)
	end
	if args.weakness.switches then
		for _, v in ipairs(args.weakness.switches) do
			if v ~= _nil then
				wkcats(v,ret)
			end
		end
	end
 
	if args.assigned_by.d then
		slaycats(args.assigned_by.d,ret)
	end
	if args.assigned_by.switches then
		for _, v in ipairs(args.assigned_by.switches) do
			if v ~= _nil then
				slaycats(v,ret)
			end
		end
	end
	-- combine table and format category wikicode
	for i, v in ipairs(ret) do
		if (v ~= '') then
			ret[i] = string.format('[[Category:%s]]',v)
		end
	end
 
	return table.concat(ret,'')
end
 
return p

Interférence d'un bloqueur de publicité détectée !


Wikia est un site gratuit qui compte sur les revenus de la publicité. L'expérience des lecteurs utilisant des bloqueurs de publicité est différente

Wikia n'est pas accessible si vous avez fait d'autres modifications. Supprimez les règles personnalisées de votre bloqueur de publicité, et la page se chargera comme prévu.