Module:Average damage calculator
Documentation for this module may be created at Module:Average damage calculator/doc
-- <pre>
local p = {}
local yesno = require ("Module:Yesno")
function p.main(frame)
local args = frame:getParent().args
--___________________________________
-- Set initial values to be used
--___________________________________
local dType = args.dmgType
local tuskaW = args.tuska
local min_hit = tonumber(args.minHit) or 0
local max_hit = tonumber(args.maxHit) or 0
local eqPerkRank = tonumber(args.eqRank) or 9
local eqActiveAura = args.eqAura
local bitingPerkRank = tonumber(args.bitingRank) or 0
local gearLevel20 = args.level20
local eGrimoire = args.grimoire
local corbiculatotem = args.corbicula
local kalgScroll = args.kalg
local min_MFury = tonumber(args.minMFury) or 0
local max_MFury = tonumber(args.maxMFury) or 0
local splitSoul = args.splitSoul
local vuln = args.vuln
local debugMode = args.debugToggle
local atLeastX = tonumber(args.atLeastX) or 0
local dmgCap = 10000
local critCap = 12000
local res = ""
--___________________________________
-- Error messages
--___________________________________
if (min_hit > max_hit) then
return "The minimum hit must not be higher than the maximum hit."
end
if (min_MFury > max_MFury) then
return "The minimum hit set for Greater Fury must not be higher than the maximum hit set for Greater Fury."
end
--___________________________________
-- Define modifiers to critical hits
-- and critical hit chance
--___________________________________
local pBiting = .02*bitingPerkRank
local pGrimoire = 0
local pFuryAndConc1 = .05
local pFuryAndConc2 = .10
local pFuryAndConc3 = .15
local pMFury = .10
local pMFuryGuarantee = 1
local pCorbicula = 0 -- only affects the Meteor Strike ultimate ability
local pKalgScroll = 0
if (gearLevel20 == "Yes") then pBiting = pBiting*1.1 end
if (eGrimoire == "Yes") then
critCap = 15000
pGrimoire = .12
end
if (corbiculatotem == "1") then pCorbicula = .20
elseif (corbiculatotem == "2") then pCorbicula = .40
end
if (kalgScroll == "Yes") then pKalgScroll = .05 end
if (dType == "Yes") then pMFuryGuarantee = .10 end --The guarantee from MFury will not be used an auto
if (dType == "No" and tuskaW == "Yes") then -- Tuska's Wrath always has a damage/crit cap of 15k
dmgCap = 15000;
critCap = 15000;
end
--___________________________________
-- Calculate forced crit hit chance,
-- forced crit min, and forced crit max
--___________________________________
local pForcedCrit = math.min(1,pBiting+pGrimoire+pCorbicula+pKalgScroll)
local forcedCritMin = min_hit + math.floor(.95*(max_hit - min_hit))
local forcedCritMax = min_hit + math.floor(math.floor(.95*(max_hit - min_hit))/.95)
--___________________________________
-- Calculate natural crit hit chance
-- and natural crit min
--___________________________________
local preEqMin = 0
local preEqRand = 0
local naturalCritMin = 0
--local naturalCritMin = math.max(.95*max_hit,min_hit)
if (eqActiveAura=="Yes") then
preEqMin = min_hit - (max_hit - min_hit)/(1-(.25+.25))*.25
preEqRand = (max_hit-min_hit)/(1-(.25+.25))
else
preEqMin = min_hit - (max_hit - min_hit)/(1-eqPerkRank*(.03+.01))*(eqPerkRank*.03)
preEqRand = (max_hit-min_hit)/(1-eqPerkRank*(.03+.01))
end
local oneMinuspNaturalCrit = 0
local pNaturalCrit = 0
if (min_hit==max_hit) then
pNaturalCrit = 1
naturalCritMin = min_hit+oneMinuspNaturalCrit*(max_hit-min_hit)
else
oneMinuspNaturalCrit = ((preEqMin+preEqRand)*.95-preEqMin)/preEqRand
naturalCritMin = math.max(min_hit+oneMinuspNaturalCrit*(max_hit-min_hit),min_hit)
pNaturalCrit = math.min(1,1-oneMinuspNaturalCrit)
end
--___________________________________
-- Define how much of the damage will
-- be set to the damage and crit caps
--___________________________________
local z1 = 0
local z2 = 0
local y = 0
if (forcedCritMax == forcedCritMin) and (forcedCritMax >= critCap) then z1 = -999
elseif (forcedCritMax == forcedCritMin) and (forcedCritMax < critCap) then z1 = 999
else z1 = (critCap - forcedCritMin)/(forcedCritMax - forcedCritMin)
end
if (max_hit == naturalCritMin) and (max_hit >= critCap) then z2 = -999
elseif (max_hit == naturalCritMin) and (max_hit <= critCap) then z2 = 999
else z2 = (critCap - naturalCritMin)/(max_hit - naturalCritMin)
end
if (min_hit == naturalCritMin) and (min_hit >= dmgCap) then y = -999
elseif (min_hit == naturalCritMin) and (min_hit < dmgCap) then y = 999
else y = (dmgCap - min_hit)/(naturalCritMin - min_hit)
end
--___________________________________
-- Define chance for MFury to crit
--___________________________________
local pCritMFury = -999
if (dType=="No") then
local preEqMinMFury = 0
local preEqRandMFury = 0
local naturalCritMinMFury = 0
if (eqActiveAura=="Yes") then
preEqMinMFury = min_MFury - (max_MFury - min_MFury)/(1-(.25+.25))*.25
preEqRandMFury = (max_MFury-min_MFury)/(1-(.25+.25))
else
preEqMinMFury = min_MFury - (max_MFury - min_MFury)/(1-eqPerkRank*(.03+.01))*(eqPerkRank*.03)
preEqRandMFury = (max_MFury-min_MFury)/(1-eqPerkRank*(.03+.01))
end
local oneMinuspNaturalCritMFury = 0
local pNaturalCritMFury = 0
if (min_MFury==max_MFury) then
pNaturalCritMFury = 1
naturalCritMinMFury = min_MFury+oneMinuspNaturalCritMFury*(max_MFury-min_MFury)
else
oneMinuspNaturalCritMFury = ((preEqMinMFury+preEqRandMFury)*.95-preEqMinMFury)/preEqRandMFury
naturalCritMinMFury = min_MFury+oneMinuspNaturalCritMFury*(max_MFury-min_MFury)
pNaturalCritMFury = math.min(1,1-oneMinuspNaturalCritMFury)
end
pCritMFury = math.min(1,pForcedCrit+(1-pForcedCrit)*pNaturalCritMFury)
end
--___________________________________
-- Calculate average damage
--___________________________________
local avgDmg = 0
local avgDmgCrit = 0
local avgDmgNonCrit = 0
function avgDmgCalc()
avgDmg = pForcedCrit*(math.max(0,math.min(1-z1,1))*critCap + math.min(math.max(0,z1),1)*(math.min(critCap,forcedCritMin) + math.min(critCap,forcedCritMax))/2)
avgDmg = avgDmg + (1-pForcedCrit)*(pNaturalCrit)*(math.max(0,math.min(1-z2,1))*critCap + math.min(math.max(0,z2),1)*(math.min(naturalCritMin,critCap) + math.min(critCap,max_hit))/2)
avgDmg = avgDmg + (1-pForcedCrit)*(1-pNaturalCrit)*(math.max(0,math.min(1-y,1))*dmgCap + math.min(math.max(0,y),1)*(math.min(dmgCap,min_hit) + math.min(dmgCap,naturalCritMin))/2)
end
function avgDmgCritCalc()
local totalChanceToCrit = math.min(1,pForcedCrit+(1-pForcedCrit)*(pNaturalCrit))
avgDmgCrit = pForcedCrit/totalChanceToCrit*(math.max(0,math.min(1-z1,1))*critCap + math.min(math.max(0,z1),1)*(math.min(critCap,forcedCritMin) + math.min(critCap,forcedCritMax))/2)
avgDmgCrit = avgDmgCrit + (1-pForcedCrit)*(pNaturalCrit)/totalChanceToCrit*(math.max(0,math.min(1-z2,1))*critCap + math.min(math.max(0,z2),1)*(math.min(naturalCritMin,critCap) + math.min(critCap,max_hit))/2)
end
function avgDmgNonCritCalc()
avgDmgNonCrit = (math.max(0,math.min(1-y,1))*dmgCap + math.min(math.max(0,y),1)*(math.min(dmgCap,min_hit) + math.min(dmgCap,naturalCritMin))/2)
end
--___________________________________
-- Calculate average damage from Splt Soul
--___________________________________
local avgDmgSplitSoul = 0
local amountHealed = 0
local avgIncreaseHealed = 0
local damageFromSpec = 0
local vulnMod = 0
if(vuln=="Yes") then vulnMod = 0.1 end
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\)") then damageFromSpec = damageFromSpec + math.floor( math.floor(amountHealed*4) * (1+vulnMod) )
elseif(splitSoul=="Yes \(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()
--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 = forcedCritMin,forcedCritMax do dmgSplitSoulOverRangeCalc(damage) end
avgDmgSplitSoul = avgDmgSplitSoul + (pForcedCrit * damageFromSpec / (forcedCritMax-forcedCritMin+1))
end
--___________________________________
-- Calculate probability of hitting at least X
--___________________________________
local probX = 0
function probDamageAtLeastX(rangeMin,rangeMax)
if(rangeMin==rangeMax) then
if (rangeMin>atLeastX) then
probX = 1
else
probbX = 0
end
else
probX = math.max(0,math.min(1, (rangeMax-atLeastX)/(rangeMax-rangeMin) ))
end
return probX
end
avgDmgCalc()
avgDmgCritCalc()
avgDmgNonCritCalc()
if(splitSoul=="Yes \(with Amulet of Souls\)" or splitSoul=="Yes \(without Amulet of Souls\)") then avgDmgSplitSoulCalc() end
local resDEBUG = ""
--___________________________________
-- Debug mode
--___________________________________
if debugMode == "Yes" then
resDEBUG = resDEBUG .. "___________________________________" .. "<br/>"
resDEBUG = resDEBUG .. "DEBUG MODE" .. "<br/>"
resDEBUG = resDEBUG .. "___________________________________" .. "<br/>"
--res = res .. (math.max(0,math.min(1-z1,1))*critCap + math.min(math.max(0,z1),1)*(math.min(critCap,forcedCritMin) + math.min(critCap,max_hit))/2) .. "<br/>"
--res = res .. (math.max(0,math.min(1-z2,1))*critCap + math.min(math.max(0,z2),1)*(math.min(naturalCritMin,critCap) + math.min(critCap,max_hit))/2) .. "<br/>"
--res = res .. (math.max(0,math.min(1-y,1))*dmgCap + math.min(math.max(0,y),1)*(math.min(dmgCap,min_hit) + math.min(dmgCap,naturalCritMin))/2) .. "<br/>"
--res = res .. pForcedCrit*(math.max(0,math.min(1-z1,1))*critCap + math.min(math.max(0,z1),1)*(math.min(critCap,forcedCritMin) + math.min(critCap,max_hit))/2) .. "<br/>"
--res = res .. (1-pForcedCrit)*(pNaturalCrit)*(math.max(0,math.min(1-z2,1))*critCap + math.min(math.max(0,z2),1)*(math.min(naturalCritMin,critCap) + math.min(critCap,max_hit))/2) .. "<br/>"
--res = res .. (1-pForcedCrit)*(1-pNaturalCrit)*(math.max(0,math.min(1-y,1))*dmgCap + math.min(math.max(0,y),1)*(math.min(dmgCap,min_hit) + math.min(dmgCap,naturalCritMin))/2) .. "<br/>"
resDEBUG = resDEBUG .. "preEqFixed = " .. preEqMin .. "<br/>"
resDEBUG = resDEBUG .. "preEqVariable = " .. preEqRand .. "<br/>"
resDEBUG = resDEBUG .. "preEqMax = (preEqFixed + preEqVariable) = " .. preEqMin+preEqRand .. "<br/>"
resDEBUG = resDEBUG .. "pForcedCrit = " .. string.format("%.3f",pForcedCrit) .. "<br/>"
resDEBUG = resDEBUG .. "pNaturalCrit = " .. "(1-" .. string.format("%.3f",pForcedCrit) .. ")*" .. string.format("%.4f",pNaturalCrit) .. " = " .. string.format("%.4f",(1-pForcedCrit)*pNaturalCrit) .. "<br/>"
resDEBUG = resDEBUG .. "pNonCrit = " .. "(1-" .. string.format("%.3f",pForcedCrit) .. ")*" .. "(1-" .. string.format("%.4f",pNaturalCrit) .. ") = " .. string.format("%.4f",(1-pForcedCrit)*(1-pNaturalCrit)) .. "<br/>"
resDEBUG = resDEBUG .. "pGreaterFuryCrit = " .. string.format("%.4f",pCritMFury) .. "<br/>"
resDEBUG = resDEBUG .. "Hit range used: [" .. min_hit .. "," .. max_hit .. "]" .. "<br/>"
resDEBUG = resDEBUG .. "forcedCritMax = " .. forcedCritMax .. "<br/>"
resDEBUG = resDEBUG .. "forcedCritMin = " .. forcedCritMin .. "<br/>"
resDEBUG = resDEBUG .. "naturalCritMin = " .. naturalCritMin .. "<br/>"
resDEBUG = resDEBUG .. "z1 = " .. z1 .. "<br/>"
resDEBUG = resDEBUG .. "z2 = " .. z2 .. "<br/>"
resDEBUG = resDEBUG .. "y = " .. y .. "<br/>"
resDEBUG = resDEBUG .. "math.max(0,math.min(1-z1,1)) = " .. math.max(0,math.min(1-z1,1)) .. "<br/>"
resDEBUG = resDEBUG .. "math.max(0,math.min(1-z2,1)) = " .. math.max(0,math.min(1-z2,1)) .. "<br/>"
resDEBUG = resDEBUG .. "math.max(0,math.min(1-y,1)) = " .. math.max(0,math.min(1-y,1)) .. "<br/>"
resDEBUG = resDEBUG .. "math.min(math.max(0,z1),1) = " .. math.min(math.max(0,z1),1) .. "<br/>"
resDEBUG = resDEBUG .. "math.min(math.max(0,z2),1) = " .. math.min(math.max(0,z2),1) .. "<br/>"
resDEBUG = resDEBUG .. "math.min(math.max(0,y),1) = " .. math.min(math.max(0,y),1) .. "<br/>"
resDEBUG = resDEBUG .. string.format("%.3f",pForcedCrit) .. "*(" .. string.format("%.3f",math.max(0,math.min(1-z1,1))) .. "*" .. critCap .. "+" .. string.format("%.3f",math.min(math.max(0,z1),1)) .. "*(" .. math.min(critCap,forcedCritMin) .. "+" .. math.min(critCap,forcedCritMax) .. ")/2)"
resDEBUG = resDEBUG .. "+(1-".. string.format("%.3f",pForcedCrit) .. ")*" .. string.format("%.4f",pNaturalCrit) .. "*(" .. string.format("%.4f",math.max(0,math.min(1-z2,1))) .. "*" .. critCap .. "+" .. string.format("%.3f",math.min(math.max(0,z2),1)) .. "*(" .. math.min(naturalCritMin,critCap) .. "+" .. math.min(critCap,max_hit) ..")/2)"
resDEBUG = resDEBUG .. "+(1-".. string.format("%.3f",pForcedCrit) .. ")*(1-" .. string.format("%.4f",pNaturalCrit) .. ")*(" .. string.format("%.4f",math.max(0,math.min(1-y,1))) .. "*" .. dmgCap .. "+" .. string.format("%.3f",math.min(math.max(0,y),1)) .. "*(" .. math.min(dmgCap,min_hit) .. "+" .. math.min(dmgCap,naturalCritMin) ..")/2)" .. "<br/>"
resDEBUG = resDEBUG .. "___________________________________" .. "<br/>"
end
--___________________________________
--Probability of hitting at least X
--___________________________________
local totalProbX = 0
totalProbX = pForcedCrit*probDamageAtLeastX(forcedCritMin,forcedCritMax)+(1-pForcedCrit)*pNaturalCrit*probDamageAtLeastX(naturalCritMin,max_hit)+(1-pForcedCrit)*(1-pNaturalCrit)*probDamageAtLeastX(min_hit,naturalCritMin)
--___________________________________
-- Average damage
--___________________________________
local avgDmgAbility = avgDmg
res = res .. "<div style=\"font-weight:bold\">Average damage: " .. string.format("%.1f",avgDmgAbility) .. "</div>"
res = res .. "Average damage (non-critical, chance = " .. string.format("%.2f",math.min(1,(1-pForcedCrit)*(1-pNaturalCrit))*100) .. "%): " .. string.format("%.1f",avgDmgNonCrit) .. "<br/>"
res = res .. "Average damage (critical, chance = " .. string.format("%.2f",math.min(1,pForcedCrit+(1-pForcedCrit)*(pNaturalCrit))*100) .. "%): " .. string.format("%.1f",avgDmgCrit) .. "<br/>"
--___________________________________
-- Output for special cases from
-- abilities that modify crit chance
--___________________________________
pForcedCrit = math.min(1,pBiting+pGrimoire+pCorbicula+pKalgScroll+pFuryAndConc2)
avgDmgCalc()
res = res .. "Average damage after two hits of Fury/Concentrated Blast: " .. string.format("%.1f",avgDmg) .. "<br/>"
local totalProbXConc2 = 0
totalProbXConc2 = pForcedCrit*probDamageAtLeastX(forcedCritMin,forcedCritMax)+(1-pForcedCrit)*pNaturalCrit*probDamageAtLeastX(naturalCritMin,max_hit)+(1-pForcedCrit)*(1-pNaturalCrit)*probDamageAtLeastX(min_hit,naturalCritMin)
--avgDmgCritCalc()
--avgDmgNonCritCalc()
--res = res .. "If used after the second hit of Fury/Concentrated Blast, average damage (non-critical, chance = " .. math.min(1,(1-pForcedCrit)*(1-pNaturalCrit))*100 .. "%) is: " .. string.format("%.1f",avgDmgNonCrit) .. "<br/>"
--res = res .. "If used after the second hit of Fury/Concentrated Blast, average damage (critical, chance = " .. math.min(1,pForcedCrit+(1-pForcedCrit)*(pNaturalCrit))*100 .. "%) is: " .. string.format("%.1f",avgDmgCrit) .. "<br/>"
pForcedCrit = math.min(1,pBiting+pGrimoire+pCorbicula+pKalgScroll+pMFury)
local pMFuryNonCritForcedCrit = pForcedCrit
avgDmgCalc()
local avgDmgNonCritMFury = avgDmg
pForcedCrit = math.min(1,pBiting+pGrimoire+pCorbicula+pKalgScroll+pMFuryGuarantee)
avgDmgCalc()
local avgDmgCritMFury = avgDmg
if (max_MFury>0 and dType=="No") then
local avgDmgCombinedMFury = pCritMFury*avgDmgCritMFury + (1-pCritMFury)*avgDmgNonCritMFury
res = res .. "Average damage after Greater Fury: " .. string.format("%.1f",avgDmgCombinedMFury) .. "<br/>"
end
if (dType=="Yes") then
res = res .. "Average damage after Greater Fury: " .. string.format("%.1f",avgDmgNonCritMFury) .. "<br/>"
end
local totalProbXMFury = 0
if(max_MFury>0 and dType=="No") then
totalProbXMFury = (pCritMFury+(1-pCritMFury)*pMFuryNonCritForcedCrit)*probDamageAtLeastX(forcedCritMin,forcedCritMax) + (1-(pCritMFury+(1-pCritMFury)*pMFuryNonCritForcedCrit))*pNaturalCrit*probDamageAtLeastX(naturalCritMin,max_hit)+(1-(pCritMFury+(1-pCritMFury)*pMFuryNonCritForcedCrit))*(1-pNaturalCrit)*probDamageAtLeastX(min_hit,naturalCritMin)
end
if (dType=="Yes") then
totalProbXMFury = (pMFuryNonCritForcedCrit)*probDamageAtLeastX(forcedCritMin,forcedCritMax) + (1-(pMFuryNonCritForcedCrit))*pNaturalCrit*probDamageAtLeastX(naturalCritMin,max_hit)+(1-(pMFuryNonCritForcedCrit))*(1-pNaturalCrit)*probDamageAtLeastX(min_hit,naturalCritMin)
end
res = res .. "<br/>"
pForcedCrit = math.min(1,pBiting+pGrimoire+pCorbicula+pKalgScroll+pMFury)
if (dType=="No") then
res = res .. "Average damage after (non-critical) Greater Fury: " .. string.format("%.1f",avgDmgNonCritMFury) .. "<br/>"
res = res .. "Average damage after (critical) Greater Fury: " .. string.format("%.1f",avgDmgCritMFury) .. "<br/>"
end
pForcedCrit = math.min(1,pBiting+pGrimoire+pCorbicula+pKalgScroll+pFuryAndConc1)
avgDmgCalc()
res = res .. "Average damage after one hit of Fury/Concentrated Blast: " .. string.format("%.1f",avgDmg) .. "<br/>"
local totalProbXConc1 = 0
totalProbXConc1 = pForcedCrit*probDamageAtLeastX(forcedCritMin,forcedCritMax)+(1-pForcedCrit)*pNaturalCrit*probDamageAtLeastX(naturalCritMin,max_hit)+(1-pForcedCrit)*(1-pNaturalCrit)*probDamageAtLeastX(min_hit,naturalCritMin)
--avgDmgCritCalc()
--avgDmgNonCritCalc()
--res = res .. "If used after the first hit of Fury/Concentrated Blast, average damage (non-critical, chance = " .. math.min(1,(1-pForcedCrit)*(1-pNaturalCrit))*100 .. "%) is: " .. string.format("%.1f",avgDmgNonCrit) .. "<br/>"
--res = res .. "If used after the first hit of Fury/Concentrated Blast, average damage (critical, chance = " .. math.min(1,pForcedCrit+(1-pForcedCrit)*(pNaturalCrit))*100 .. "%) is: " .. string.format("%.1f",avgDmgCrit) .. "<br/>"
pForcedCrit = math.min(1,pBiting+pGrimoire+pCorbicula+pFuryAndConc3)
avgDmgCalc()
res = res .. "Average damage after three hits of Fury/Concentrated Blast: " .. string.format("%.1f",avgDmg) .. "<br/>"
local totalProbXConc3 = 0
totalProbXConc3 = pForcedCrit*probDamageAtLeastX(forcedCritMin,forcedCritMax)+(1-pForcedCrit)*pNaturalCrit*probDamageAtLeastX(naturalCritMin,max_hit)+(1-pForcedCrit)*(1-pNaturalCrit)*probDamageAtLeastX(min_hit,naturalCritMin)
--avgDmgCritCalc()
--avgDmgNonCritCalc()
--res = res .. "If used after the third hit of Fury/Concentrated Blast, average damage (non-critical, chance = " .. math.min(1,(1-pForcedCrit)*(1-pNaturalCrit))*100 .. "%) is: " .. string.format("%.1f",avgDmgNonCrit) .. "<br/>"
--res = res .. "If used after the third hit of Fury/Concentrated Blast, average damage (critical, chance = " .. math.min(1,pForcedCrit+(1-pForcedCrit)*(pNaturalCrit))*100 .. "%) is: " .. string.format("%.1f",avgDmgCrit) .. "<br/>"
res = res .. "<br/>"
--___________________________________
-- Return probability of hitting at least X
--___________________________________
local resX = ""
if(atLeastX > 0) then
resX = resX .. "Probability of hitting over " .. atLeastX .. " damage: " .. string.format("%.2f",totalProbX*100) .. "%<br/>"
resX = resX .. "Probability of hitting over " .. atLeastX .. " damage after two hits of Fury/Concentrated Blast: " .. string.format("%.2f",totalProbXConc2*100) .. "%<br/>"
if(max_MFury>0) then
resX = resX .. "Probability of hitting over " .. atLeastX .. " damage after Greater Fury: " .. string.format("%.2f",totalProbXMFury*100) .. "%<br/>"
end
resX = resX .. "<br/>"
resX = resX .. "Probability of hitting over " .. atLeastX .. " damage after one hit of Fury/Concentrated Blast: " .. string.format("%.2f",totalProbXConc1*100) .. "%<br/>"
resX = resX .. "Probability of hitting over " .. atLeastX .. " damage after three hits of Fury/Concentrated Blast: " .. string.format("%.2f",totalProbXConc3*100) .. "%<br/>"
resX = resX .. "<br/>"
end
--___________________________________
-- Average damage if Eldtrich crossbow Special attack is used
--___________________________________
local resECB = ""
if(splitSoul=="Yes (with Amulet of Souls)" or splitSoul=="Yes (without Amulet of Souls)") then
resECB = resECB .. "<div style=\"font-weight:bold\">Average damage from ability: " .. string.format("%.1f",avgDmgAbility) .. "</div>"
resECB = resECB .. "Average damage from Split Soul: " .. string.format("%.1f",avgDmgSplitSoul) .. "<br/>"
end
resECB = resECB .. "<br/>"
--___________________________________
-- Output of what was set in the
-- user interface
--___________________________________
local resINPUT = ""
resINPUT = resINPUT .. "Auto attack: " .. dType .. "<br/>"
--___________________________________
-- Calculating the damage range
--___________________________________
local minHitDmgRange = 0
local maxHitDmgRange = math.min(critCap,max_hit)
if (min_hit>.95*max_hit and min_hit>=critCap) then
minHitDmgRange = critCap
elseif (min_hit>.95*max_hit and min_hit<critCap) then
minHitDmgRange = min_hit
else
minHitDmgRange = math.min(dmgCap,min_hit)
end
resINPUT = resINPUT .. "Damage range: [" .. minHitDmgRange .. "," .. maxHitDmgRange .. "]" .. "<br/>"
resINPUT = resINPUT .. "Biting perk rank: " .. bitingPerkRank .. "<br/>"
resINPUT = resINPUT .. "Biting perk on level 20 gear: " .. gearLevel20 .. "<br/>"
resINPUT = resINPUT .. "Erethdor's grimoire active: " .. eGrimoire .. "<br/>"
resINPUT = resINPUT .. "#Corbicula farm totems: " .. corbiculatotem .. "<br/>"
resINPUT = resINPUT .. "Crit-i-kal scroll from Kal'gerion demon (familiar) active: " .. kalgScroll .. "<br/>"
resINPUT = resINPUT .. "Eldritch crossbow special attack active: " .. splitSoul .. "<br/>"
resINPUT = resINPUT .. "(Optional) Minimum hit of Greater Fury: " .. min_MFury .. "<br/>"
resINPUT = resINPUT .. "(Optional) Minimum hit of Greater Fury: " .. max_MFury .. "<br/>"
resINPUT = resINPUT .. "Find the probability of hitting at least X damage (Enter value for X) " .. atLeastX .. "<br/>"
resINPUT = resINPUT .. "Display additional information? " .. debugMode .. "<br/>"
--___________________________________
-- Return result
--___________________________________
if(splitSoul ~= "No") then
return resDEBUG .. resECB .. resINPUT
else
return resDEBUG .. res .. resX .. resINPUT
end
end
return p