Module:Crystal Rain calculator

From WIDEVERSE Wiki
Revision as of 22:22, 4 November 2021 by Admin (talk | contribs) (1 revision imported)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search

Documentation for this module may be created at Module:Crystal Rain calculator/doc

-- <pre>
local p = {}

local yesno = require ("Module:Yesno")
local lang = mw.getContentLanguage()

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

function p._main(invokeArgs,args)
	
	local ad = tonumber(args.AD) or 0
    local rangedlvl = tonumber(args.ranged) or 0
    local preciseRank = tonumber(args.precise) or 0
    local equilibriumRank = tonumber(args.eq) or 0
    local weaponSwitch = args.weaponSwitch
    local eqSwitchRank = tonumber(args.eqswitch) or -1
    local splitSoul = args.splitSoul or ""
    local ruthlessRank = tonumber(args.ruthless) or 0
    local ruthlessStacks = tonumber(args.rstacks) or 0
    local bitingRank = tonumber(args.biting) or 0
    local bitingLevel20 = args.bitinglvl20
    local pocket = args.pocket
    local potion = args.potion
    local berserkBloodEssence = args.essence or ""
    local prayer = args.prayer
    local aura = args.aura
    local vuln = args.vuln
    local swiftness = args.swiftness
    local needle = args.needle
    local dhrelic = args.dhrelic
    local ripper = tonumber(args.ripper) or 0
    local telosBeam = args.telosBeam
    local npc = args.npc
    
	return calculateDamage(ad,rangedlvl,preciseRank,equilibriumRank,weaponSwitch,eqSwitchRank,splitSoul,ruthlessRank,ruthlessStacks,bitingRank,bitingLevel20,pocket,potion,berserkBloodEssence,prayer,aura,vuln,swiftness,needle,dhrelic,ripper,telosBeam,npc)
	
end

