Module:Split Soul calculator

Documentation for this module may be created at Module:Split Soul calculator/doc

-- <pre>
local p = {}

local htmlext = require('Module:Mw.html extension')
local yesno = require ("Module:Yesno")
local lang = mw.getContentLanguage()


function p.main(frame)
	
	local args = frame:getParent().args
	local combatMode = args.combatMode --Full Manual/Revolution, Legacy
	local damage = tonumber(args.damage) or 0
	local damageCap = tonumber(args.damageCap) or 0 --damage caps of 10k, 12k, 13.44k, 15k, 16.8k, 30k to base hit
	local target = args.target --Primary, Secondary
    local souls = yesno(args.souls) or false
    
    local vuln = yesno(args.vuln) or false
    local slayerPerk = yesno(args.slayerPerk) or false
    local slayerAbility = yesno(args.slayerAbility) or false
    local spider = args.spider --0%, 2%, 3%
    local croesusDeathspores = yesno(args.croesusDeathspores) or false
    
    local addinfo = yesno(args.addinfo) or false
	return calculateDamage(combatMode,damage,damageCap,target,souls,vuln,slayerPerk,slayerAbility,spider,croesusDeathspores,addinfo)
	
end

function calculateDamage(combatMode,damage,damageCap,target,souls,vuln,slayerPerk,slayerAbility,spider,croesusDeathspores,addinfo)

	local amountHealed = 0
	local damageFromSpecSoulsAvg = 0
	local damageFromSpecSoulsMin = 0
	local damageFromSpecSoulsMax = 0
	
	--values without direct split soul damage modifiers
	local vulnMod = 1; if(vuln) then vulnMod = 1.1 end
	local slayerPerkMod = 1; if(slayerPerk) then slayerPerkMod = 1.07 end
	local slayerAbilityMod = 1; if(slayerAbility) then slayerAbilityMod = 1.15 end
	local spiderMod = 1; if (spider=="2%") then spiderMod = 1.02 elseif (spider=="3%") then spiderMod = 1.03 end 
	local croesusDeathsporesMod = 1; if(croesusDeathspores) then croesusDeathsporesMod = 1.1 end
	
	local noVulnDamage = math.max(1, math.ceil(damage/(vulnMod*slayerPerkMod*slayerAbilityMod*spiderMod*croesusDeathsporesMod)) )
	local noVulnAmountHealed = 0 
	local noVulnDamageFromSpecSoulsAvg = 0
	local noVulnDamageFromSpecSoulsMin = 0
	local noVulnDamageFromSpecSoulsMax = 0	
	
	--soul split heals
	if(combatMode=="Full Manual/Revolution") then
		if target=="Primary" then
			amountHealed = math.floor(math.min(2000,damage)*.1) + math.floor(math.max(0,math.min(2000,damage-2000))*.05) + math.floor(math.max(0,damage-4000)*.0125)
			noVulnAmountHealed = math.floor(math.min(2000,noVulnDamage)*.1) + math.floor(math.max(0,math.min(2000,noVulnDamage-2000))*.05) + math.floor(math.max(0,noVulnDamage-4000)*.0125)
		elseif target=="Secondary" then
			amountHealed = math.floor(math.min(2000,damage)*.1*.5) + math.floor(math.max(0,math.min(2000,damage-2000))*.05*.5) + math.floor(math.max(0,damage-4000)*.0125*.5)
			noVulnAmountHealed = math.floor(math.min(2000,noVulnDamage)*.1*.5) + math.floor(math.max(0,math.min(2000,noVulnDamage-2000))*.05*.5) + math.floor(math.max(0,noVulnDamage-4000)*.0125*.5)
		end
	elseif(combatMode=="Legacy") then
		if target=="Primary" then
			amountHealed = math.floor(damage*.1)
			noVulnAmountHealed = math.floor(noVulnDamage*.1)
		elseif target=="Secondary" then
			amountHealed = math.floor(damage*.1*.5)
			noVulnAmountHealed = math.floor(noVulnDamage*.1*.5)
		end
	end
	
	local avgIncreaseHealed = math.floor(amountHealed*.375)
	local maxIncreaseHealed = math.floor(amountHealed*.5)
	local noVulnAvgIncreaseHealed = math.floor(noVulnAmountHealed*.375)
	local noVulnMaxIncreaseHealed = math.floor(noVulnAmountHealed*.5)
	
	
	--split soul damage
	--avg with amulet of souls
	damageFromSpecSoulsAvg = math.min(10000,math.floor(math.floor(math.floor(math.floor(math.floor( (.5*math.floor(amountHealed*4) + .5*math.floor((amountHealed+avgIncreaseHealed)*4)) * vulnMod) * slayerPerkMod) * slayerAbilityMod) * spiderMod) * croesusDeathsporesMod))
	noVulnDamageFromSpecSoulsAvg = math.min(10000,.5*math.floor(noVulnAmountHealed*4) + .5*math.floor((noVulnAmountHealed+noVulnAvgIncreaseHealed)*4))
	--min with amulet of souls or no amulet of souls
	damageFromSpecSoulsMin = math.min(10000,math.floor(math.floor(math.floor(math.floor(math.floor( math.floor(amountHealed*4) * vulnMod) * slayerPerkMod) * slayerAbilityMod) * spiderMod) * croesusDeathsporesMod))
	noVulnDamageFromSpecSoulsMin = math.min(10000,math.floor(noVulnAmountHealed*4))
	--max with amulet of souls
	damageFromSpecSoulsMax = math.min(10000,math.floor(math.floor(math.floor(math.floor(math.floor( math.floor((amountHealed+maxIncreaseHealed)*4) * vulnMod) * slayerPerkMod) * slayerAbilityMod) * spiderMod) * croesusDeathsporesMod))
	noVulnDamageFromSpecSoulsMax = math.min(10000,math.floor((noVulnAmountHealed+noVulnMaxIncreaseHealed)*4))
	
	--apply damage caps to base hit AFTER split soul calculations
	local damageCapValue = damageCap
	local damageOriginal = damage
	if(damageCapValue~=0) then	
		damage = math.min(damageCapValue,damage)
		noVulnDamage = math.min(damageCapValue,noVulnDamage) 
	end

	--table for output
	local size = 25
	local check = {
    	[true] = 'Yes check',
    	[false] = 'X mark'
	}
	local resultsDiv = mw.html.create( 'div' )
	local resultsTable = mw.html.create( 'table' )
	
	resultsTable:addClass( 'wikitable' )
	:IF(addinfo)
		:addClass( 'align-center-1 align-center-2 align-center-3 align-center-4 align-center-5 align-center-6' )
	:ELSE()
		:addClass( 'align-center-1 align-center-2 align-center-3 align-center-4 align-center-5' )
	:END()
	--[[
	:tag( 'caption' )
		:IF(addinfo)
			:wikitext( 'Damage from Split Soul. The Increase from Split Soul damage modifiers column describes the base damage hitsplat and Split Soul damage increase with Split Soul damage modifiers to without Split Soul damage modifiers.' )
			:css('text-align', 'left')
		:ELSE()
			:wikitext( 'Damage from Split Soul.' )
			:css('text-align', 'center')
		:END()
	]]--
	:tag( 'tr' )
		:tag( 'th' )
			:wikitext( 'Damage from Split Soul (' .. target .. ' target)' .. '<br/>Combat Mode: ' .. combatMode .. '<br/>')
			:wikitext(' Base Hitsplat damage: ' .. string.format("%s",lang:formatNum(damageOriginal)) .. '<br/>')
			:IF(damageCap=="None")
				:wikitext( 'Base Hitsplat damage cap: None<br/>' )
			:ELSE()
				:wikitext( 'Base Hitsplat damage cap: ' .. string.format("%s",lang:formatNum(damageCapValue)) .. '<br/>')
			:END()
			:wikitext( 'Active Split Soul damage modifiers: ')
				:IF(vuln)
					:wikitext(string.format("[[File:Vulnerability icon.png|link=Vulnerability|x%dpx]]",size))
				:END()
				:IF(slayerPerk)
					:wikitext(string.format("[[File:Demon_Slayer_(perk).png|link=Demon_Slayer_(perk)|x%dpx]][[File:Dragon_Slayer_(perk).png|link=Dragon_Slayer_(perk)|x%dpx]][[File:Undead_Slayer.png|link=Undead_Slayer|x%dpx]]",size,size,size))
				:END()
				:IF(slayerAbility)
					:wikitext(string.format("[[File:Demon_Slayer_(ability).png|link=Demon_Slayer_(ability)|x%dpx]][[File:Dragon_Slayer_(ability).png|link=Dragon_Slayer_(ability)|x%dpx]][[File:Undead_Slayer_(ability).png|link=Undead_Slayer_(ability)|x%dpx]]",size,size,size))
				:END()
				:IF(spider~="0%")
					:wikitext(string.format("[[File:NopeNopeNope_status_icon.png|link=Player-owned_farm#Perks|x%dpx]]",size) .. spider)
				:END()
				:IF(croesusDeathspores)
					:wikitext(string.format("[[File:Cryptbloom helm.png|link=Cryptbloom armour#Set effect|x%dpx]]",size))
				:END()
				:IF(vuln==false and slayerPerk==false and slayerAbility==false and spider=="0%" and croesusDeathspores==false)
					:wikitext( 'None' )
				:END()
			:IF(addinfo)
				:attr( 'colspan', 6 )
			:ELSE()
				:attr( 'colspan', 5 )
			:END()
		:done()
	:done()
	:tag( 'tr' )
		:tag( 'th' )
			:wikitext( string.format("[[File:Amulet_of_souls_(or).png|link=]]") .. string.format('[[File:%s.svg|20px|link=]]', check[yesno(souls)]) )
		:done()
		:tag( 'th' )
			:wikitext( 'Base Hitsplat<br/>' .. string.format("[[File:Ranged hitsplat.png|link=|x%dpx]]",size) )
		:done()
		:tag( 'th' )
			:wikitext( 'Split Soul damage<br/>' .. string.format("[[File:Split Soul hitsplat.png|link=|x%dpx]]",size) )
		:done()
		:tag( 'th' )
			:wikitext( 'Total damage<br/>' .. string.format("[[File:Ranged hitsplat.png|link=|x%dpx]]",size) .. "+" .. string.format("[[File:Split Soul hitsplat.png|link=|x%dpx]]",size) )
		:done()
		:tag( 'th' )
			:wikitext( 'Damage Increase<br/>(%)' )
		:done()
		:IF(addinfo)
			:tag( 'th' )
				:wikitext( 'Increase from Split Soul<br/>damage modifiers' )
			:done()
		:END()
	:done()
	:IF(souls)
		:tag( 'tr' )
			:tag( 'td' )
				:wikitext( '<b>Average</b>' )
			:done()
			:tag( 'td' )
				:wikitext( string.format("<b>%s</b>",lang:formatNum(damage)) )
			:done()
			:tag( 'td' )
				:wikitext( string.format("<b>%s</b>",lang:formatNum(damageFromSpecSoulsAvg)) )
			:done()
			:tag( 'td' )
				:wikitext( string.format("<b>%s</b>",lang:formatNum(damage+damageFromSpecSoulsAvg)) )
			:done()
			:tag( 'td' )
				:wikitext( string.format("<b>%.2f</b>",lang:formatNum(damageFromSpecSoulsAvg/damage*100)) .. "<b>%</b>" )
			:done()
			:IF(addinfo)
				:tag( 'td' )
					:wikitext( string.format("<b>%.2f</b>", lang:formatNum(((damage+damageFromSpecSoulsAvg)/(noVulnDamage+noVulnDamageFromSpecSoulsAvg)-1)*100)) .. "<b>%</b>" )
				:done()
			:END()
		:done()
	:END()
	:tag( 'tr' )
		:tag( 'td' )
			:IF(souls)
				:wikitext( 'Minimum' )
			:ELSE()
				:wikitext( 'Damage' )
			:END()
		:done()
		:tag( 'td' )
			:wikitext( string.format("%s",lang:formatNum(damage)) )
		:done()
		:tag( 'td' )
			:wikitext( string.format("%s",lang:formatNum(damageFromSpecSoulsMin)) )
		:done()
		:tag( 'td' )
			:wikitext( string.format("%s",lang:formatNum(damage+damageFromSpecSoulsMin)) )
		:done()
		:tag( 'td' )
			:wikitext( string.format("%.2f",lang:formatNum(damageFromSpecSoulsMin/damage*100)) .. "%" )
		:done()
		:IF(addinfo)
			:tag( 'td' )
				:wikitext( string.format("%.2f", lang:formatNum(((damage+damageFromSpecSoulsMin)/(noVulnDamage+noVulnDamageFromSpecSoulsMin)-1)*100)) .."%" )
			:done()
		:END()		
	:done()
	:IF(souls)
		:tag( 'tr' )
			:tag( 'td' )
				:wikitext( 'Maximum' )
			:done()
			:tag( 'td' )
				:wikitext( string.format("%s",lang:formatNum(damage)) )
			:done()
			:tag( 'td' )
				:wikitext( string.format("%s",lang:formatNum(damageFromSpecSoulsMax)) )
			:done()
			:tag( 'td' )
				:wikitext( string.format("%s",lang:formatNum(damage+damageFromSpecSoulsMax)) )
			:done()
			:tag( 'td' )
				:wikitext( string.format("%.2f",lang:formatNum(damageFromSpecSoulsMax/damage*100)) .. "%" )
			:done()
			:IF(addinfo)
				:tag( 'td' )
					:wikitext( string.format("%.2f", lang:formatNum(((damage+damageFromSpecSoulsMax)/(noVulnDamage+noVulnDamageFromSpecSoulsMax)-1)*100)) .."%" )
				:done()
			:END()			
		:done()
	:END()
	:done()

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

return p