Module:Crystal Shield calculator

-- local p = {}

local yesno = require ("Module:Yesno")

function p.main(frame) math.randomseed(os.time) local args = frame:getParent.args local min_hit = tonumber(args.minHit) or 0 local max_hit = tonumber(args.maxHit) or 0 local timeStep = tonumber(args.timeStep) or 0 local gearLevel20 = yesno(args.level20) or false

local tAbsorb = 16 -- absorbption phase local tCooldown = 100 -- cooldown phase (tShield = 50 not defined on its own for this as this assumes the pool will always be depleted) local proc = .1 if gearLevel20 then proc = .11 end local csDamage = 0 local totalDamage = 0 local averageDamageBetweenProcs = {0,0,0} local averageDamageRatioOverTime = {0,0,0} local pastHits = 0 --hits that failed to proc local absorbHits = 0 --hits that are done during the absorbption phase (tAbsorb) local cooldownHits = 0 --hits that are done during the cooldown phase (tCooldown) local nHitsAbsorb = math.ceil(tAbsorb/timeStep) local nHitsCooldown = math.ceil((tCooldown-tAbsorb)/timeStep) local res = "" if min_hit > max_hit then return "The minimum hit must not be higher than the maximum hit." end for nHitsAbsorb = 1,nHitsAbsorb do       absorbHits = absorbHits + math.floor(math.random(min_hit,max_hit)) end for nHitsCooldown = 1,nHitsCooldown do       cooldownHits = cooldownHits + math.floor(math.random(min_hit,max_hit)) end for perkRank = 1,3 do       csDamage=0 totalDamage=0 for n = 0,999 do           pastHits=0 for nHitsNoProc = 0,n-1 do               pastHits = pastHits + math.floor(math.random(min_hit,max_hit)) end csDamage = csDamage + (math.pow(1-proc,n)*proc * (pastHits + (1-.05*perkRank)*absorbHits + cooldownHits)) totalDamage = totalDamage + (math.pow(1-proc,n)*proc * (pastHits + absorbHits + cooldownHits)) averageDamageBetweenProcs[perkRank] = averageDamageBetweenProcs[perkRank] + (math.pow(1-proc,n)*proc * (pastHits + (1-.05*perkRank)*absorbHits + cooldownHits) / (pastHits + absorbHits + cooldownHits) ) end averageDamageRatioOverTime[perkRank] = averageDamageRatioOverTime[perkRank] + csDamage/totalDamage end for perkRank = 1,3 do       res = res .. "Average damage reduction from Crystal Shield " .. perkRank .. " : " .. string.format("%2.3f",(1-averageDamageRatioOverTime[perkRank])*100) .. "%. "   end res = res .. " "       for perkRank = 1,3 do        res = res .. "Average damage reduction between procs for Crystal Shield " .. perkRank .. " : " .. string.format("%2.3f",(1-averageDamageBetweenProcs[perkRank])*100) .. "%. "   end return res end

return p