function calculateDamage(ad,rangedlvl,preciseRank,equilibriumRank,weaponSwitch,eqSwitchRank,splitSoul,ruthlessRank,ruthlessStacks,bitingRank,bitingLevel20,pocket,potion,berserkBloodEssence,prayer,aura,vuln,swiftness,needle,dhrelic,ripper,telosBeam,npc)
	
	-- calculate effective level and Ability damage (AD)
	local lvlMult = 1
	local lvlAdd = 0
	if(potion=="Elder overload potion") then lvlMult = 1.17; lvlAdd = 5
	elseif(potion=="Supreme overload potion" or potion=="Supreme ranging potion") then lvlMult = 1.16; lvlAdd = 4
	elseif(potion=="Overload") then lvlMult = 1.15; lvlAdd = 3
	end
	local lvlAura = 0
	if(aura=="Reckless") then lvlAura = 0.1 end
	
	local rangedlvlEff = rangedlvl
	if(potion=="Supreme ranging potion") then
		rangedlvlEff = math.floor(rangedlvl*lvlMult+lvlAdd)
		if(berserkBloodEssence=="Yes") then -- 133 stats at level 99 (with or without reckless)
			rangedlvlEff = rangedlvlEff + math.floor(rangedlvl*1.14+2) - rangedlvl
		end
	elseif(potion=="None") then
		rangedlvlEff = math.floor(rangedlvl*(lvlAura + lvlMult))
		if(berserkBloodEssence=="Yes") then -- 123 stats at level 99 with reckless (114 without)
			rangedlvlEff = rangedlvlEff + math.floor(rangedlvl*1.14+2) - rangedlvl
		end
	else --overloads
		rangedlvlEff = math.floor(rangedlvl*(lvlAura + lvlMult)+lvlAdd)
	end
	
	local prayerMod = 1
	if(prayer=="Desolation") then prayerMod = 1.12
	elseif(prayer=="Anguish") then prayerMod = 1.10
	elseif(prayer=="Leech Range Strength + Amulet of zealots") then prayerMod = 1.18
	elseif(prayer=="Overpowering Force + Amulet of zealots") then prayerMod = 1.16
	elseif(prayer=="Rigour") then prayerMod = 1.08
	end
	
	--local adEff = math.floor(ad*prayerMod)
	
	-- base sgb arrow range %s
	local arrowFixedPercent = {80,80,80,80,80}
	local arrowVarPercent = {120,160,133,106,80}
	
	-- sgb as damage from AD
	local arrowFixedBase = {0,0,0,0,0}
	local arrowVarBase = {0,0,0,0,0}
	
	-- sgb arrows as damage from ADeff
	local arrowFixed = {0,0,0,0,0}
	local arrowVar = {0,0,0,0,0}
	--base
	for arrow = 1,5 do 
		arrowFixedBase[arrow] = math.floor(ad*arrowFixedPercent[arrow]/100)
		arrowVarBase[arrow] = math.floor(ad*arrowVarPercent[arrow]/100)
		arrowFixed[arrow] = math.floor(arrowFixedBase[arrow]*prayerMod) -- prayerMod applied here
		arrowVar[arrow] = math.floor(arrowVarBase[arrow]*prayerMod) -- prayerMod applied here
	end
	
	--boosted
	for arrow = 1,5 do 
		arrowFixed[arrow] = arrowFixed[arrow] + 4*(rangedlvlEff - rangedlvl)
		arrowVar[arrow] = arrowVar[arrow] + 4*(rangedlvlEff - rangedlvl)
	end
	
	--precise
	local Aprecise = math.floor(.015*preciseRank*(arrowFixed[1]+arrowVar[1]))
	arrowFixed[1] = arrowFixed[1] + Aprecise
	for arrow = 2,5 do arrowFixed[arrow] = arrowFixed[1] end
	arrowVar[1] = arrowVar[1] - Aprecise
	arrowVar[2] = 2*arrowFixed[1]
	arrowVar[3] = math.floor(5/3*arrowFixed[1])
	arrowVar[4] = math.floor(4/3*arrowFixed[1])
	arrowVar[5] = 1*arrowFixed[1]
	
	-- calculate p forced crit
	local bitingMod = 0
	if(bitingLevel20=="Yes") then bitingMod = 1 end
	local pForcedCrit = .02*bitingRank*(1+.1*bitingMod)
	if(pocket=="Grimoire") then pForcedCrit = pForcedCrit + 0.12 end
	
	--calculate pNatCrit
	local pNatCrit = {0,0,0,0,0}
	for arrow = 1,5 do 
		pNatCrit[arrow] = math.floor(.05*(arrowFixed[arrow]+arrowVar[arrow]))/arrowVar[arrow]
	end
	
	--equilibrium (aura overrides perk)
	for arrow = 1,5 do 
		if(aura=="Equilibrium") then 
			arrowFixed[arrow] = arrowFixed[arrow] + math.floor(.25*arrowVar[arrow])
			arrowVar[arrow] = math.floor((1-.50)*arrowVar[arrow])
		else
			local eqRankEffective = equilibriumRank
			if(weaponSwitch=="Yes" and arrow>1) then eqRankEffective = eqSwitchRank end
			arrowFixed[arrow] = arrowFixed[arrow] + math.floor(.03*eqRankEffective*arrowVar[arrow])
			arrowVar[arrow] = math.floor((1-.04*eqRankEffective)*arrowVar[arrow])
		end
	end
	
	--calculate hits after vuln/swiftness/aura/ruthless/scrim
	local ruthlessMod = 0.005*ruthlessRank*ruthlessStacks
	local vulnMod = 0
	if(vuln=="Yes") then vulnMod = 0.1 end
	local swiftnessMod = 0
	if(swiftness=="Yes" or swiftness=="Yes \(cast on last few ticks\)") then swiftnessMod = 0.5 end
	local auraMod = 0
	if(aura=="Mahjarrat") then auraMod = 0.05
	elseif(aura=="Reckless" and (swiftness=="Yes \(cast on last few ticks\)" or swiftness=="No")) then auraMod = 0.1
	elseif(aura=="Reckless" and swiftness=="Yes") then auraMod = 0
	end
	local pocketMod = 0
	if(pocket=="Scrimshaw of cruelty") then pocketMod = 0.05
	elseif(pocket=="Superior scrimshaw of cruelty") then pocketMod = 0.0666
	end
	local needleMod = 0
	if(needle=="Yes") then needleMod = 0.07 end
	local berserkersFury = dhrelic/100
	local ripperDemonPassive = ripper/100
	local telosRedBeamMod = 0
	local telosBlackBeamMod = 0
	if(telosBeam=="Player is in black beam \(Phases 2 or 5\)") then telosBlackBeamMod=-0.30
	elseif(telosBeam=="Telos is in black beam \(Phase 2\)") then telosBlackBeamMod=-0.20
	elseif(telosBeam=="Player is in red beam \(Phase 3\)") then telosRedBeamMod=0.30
	elseif(telosBeam=="Player is in red beam; Telos is in black beam \(Phase 5\)") then telosRedBeamMod=0.30; telosBlackBeamMod=-0.20
	elseif(telosBeam=="Player is not in red beam; Telos is in black beam \(Phase 5\)") then telosBlackBeamMod=-0.20
	end
	local finalMod = (1+ruthlessMod) * (1+vulnMod) * (1+swiftnessMod) * (1+auraMod) * (1+pocketMod) * (1+needleMod) * (1+berserkersFury) * (1+ripperDemonPassive) * (1+telosRedBeamMod) * (1+telosBlackBeamMod)
	
	local natCritMin = {0,0,0,0,0}
	local forcedCritMin = {0,0,0,0,0}
	for arrow = 1,5 do 
		arrowFixed[arrow] = math.floor(arrowFixed[arrow] * finalMod)
		arrowVar[arrow] = math.floor(arrowVar[arrow] * finalMod)
		natCritMin[arrow] = math.floor(arrowFixed[arrow] + (1-pNatCrit[arrow])*arrowVar[arrow])
		forcedCritMin[arrow] = math.floor(arrowFixed[arrow]+0.95*arrowVar[arrow])
	end
	
	--damage caps
	local critCap = 12000
	if(pocket=="Grimoire") then critCap = 15000 end
	local nonCap = 10000
	
	--calculate probability of hits above caps
	local pForcedCritCap = {0,0,0,0,0}
	local pNaturalCritCap = {0,0,0,0,0}
	local pNonCritCap = {0,0,0,0,0}
	
	for arrow = 1,5 do 
		pForcedCritCap[arrow] = (critCap - forcedCritMin[arrow])/(arrowFixed[arrow]+arrowVar[arrow] - forcedCritMin[arrow])
		pNaturalCritCap[arrow] = (critCap - natCritMin[arrow])/(arrowFixed[arrow]+arrowVar[arrow] - natCritMin[arrow])
		pNonCritCap[arrow] = (nonCap - arrowFixed[arrow])/(natCritMin[arrow] - arrowFixed[arrow])
	end
	
	--calculate average damages
	local arrowAverage = {0,0,0,0,0}
	for arrow = 1,5 do
		arrowAverage[arrow] = pForcedCrit*(math.max(0,math.min(1-pForcedCritCap[arrow],1))*critCap + math.min(math.max(0,pForcedCritCap[arrow]),1)*(math.min(critCap,forcedCritMin[arrow]) + math.min(critCap,(arrowFixed[arrow]+arrowVar[arrow])))/2)
		arrowAverage[arrow] = arrowAverage[arrow] + (1-pForcedCrit)*(pNatCrit[arrow])*(math.max(0,math.min(1-pNaturalCritCap[arrow],1))*critCap + math.min(math.max(0,pNaturalCritCap[arrow]),1)*(math.min(natCritMin[arrow],critCap) + math.min(critCap,(arrowFixed[arrow]+arrowVar[arrow])))/2)
		arrowAverage[arrow] = arrowAverage[arrow] + (1-pForcedCrit)*(1-pNatCrit[arrow])*(math.max(0,math.min(1-pNonCritCap[arrow],1))*nonCap + math.min(math.max(0,pNonCritCap[arrow]),1)*(math.min(nonCap,arrowFixed[arrow]) + math.min(nonCap,natCritMin[arrow]))/2)
	end
	
	--calculate ecb spec damages
	local amountHealed = 0
	local avgIncreaseHealed = 0
	local damageFromSpec = 0
	function dmgSplitSoulOverRangeCalc(n)
		amountHealed = (math.floor(math.min(2000,n)*.1) + math.floor(math.max(0,math.min(2000,n-2000))*.05) + math.floor(math.max(0,n-4000)*.0125))
		avgIncreaseHealed = math.floor(amountHealed*.375)
		if(splitSoul==("Yes \(without Amulet of Souls\)") or splitSoul==("Yes \(stalling; without Amulet of Souls\)")) then damageFromSpec = damageFromSpec + math.floor( math.floor(amountHealed*4) * (1+vulnMod) )
		elseif(splitSoul==("Yes \(with Amulet of Souls\)") or splitSoul==("Yes \(stalling; with Amulet of Souls\)")) then damageFromSpec = damageFromSpec + math.floor( ((.5*math.floor(amountHealed*4) + .5*math.floor((amountHealed+avgIncreaseHealed)*4))) * (1+vulnMod) )
		end
	end
	function avgDmgSplitSoulCalc(min_hit,max_hit,fCritMin,fCritMax)
		local avgDmgSplitSoul = 0
		--non-forced crit
		damageFromSpec = 0
		for damage = min_hit,max_hit do dmgSplitSoulOverRangeCalc(damage) end
		avgDmgSplitSoul = avgDmgSplitSoul + ((1-pForcedCrit) * damageFromSpec / (max_hit-min_hit+1))
		--forced crit
		damageFromSpec = 0
		for damage = fCritMin,fCritMax do dmgSplitSoulOverRangeCalc(damage) end
		avgDmgSplitSoul = avgDmgSplitSoul + (pForcedCrit * damageFromSpec / (fCritMax-fCritMin+1))
		return avgDmgSplitSoul
	end
	
	--calculate ecb average damages
	local ecbAverage = {0,0,0,0,0}
	local minSoulSplitSplat = 2
	if(weaponSwitch=="Yes" and splitSoul~="No") then
		if(splitSoul==("Yes \(stalling; with Amulet of Souls\)") or splitSoul==("Yes \(stalling; without Amulet of Souls\)")) then minSoulSplitSplat = 1 end
		for arrow = minSoulSplitSplat,5 do
			arrowMin = arrowFixed[arrow]
			arrowMax = arrowFixed[arrow] + arrowVar[arrow]
			fCritMin = forcedCritMin[arrow]
			
			ecbAverage[arrow] = avgDmgSplitSoulCalc(arrowMin,arrowMax,fCritMin,arrowMax)
		end
	end
	
	--create arrow damage table
	local resultsDiv = mw.html.create( 'div' )
	local resultsTable = mw.html.create( 'table' )
	if(splitSoul=="No" or splitSoul=="") then
		resultsTable:addClass( 'wikitable' )
				:addClass( 'align-center-1 align-center-2 align-center-3 align-center-4 align-center-5' )
				:tag( 'caption' )
					:wikitext( 'Average damage for individual arrows as well as the combined average damage for the total number of arrows that land.' )				
					:css('text-align', 'left')
			:tag( 'tr' )
				:tag( 'th' )
					:wikitext( 'Arrow Damages' )
					:attr( 'colspan', 5 )
				:done()
			:done()
			:tag( 'tr' )
				:tag( 'th' )
					:wikitext( 'Arrow' )
					:attr( 'rowspan', 2 )
				:done()
				:tag( 'th' )
					:wikitext( 'Individual Arrow Damages' )
					:attr( 'colspan', 3 )
				:done()
				:tag( 'th' )
					:wikitext( 'Total Average Damage over n Arrows' )
					:attr( 'rowspan', 2 )
				:done()
			:done()
			:tag( 'tr' )
				:tag( 'th' )
					:wikitext( 'Minimum')
				:done()
				:tag( 'th' )
					:wikitext( 'Maximum')
				:done()
				:tag( 'th' )
					:wikitext( 'Average')
				:done()
			:done()
		:done()
		local sumAverage = 0
		for arrow = 1,5 do
			sumAverage = sumAverage + arrowAverage[arrow]
			resultsTable:tag( 'tr' )
				:tag( 'td' )
					:wikitext ( string.format("%d",arrow) )
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(arrowFixed[arrow]+0.5)) ))
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(arrowFixed[arrow]+arrowVar[arrow]+0.5)) ))
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(arrowAverage[arrow]+0.5)) ))
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(sumAverage+0.5)) ))
				:done()
			:done()
		end
	else
		resultsTable:addClass( 'wikitable' )
				:addClass( 'align-center-1 align-center-2 align-center-3 align-center-4 align-center-5 align-center-6 align-center-7 align-center-8 align-center-9' )
				:tag( 'caption' )
					:wikitext( 'Average damage for individual arrows as well as the combined average damage for the total number of arrows that land.' )				
			:tag( 'tr' )
				:tag( 'th' )
					:wikitext( 'Arrow Damages' )
					:attr( 'colspan', 9 )
				:done()
			:done()
			:tag( 'tr' )
				:tag( 'th' )
					:wikitext( 'Arrow' )
					:attr( 'rowspan', 2 )
				:done()
				:tag( 'th' )
					:wikitext( 'Individual Arrow Damages' )
					:attr( 'colspan', 5 )
				:done()
				:tag( 'th' )
					:wikitext( 'Total Average Damage over n Arrows' )
					:attr( 'colspan', 3 )
				:done()
			:done()
			:tag( 'tr' )
				:tag( 'th' )
					:wikitext( 'Minimum')
				:done()
				:tag( 'th' )
					:wikitext( 'Maximum')
				:done()
				:tag( 'th' )
					:wikitext( 'Average')
				:done()
				:tag( 'th' )
					:wikitext( 'Average from Split Soul')
				:done()
				:tag( 'th' )
					:wikitext( 'Average from Arrow + Split Soul')
				:done()
				:tag( 'th' )
					:wikitext( 'Average from n Arrows')
				:done()
				:tag( 'th' )
					:wikitext( 'Average from Split Soul over n Arrows')
				:done()
				:tag( 'th' )
					:wikitext( 'Average from n Arrows + Split Soul')
				:done()
			:done()
		:done()
		local sumAverage = 0
		local ecbSumAverage = 0
		for arrow = 1,5 do
			sumAverage = sumAverage + arrowAverage[arrow]
			ecbSumAverage = ecbSumAverage + ecbAverage[arrow]
			resultsTable:tag( 'tr' )
				:tag( 'td' )
					:wikitext ( string.format("%d",arrow) )
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(arrowFixed[arrow]+0.5)) ))
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(arrowFixed[arrow]+arrowVar[arrow]+0.5)) ))
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(arrowAverage[arrow]+0.5)) ))
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(ecbAverage[arrow]+0.5)) ))
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(arrowAverage[arrow]+ecbAverage[arrow])) ))
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(sumAverage+0.5)) ))
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(ecbSumAverage+0.5)) ))
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(sumAverage+ecbSumAverage+0.5)) ))
				:done()
			:done()
		end
	end
	
	--create arrays based on NPC size
	local pArrow1NoBlock = {0.840,0.473,0.144,0.141,0.045,0.083,0.026,0.057,0.017,0.043,0.013}
	local pArrow2NoBlock = {0.160,0.420,0.398,0.327,0.193,0.222,0.124,0.168,0.091,0.135,0.071}
	local pArrow3NoBlock = {0.000,0.100,0.342,0.324,0.324,0.281,0.250,0.240,0.203,0.208,0.171}
	local pArrow4NoBlock = {0.000,0.007,0.106,0.170,0.282,0.231,0.277,0.227,0.247,0.210,0.219}
	local pArrow5NoBlock = {0.000,0.000,0.010,0.038,0.155,0.182,0.323,0.308,0.441,0.404,0.526}
	
	local pArrow1Block = {0.840,0.473,0.144,0.010,0.000}
	local pArrow2Block = {0.160,0.420,0.398,0.106,0.000}
	local pArrow3Block = {0.000,0.100,0.342,0.342,0.000}
	local pArrow4Block = {0.000,0.007,0.106,0.398,0.000}
	local pArrow5Block = {0.000,0.000,0.010,0.144,1.000}

	local npcSizeDiv = mw.html.create( 'div' )
	local npcSizeTable = mw.html.create( 'table' )
	if(splitSoul=="No" or splitSoul=="") then
		npcSizeTable:addClass( 'wikitable' )
				:addClass( 'align-center-1 align-center-2 align-center-3' )
				:tag( 'caption' )
					:wikitext( 'Average damage based on the NPC size. In general, damage increases with the NPC size.' )
					:css('text-align', 'left')
			:tag( 'tr' )
				:tag( 'th' )
					:wikitext( 'Damage based on size of Target' )
					:attr( 'colspan', 3 )
				:done()
			:done()
			:tag( 'tr' )
				:tag( 'th' )
					:wikitext( 'NPC Size' )
				:done()
				:tag( 'th' )
					:wikitext( 'Expected number of Arrows' )
				:done()
				:tag( 'th' )
					:wikitext( 'Average Damage')
				:done()
			:done()
		:done()
		if(npc=="No \(Non-blocking\)") then
			for size = 1,11 do
				local sizeArrowAvg = pArrow1NoBlock[size]*arrowAverage[1]+pArrow2NoBlock[size]*(arrowAverage[1]+arrowAverage[2])+pArrow3NoBlock[size]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3])+pArrow4NoBlock[size]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3]+arrowAverage[4])+pArrow5NoBlock[size]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3]+arrowAverage[4]+arrowAverage[5])
				local nArrows = pArrow1NoBlock[size]*1+pArrow2NoBlock[size]*2+pArrow3NoBlock[size]*3+pArrow4NoBlock[size]*4+pArrow5NoBlock[size]*5
				npcSizeTable:tag( 'tr' )
					:tag( 'td' )
						:wikitext ( string.format("%dx%d",size,size) )
					:done()
					:tag( 'td' )
						:wikitext ( string.format("%.2f",nArrows) )
					:done()
					:tag( 'td' )
						:wikitext ( string.format("%s",lang:formatNum(math.floor(sizeArrowAvg+0.5)) ))
					:done()
				:done()
			end
		elseif(npc=="Yes \(Blocking\)") then
			for size = 1,4 do
				local sizeArrowAvg = pArrow1Block[size]*arrowAverage[1]+pArrow2Block[size]*(arrowAverage[1]+arrowAverage[2])+pArrow3Block[size]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3])+pArrow4Block[size]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3]+arrowAverage[4])+pArrow5Block[size]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3]+arrowAverage[4]+arrowAverage[5])
				local nArrows = pArrow1Block[size]*1+pArrow2Block[size]*2+pArrow3Block[size]*3+pArrow4Block[size]*4+pArrow5Block[size]*5
				npcSizeTable:tag( 'tr' )
					:tag( 'td' )
						:wikitext ( string.format("%dx%d",size,size) )
					:done()
					:tag( 'td' )
						:wikitext ( string.format("%.2f",nArrows) )
					:done()
					:tag( 'td' )
						:wikitext ( string.format("%s",lang:formatNum(math.floor(sizeArrowAvg+0.5)) ))
					:done()
				:done()
			end
			local sizeArrowAvg = pArrow1Block[5]*arrowAverage[1]+pArrow2Block[5]*(arrowAverage[1]+arrowAverage[2])+pArrow3Block[5]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3])+pArrow4Block[5]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3]+arrowAverage[4])+pArrow5Block[5]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3]+arrowAverage[4]+arrowAverage[5])
			local nArrows = pArrow1Block[5]*1+pArrow2Block[5]*2+pArrow3Block[5]*3+pArrow4Block[5]*4+pArrow5Block[5]*5
			npcSizeTable:tag( 'tr' )
				:tag( 'td' )
					:wikitext ( "5x5+" )
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%.2f",nArrows) )
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(sizeArrowAvg+0.5)) ))
				:done()
			:done()
		end
	else
		npcSizeTable:addClass( 'wikitable' )
				:addClass( 'align-center-1 align-center-2 align-center-3 align-center-4 align-center-5' )
				:tag( 'caption' )
					:wikitext( 'Average damage based on the NPC size. In general, damage increases with the NPC size.' )
			:tag( 'tr' )
				:tag( 'th' )
					:wikitext( 'Expected Damage based on size of Target' )
					:attr( 'colspan', 5 )
				:done()
			:done()
			:tag( 'tr' )
				:tag( 'th' )
					:wikitext( 'NPC Size' )
				:done()
				:tag( 'th' )
					:wikitext( 'Expected number of Arrows' )
				:done()
				:tag( 'th' )
					:wikitext( 'Average')
				:done()
				:tag( 'th' )
					:wikitext( 'Average from Split Soul')
				:done()
				:tag( 'th' )
					:wikitext( 'Total Average')
				:done()
			:done()
		:done()
		if(npc=="No \(Non-blocking\)") then
			for size = 1,11 do
				local sizeArrowAvg = pArrow1NoBlock[size]*arrowAverage[1]+pArrow2NoBlock[size]*(arrowAverage[1]+arrowAverage[2])+pArrow3NoBlock[size]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3])+pArrow4NoBlock[size]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3]+arrowAverage[4])+pArrow5NoBlock[size]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3]+arrowAverage[4]+arrowAverage[5])
				local ecbSizeArrowAvg = pArrow1NoBlock[size]*ecbAverage[1]+pArrow2NoBlock[size]*(ecbAverage[1]+ecbAverage[2])+pArrow3NoBlock[size]*(ecbAverage[1]+ecbAverage[2]+ecbAverage[3])+pArrow4NoBlock[size]*(ecbAverage[1]+ecbAverage[2]+ecbAverage[3]+ecbAverage[4])+pArrow5NoBlock[size]*(ecbAverage[1]+ecbAverage[2]+ecbAverage[3]+ecbAverage[4]+ecbAverage[5])
				local nArrows = pArrow1NoBlock[size]*1+pArrow2NoBlock[size]*2+pArrow3NoBlock[size]*3+pArrow4NoBlock[size]*4+pArrow5NoBlock[size]*5
				npcSizeTable:tag( 'tr' )
					:tag( 'td' )
						:wikitext ( string.format("%dx%d",size,size) )
					:done()
					:tag( 'td' )
						:wikitext ( string.format("%.2f",nArrows) )
					:done()
					:tag( 'td' )
						:wikitext ( string.format("%s",lang:formatNum(math.floor(sizeArrowAvg+0.5)) ))
					:done()
					:tag( 'td' )
						:wikitext ( string.format("%s",lang:formatNum(math.floor(ecbSizeArrowAvg+0.5)) ))
					:done()
					:tag( 'td' )
						:wikitext ( string.format("%s",lang:formatNum(math.floor(sizeArrowAvg+ecbSizeArrowAvg+0.5)) ))
					:done()
				:done()
			end
		elseif(npc=="Yes \(Blocking\)") then
			for size = 1,4 do
				local sizeArrowAvg = pArrow1Block[size]*arrowAverage[1]+pArrow2Block[size]*(arrowAverage[1]+arrowAverage[2])+pArrow3Block[size]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3])+pArrow4Block[size]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3]+arrowAverage[4])+pArrow5Block[size]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3]+arrowAverage[4]+arrowAverage[5])
				local ecbSizeArrowAvg = pArrow1Block[size]*ecbAverage[1]+pArrow2Block[size]*(ecbAverage[1]+ecbAverage[2])+pArrow3Block[size]*(ecbAverage[1]+ecbAverage[2]+ecbAverage[3])+pArrow4Block[size]*(ecbAverage[1]+ecbAverage[2]+ecbAverage[3]+ecbAverage[4])+pArrow5Block[size]*(ecbAverage[1]+ecbAverage[2]+ecbAverage[3]+ecbAverage[4]+ecbAverage[5])
				local nArrows = pArrow1NoBlock[size]*1+pArrow2NoBlock[size]*2+pArrow3NoBlock[size]*3+pArrow4NoBlock[size]*4+pArrow5NoBlock[size]*5
				npcSizeTable:tag( 'tr' )
					:tag( 'td' )
						:wikitext ( string.format("%dx%d",size,size) )
					:done()
					:tag( 'td' )
						:wikitext ( string.format("%.2f",nArrows) )
					:done()
					:tag( 'td' )
						:wikitext ( string.format("%s",lang:formatNum(math.floor(sizeArrowAvg+0.5)) ))
					:done()
					:tag( 'td' )
						:wikitext ( string.format("%s",lang:formatNum(math.floor(ecbSizeArrowAvg+0.5)) ))
					:done()
					:tag( 'td' )
						:wikitext ( string.format("%s",lang:formatNum(math.floor(sizeArrowAvg+ecbSizeArrowAvg+0.5)) ))
					:done()
				:done()
			end
			local sizeArrowAvg = pArrow1Block[5]*arrowAverage[1]+pArrow2Block[5]*(arrowAverage[1]+arrowAverage[2])+pArrow3Block[5]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3])+pArrow4Block[5]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3]+arrowAverage[4])+pArrow5Block[5]*(arrowAverage[1]+arrowAverage[2]+arrowAverage[3]+arrowAverage[4]+arrowAverage[5])
			local ecbSizeArrowAvg = pArrow1Block[5]*ecbAverage[1]+pArrow2Block[5]*(ecbAverage[1]+ecbAverage[2])+pArrow3Block[5]*(ecbAverage[1]+ecbAverage[2]+ecbAverage[3])+pArrow4Block[5]*(ecbAverage[1]+ecbAverage[2]+ecbAverage[3]+ecbAverage[4])+pArrow5Block[5]*(ecbAverage[1]+ecbAverage[2]+ecbAverage[3]+ecbAverage[4]+ecbAverage[5])
			local nArrows = pArrow1Block[5]*1+pArrow2Block[5]*2+pArrow3Block[5]*3+pArrow4Block[5]*4+pArrow5Block[5]*5
			npcSizeTable:tag( 'tr' )
				:tag( 'td' )
					:wikitext ( "5x5+" )
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%.2f",nArrows) )
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(sizeArrowAvg+0.5)) ))
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(ecbSizeArrowAvg+0.5)) ))
				:done()
				:tag( 'td' )
					:wikitext ( string.format("%s",lang:formatNum(math.floor(sizeArrowAvg+ecbSizeArrowAvg+0.5)) ))
				:done()
			:done()
		end
	end

	
	--return results (table)
	resultsDiv:node(tostring(resultsTable))
	npcSizeDiv:node(tostring(npcSizeTable))
	return resultsDiv, npcSizeTable
end

return p
-- </nowiki>