Module:CombatStyles

From Roat Pkz
Revision as of 19:01, 12 May 2024 by Hefner (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Documentation for this module may be created at Module:CombatStyles/doc

local p = {}

local paramTest = require('Module:Paramtest')

local CombatOptionLink = {
	['Melee'] = 'Combat Options#Melee weapons',
	['Ranged'] = 'Combat Options#Ranged weapons',
	['Magic'] = 'Combat Options#Magic weapons',
	['Multiple'] = 'Combat Options',
	['None'] = '',
}

-- Combat type
--  Weapon Style
--   Weapon Style
--   Experience gained
--   Invisible boost
local WeaponStyles = {
	['Magic'] = {
		['Accurate'] = { -- Trident only
			['Weapon Style'] = 'Accurate',
			['Experience'] = '[[File:Magic icon.png|alt=Magic|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = '+3 Magic',
		},
		['Defensive'] = {
			['Weapon Style'] = 'Defensive',
			['Experience'] = '[[File:Magic icon.png|alt=Magic|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = '+3 Defence',
		},
		['Autocast'] = {
			['Weapon Style'] = 'Autocast',
			['Experience'] = '[[File:Magic icon.png|alt=Magic|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = 'None',
		},
		['Defensive Autocast'] = {
			['Weapon Style'] = 'Defensive Autocast',
			['Experience'] = '[[File:Magic icon.png|alt=Magic|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]] [[File:Defence icon.png|alt=Defence|link=]]',
			['Boost'] = 'None',
		},
		['Longrange'] = { -- Trident only
			['Weapon Style'] = 'Longrange',
			['Experience'] = '[[File:Magic icon.png|alt=Magic|link=]] [[File:Defence icon.png|alt=Defence|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = '+1 Magic, +3 Defence',
		},
	},
	['Melee'] = {
		['Accurate'] = {
			['Weapon Style'] = 'Accurate',
			['Experience'] = '[[File:Attack icon.png|alt=Attack|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = '+3 Attack',
		},
		['Aggressive'] = {
			['Weapon Style'] = 'Aggressive',
			['Experience'] = '[[File:Strength icon.png|alt=Strength|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = '+3 Strength',
		},
		['Controlled'] = {
			['Weapon Style'] = 'Controlled',
			['Experience'] = '[[File:Attack icon.png|alt=Attack|link=]] [[File:Strength icon.png|alt=Strength|link=]] [[File:Defence icon.png|alt=Defence|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = '+1 Attack, Strength, Defence',
		},
		['Defensive'] = {
			['Weapon Style'] = 'Defensive',
			['Experience'] = '[[File:Defence icon.png|alt=Defence|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = '+3 Defence',
		},
	},
	['Ranged'] = {
		['Accurate'] = {
			['Weapon Style'] = 'Accurate',
			['Experience'] = '[[File:Ranged icon.png|alt=Ranged|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = '+3 Ranged',
		},
		['Rapid'] = {
			['Weapon Style'] = 'Rapid',
			['Experience'] = '[[File:Ranged icon.png|alt=Ranged|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = 'None',
		},
		['Longrange'] = {
			['Weapon Style'] = 'Longrange',
			['Experience'] = '[[File:Ranged icon.png|alt=Ranged|link=]] [[File:Defence icon.png|alt=Defence|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = '+3 Defence',
		},
		['Short fuse'] = {
			['Weapon Style'] = 'Short fuse',
			['Experience'] = '[[File:Ranged icon.png|alt=Ranged|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = '+3 Ranged',
		},
		['Medium fuse'] = {
			['Weapon Style'] = 'Medium fuse',
			['Experience'] = '[[File:Ranged icon.png|alt=Ranged|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = 'None',
		},
		['Long fuse'] = {
			['Weapon Style'] = 'Long fuse',
			['Experience'] = '[[File:Ranged icon.png|alt=Ranged|link=]] [[File:Defence icon.png|alt=Defence|link=]] [[File:Hitpoints icon.png|alt=Hitpoints|link=]]',
			['Boost'] = 'None',
		},
	},
	['None'] = {
		['Weapon Style'] = 'None',
		['Experience'] = 'None',
		['Boost'] = 'None',
	},
}

-- WeaponType
--  Combat Type
--  {
--    Combat Style
--    Attack type
--    Style type (The above tables)
--  }
local WeaponTypes = {
	['2h Sword'] = {
		'Melee',
		{
			'Chop',
			'Slash',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Slash',
			'Slash',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Smash',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Block',
			'Slash',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Axe'] = {
		'Melee',
		{
			'Chop',
			'Slash',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Hack',
			'Slash',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Smash',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Block',
			'Slash',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Banner'] = {
		'Melee',
		{
			'Lunge',
			'Stab',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Swipe',
			'Slash',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Pound',
			'Crush',
			WeaponStyles['Melee']['Controlled'],
		},
		{
			'Block',
			'Stab',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Bladed Staff'] = {
		'Multiple',
		{
			'Jab',
			'Stab',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Swipe',
			'Slash',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Fend',
			'Crush',
			WeaponStyles['Melee']['Defensive'],
		},
		{
			'Spell',
			'Magic',
			WeaponStyles['Magic']['Defensive Autocast'],
		},
		{
			'Spell',
			'Magic',
			WeaponStyles['Magic']['Autocast'],
		},
	},
	['Blaster'] = {
		'None',
		{
			'Explosive',
			'Fires explosive round',
		},
		{
			'Flamer',
			'Emits a jet of flame',
		},
	},
	['Bludgeon'] = {
		'Melee',
		{
			'Pound',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Pummel',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Smash',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
	},
	['Blunt'] = {
		'Melee',
		{
			'Pound',
			'Crush',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Pummel',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Block',
			'Crush',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Bow'] = {
		'Ranged',
		{
			'Accurate',
			'Ranged',
			WeaponStyles['Ranged']['Accurate'],
		},
		{
			'Rapid',
			'Ranged',
			WeaponStyles['Ranged']['Rapid'],
		},
		{
			'Longrange',
			'Ranged',
			WeaponStyles['Ranged']['Longrange'],
		},
	},
	['Bulwark'] = {
		'Melee',
		{
			'Pummel',
			'Crush',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Block',
			'None',
			WeaponStyles['None'],
		},
	},
	['Chinchompas'] = {
		'Ranged',
		{
			'Short fuse',
			'Ranged',
			WeaponStyles['Ranged']['Short fuse'],
		},
		{
			'Medium fuse',
			'Ranged',
			WeaponStyles['Ranged']['Medium fuse'],
		},
		{
			'Long fuse',
			'Ranged',
			WeaponStyles['Ranged']['Long fuse'],
		},
	},
	['Claw'] = {
		'Melee',
		{
			'Chop',
			'Slash',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Slash',
			'Slash',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Lunge',
			'Stab',
			WeaponStyles['Melee']['Controlled'],
		},
		{
			'Block',
			'Slash',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Crossbow'] = {
		'Ranged',
		{
			'Accurate',
			'Ranged',
			WeaponStyles['Ranged']['Accurate'],
		},
		{
			'Rapid',
			'Ranged',
			WeaponStyles['Ranged']['Rapid'],
		},
		{
			'Longrange',
			'Ranged',
			WeaponStyles['Ranged']['Longrange'],
		},
	},
	['Gun'] = {
		'Melee',
		{
			'Aim and Fire',
			'None',
			WeaponStyles['None'],
		},
		{
			'Kick',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
	},
	['Partisan'] = {
		'Melee',
		{
			'Stab',
			'Stab',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Lunge',
			'Stab',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Pound',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Block',
			'Stab',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Pickaxe'] = {
		'Melee',
		{
			'Spike',
			'Stab',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Impale',
			'Stab',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Smash',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Block',
			'Stab',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Polearm'] = {
		'Melee',
		{
			'Jab',
			'Stab',
			WeaponStyles['Melee']['Controlled'],
		},
		{
			'Swipe',
			'Slash',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Fend',
			'Stab',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Polestaff'] = {
		'Melee',
		{
			'Bash',
			'Crush',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Pound',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Block',
			'Crush',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Powered Staff'] = {
		'Magic',
		{
			'Accurate',
			'Magic',
			WeaponStyles['Magic']['Accurate'],
		},
		{
			'Accurate',
			'Magic',
			WeaponStyles['Magic']['Accurate'],
		},
		{
			'Longrange',
			'Magic',
			WeaponStyles['Magic']['Longrange'],
		},
	},
	['Powered Wand'] = {
		'Magic',
		{
			'Accurate',
			'Magic',
			WeaponStyles['Magic']['Accurate'],
		},
		{
			'Accurate',
			'Magic',
			WeaponStyles['Magic']['Accurate'],
		},
		{
			'Longrange',
			'Magic',
			WeaponStyles['Magic']['Longrange'],
		},
	},
	['Salamander'] = {
		'Multiple',
		{
			'Scorch',
			'Slash',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Flare',
			'Ranged',
			WeaponStyles['Ranged']['Accurate'],
		},
		{
			'Blaze',
			'Magic',
			WeaponStyles['Magic']['Defensive'],
		},
	},
	['Scythe'] = {
		'Melee',
		{
			'Reap',
			'Slash',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Chop',
			'Slash',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Jab',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Block',
			'Slash',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Slash Sword'] = {
		'Melee',
		{
			'Chop',
			'Slash',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Slash',
			'Slash',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Lunge',
			'Stab',
			WeaponStyles['Melee']['Controlled'],
		},
		{
			'Block',
			'Slash',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Spear'] = {
		'Melee',
		{
			'Lunge',
			'Stab',
			WeaponStyles['Melee']['Controlled'],
		},
		{
			'Swipe',
			'Slash',
			WeaponStyles['Melee']['Controlled'],
		},
		{
			'Pound',
			'Crush',
			WeaponStyles['Melee']['Controlled'],
		},
		{
			'Block',
			'Stab',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Spiked'] = {
		'Melee',
		{
			'Pound',
			'Crush',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Pummel',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Spike',
			'Stab',
			WeaponStyles['Melee']['Controlled'],
		},
		{
			'Block',
			'Crush',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Stab Sword'] = {
		'Melee',
		{
			'Stab',
			'Stab',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Lunge',
			'Stab',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Slash',
			'Slash',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Block',
			'Stab',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Staff'] = {
		'Multiple',
		{
			'Bash',
			'Crush',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Pound',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Focus',
			'Crush',
			WeaponStyles['Melee']['Defensive'],
		},
		{
			'Spell',
			'Magic',
			WeaponStyles['Magic']['Defensive Autocast'],
		},
		{
			'Spell',
			'Magic',
			WeaponStyles['Magic']['Autocast'],
		},
	},
	['Thrown'] = {
		'Ranged',
		{
			'Accurate',
			'Ranged',
			WeaponStyles['Ranged']['Accurate'],
		},
		{
			'Rapid',
			'Ranged',
			WeaponStyles['Ranged']['Rapid'],
		},
		{
			'Longrange',
			'Ranged',
			WeaponStyles['Ranged']['Longrange'],
		},
	},
	['Unarmed'] = {
		'Melee',
		{
			'Punch',
			'Crush',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Kick',
			'Crush',
			WeaponStyles['Melee']['Aggressive'],
		},
		{
			'Block',
			'Crush',
			WeaponStyles['Melee']['Defensive'],
		},
	},
	['Whip'] = {
		'Melee',
		{
			'Flick',
			'Slash',
			WeaponStyles['Melee']['Accurate'],
		},
		{
			'Lash',
			'Slash',
			WeaponStyles['Melee']['Controlled'],
		},
		{
			'Deflect',
			'Slash',
			WeaponStyles['Melee']['Defensive'],
		},
	}
}

function speedarg(arg, weaponType, elementNum)
	if paramTest.is_empty(arg) then
		return nil
	end
	
	rootyTootyRapidShooty = {['Rapid']=true, ['Medium fuse']=true, ['Flare']=true}								--Combat styles that provide an attack speed bonus
	phallic = {['Staff']=true, ['Bladed Staff']=true}
	local pageName = mw.title.getCurrentTitle().text
	local numarg = tonumber(arg)
    local lowarg = string.lower(arg)

	if numarg ~= nil then
		if rootyTootyRapidShooty[WeaponTypes[weaponType][elementNum][1]] then
			return string.format('%s ticks (%.1fs)', numarg - 1, (numarg - 1) * 0.6)
   		elseif not (phallic[weaponType] and elementNum == 5) then
			return string.format('%s ticks (%.1fs)', numarg, numarg * 0.6)
		end	
	end

	if (phallic[weaponType] and elementNum == 5) then
		if pageName == 'Harmonised nightmare staff' then
			return string.format('%s ticks (%.1fs)<br/><span title="The harmonised nightmare staff has an attack speed of 4 ticks when autocasting offensive spells from the standard spellbook, and does not suffer from an initial one tick delay." style="cursor:help; border-bottom:1px dotted;"><i><small>standard spells</small></i></span>', 4, 4 * 0.6)
		else
			return string.format('<span title="In contrast to manually casting spells, the first attack is delayed by 1 tick when using autocast." style="cursor:help; border-bottom:1px dotted;">%s ticks (%.1fs)</span>', 5, 5 * 0.6)
		end
	end

	if lowarg ~= nil then
		if lowarg == 'varies' then																		--As of writing only the beta item "Tumeken's heka" uses "varies"
    		return '<span title="This weapon has a variable attack speed." style="cursor:help; border-bottom:1px dotted;">Variable</span>'
		end
		return string.format('N/A')
	end	
	return nil
end

function rangearg(arg, weaponType, elementNum)
	if paramTest.is_empty(arg) then
		return nil
	end
	
	rootyTootyLongrangeShooty = {['Longrange']=true, ['Long fuse']=true}								--Weapon styles that provide an attack range bonus
	tooStronk = false
	local numarg = tonumber(arg)
    local lowarg = string.lower(arg)
    
    if numarg ~= nil then
		if rootyTootyLongrangeShooty[WeaponTypes[weaponType][elementNum][1]] then
			if (numarg ~= 9 and numarg ~= 10) then
				return string.format('%s %s', numarg + 2, 'tiles')
			elseif 	numarg == 9 then
				return string.format('%s %s', numarg + 1, 'tiles')
			elseif numarg == 10 then
				tooStronk = true
				return string.format('%s %s', numarg, 'tiles')
			end
   		elseif not phallic[weaponType] then
			return string.format('%s %s', numarg, (numarg > 1) and 'tiles' or 'tile')
		end
    end

	if phallic[weaponType] then
		if elementNum == 2 then
			return '1 tile'
		elseif elementNum == 5 then	
			return '10 tiles'
		end	
	end
	
	if lowarg ~= nil then
		if lowarg == 'varies' then
    		return '<span title="This weapon has a variable attack range." style="cursor:help; border-bottom:1px dotted;">Variable</span>'
		end
		return 'N/A'
	end	
	return nil
end

-- Build table rows
function buildRow(elementNum, weaponType, range, speed)
	local ret = mw.html.create('tr')
	local combatStyleIcon = string.lower(WeaponTypes[weaponType][elementNum][1])						--Add image of corresponding icon to each combat style
	local phallic = {['Staff']=true, ['Bladed Staff']=true}
		if phallic[weaponType] then
			if (WeaponTypes[weaponType][elementNum][3]['Weapon Style']:match('Defensive Autocast')) then
			combatStyleIcon = string.format(combatStyleIcon .. ', defensive')								--Account for autocast and defensive autocast both being labelled 'Spell' by checking against weapon style
			end
		end

			ret:tag('td')																				--WeaponTypes enters the second table
					:css({																				--WeaponTypes[weaponType] selects the combat options category in that table
							['border-right-style'] = 'hidden',											--WeaponTypes[weaponType][elementNum] iterates starting from the second option
							['padding-right'] = '0',													--		(e.g. skips 'Ranged', selects following three tables in succession)
							['text-align'] = 'center',													--WeaponTypes[weaponType][elementNum][1] selects the first entry in each of those tables
					})																					
					
					:wikitext('[[File:CombatStyles_(' .. string.lower(weaponType:gsub("%s+", "_")) .. ',_' .. combatStyleIcon .. ').png|link=]]')
					:done()	

	for i, v in ipairs(WeaponTypes[weaponType][elementNum]) do
		if(type(v) == 'table') then
			
			ret:tag('td'):wikitext(v['Weapon Style']):done()	
			
			if speedarg(speed, weaponType, elementNum) ~= nil then
				if phallic[weaponType]	then
					if elementNum == 2 then
						ret:tag('td')
							:wikitext(speedarg(speed, weaponType, elementNum))
							:attr('rowspan', 3):done()
					elseif elementNum == 5 then
						ret:tag('td')	
							:wikitext(speedarg(speed, weaponType, elementNum))
							:attr('rowspan', 2):done()
					end		
				
				elseif	(WeaponTypes[weaponType][1]:match('Melee') or string.lower(weaponType) == 'powered staff') then
					if elementNum == 2 then
						ret:tag('td')
							:wikitext(speedarg(speed, weaponType, elementNum))
							:attr('rowspan', #WeaponTypes[weaponType] - 1)
							:css('text-align', 'center'):done()
					end		
				else
					if  rootyTootyRapidShooty[WeaponTypes[weaponType][elementNum][1]] then
						ret:tag('td')
							:wikitext(speedarg(speed, weaponType, elementNum))
							:addClass('table-yes'):done()
					else
						ret:tag('td')
							:wikitext(speedarg(speed, weaponType, elementNum)):done()
					end
				end	
			end

			if rangearg(range, weaponType, elementNum) ~= nil then
				if phallic[weaponType]	then
					if elementNum == 2 then
						ret:tag('td')
							:wikitext(rangearg(range, weaponType, elementNum))
							:attr('rowspan', 3):done()
					elseif elementNum == 5 then
						ret:tag('td')
							:wikitext(rangearg(range, weaponType, elementNum))
							:attr('rowspan', 2):done()
					end
				elseif	(WeaponTypes[weaponType][1]:match('Melee')) then
					if elementNum == 2 then
						ret:tag('td')
							:wikitext(rangearg(range, weaponType, elementNum))
							:attr('rowspan', #WeaponTypes[weaponType] - 1)
							:css('text-align', 'center'):done()
					end		
				else
					if  (rootyTootyLongrangeShooty[WeaponTypes[weaponType][elementNum][1]] and tooStronk ~= true) then
						ret:tag('td')
							:wikitext(rangearg(range, weaponType, elementNum))
							:addClass('table-yes'):done()
					else
						ret:tag('td')
							:wikitext(rangearg(range, weaponType, elementNum)):done()
					end
				end	
			end		
		
			ret:tag('td')
					:addClass('combat-styles-icons')
					:wikitext(v['Experience'])
					:done()	
			ret:tag('td'):wikitext(v['Boost']):done()
			
		else	
			ret:tag('td'):wikitext(v):done()
		end
	end
	return ret
end

-- Two header rows
--  First is full table span link to weaponType
--  Second is Style type, Weapon style, Attack speed, Range, Experience, Invisible level boosts
--   CombatOptionLink changes subsection of [[Combat Options]] linked to
function createHeader(weaponType, range, speed)
	local ret = mw.html.create('table'):addClass('wikitable combat-styles')
	-- colspan is 8 except for weapons without attack optons, which use 3
	local colCount = WeaponTypes[weaponType][1] == 'None' and 3 or 8
	ret:tag('tr'):done()
	ret:tag('th'):addClass('combat-styles-header'):wikitext('Combat style'):attr('colspan',2):done()
	ret:tag('th'):addClass('combat-styles-header'):wikitext('Attack type'):done()
	if(colCount == 8) then
		ret:tag('th'):addClass('combat-styles-header'):wikitext('Weapon style'):done()
		if paramTest.has_content(speed) then		
			ret:tag('th'):addClass('combat-styles-header'):wikitext('Attack speed'):done()
		end	
		if paramTest.has_content(range) then
			ret:tag('th'):addClass('combat-styles-header'):wikitext('Range'):done()
		end
		ret:tag('th'):addClass('combat-styles-header'):wikitext('Experience'):done()
		ret:tag('th'):addClass('combat-styles-header'):wikitext('Level boost'):done()
	end
	return ret
end

function p._main(args)
	local weaponType, range, speed
	if(args[1] ~= nil) then
		weaponType = args[1]
		range = args.attackrange
		speed = args.speed
	end
	
	-- Force Pascal Case
	weaponType = string.gsub(" " .. weaponType:lower(), "%W%l", string.upper):sub(2)
	
	if(WeaponTypes[weaponType] ~= nil) then
		local ret = createHeader(weaponType, range, speed)
		-- Skip [1], the CombatOptionLink setting
		for i = 2, #WeaponTypes[weaponType], 1 do
			ret:node(buildRow(i, weaponType, range, speed))
		end
		local clear = mw.html.create('div'):css('clear','left'):done()

		return tostring(ret), tostring(clear)

	else
		error('Invalid or empty parameter for weaponType with value: ' .. (weaponType or ''))
	end
end

--mw.log(p._main({'Bow', ['range'] = 9}))

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

return p