Skip to content

Commit

Permalink
Fix calc mode issues for triggers and mirages (#7458)
Browse files Browse the repository at this point in the history
* FIX: Remove dead code. Fix calc mode issues.

* FIX: remove vestigial exclude list

* FIX: remove left over greoup table wipe
  • Loading branch information
Paliak authored Mar 27, 2024
1 parent f4ae364 commit 8f20e3d
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 139 deletions.
1 change: 0 additions & 1 deletion src/Classes/GemSelectControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ function GemSelectClass:CalcOutputWithThisGem(calcFunc, gemData, qualityId)
gemInstance.displayEffect = oldGem.displayEffect
else
gemList[self.index] = nil
calcFunc({ }, { allocNodes = true, requirementsItems = true })
end

return output, gemInstance
Expand Down
2 changes: 0 additions & 2 deletions src/Data/Global.lua
Original file line number Diff line number Diff line change
Expand Up @@ -316,8 +316,6 @@ SkillType = {

GlobalCache = {
cachedData = { MAIN = {}, CALCS = {}, CALCULATOR = {}, CACHE = {}, },
deleteGroup = { },
excludeFullDpsList = { },
noCache = nil,
useFullDPS = false,
numActiveSkillInFullDPS = 0,
Expand Down
2 changes: 1 addition & 1 deletion src/Data/Skills/sup_str.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2139,7 +2139,7 @@ skills["AvengingFlame"] = {
castTime = 1,
preDamageFunc = function(activeSkill, output)
local uuid = activeSkill.skillData.triggerSourceUUID
local cache = uuid and GlobalCache.cachedData["CACHE"][uuid]
local cache = uuid and (GlobalCache.cachedData["MAIN"][uuid] or GlobalCache.cachedData["CALCS"][uuid])
local totemLife = cache and cache.Env.player.output.TotemLife or 0

local add = totemLife * activeSkill.skillData.lifeDealtAsFire / 100
Expand Down
7 changes: 0 additions & 7 deletions src/Modules/Build.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1019,7 +1019,6 @@ function buildMode:OnFrame(inputEvents)
self.controls.secondaryAscendDrop.list = {{label = "None", ascendClassId = 0}, {label = "Warden", ascendClassId = 1}, {label = "Warlock", ascendClassId = 2}, {label = "Primalist", ascendClassId = 3}}
self.controls.secondaryAscendDrop:SelByValue(self.spec.curSecondaryAscendClassId, "ascendClassId")

local checkFabricatedGroups = self.buildFlag
if self.buildFlag then
-- Wipe Global Cache
wipeGlobalCache()
Expand All @@ -1046,12 +1045,6 @@ function buildMode:OnFrame(inputEvents)
-- Update contents of main skill dropdowns
self:RefreshSkillSelectControls(self.controls, self.mainSocketGroup, "")

-- Delete any possible fabricated groups
if checkFabricatedGroups then
deleteFabricatedGroup(self.skillsTab)
checkFabricatedGroups = false
end

-- Draw contents of current tab
local sideBarWidth = 312
local tabViewPort = {
Expand Down
38 changes: 19 additions & 19 deletions src/Modules/CalcMirages.lua
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ local function calculateMirage(env, config)
end

if mirageSkill then
local newSkill, newEnv = calcs.copyActiveSkill(env, env.mode == "CALCS" and "CALCS" or "MAIN", mirageSkill)
local newSkill, newEnv = calcs.copyActiveSkill(env, env.mode, mirageSkill)
newSkill.skillCfg.skillCond["usedByMirage"] = true
newSkill.skillData.limitedProcessing = true
newSkill.skillData.mirageUses = env.player.mainSkill.skillData.storedUses
Expand Down Expand Up @@ -122,17 +122,17 @@ function calcs.mirages(env)
compareFunc = function(skill, env, config, mirageSkill)
if skill ~= env.player.mainSkill and skill.skillTypes[SkillType.Attack] and not skill.skillTypes[SkillType.Totem] and not skill.skillTypes[SkillType.SummonsTotem] and band(skill.skillCfg.flags, bor(ModFlag.Sword, ModFlag.Weapon1H)) == bor(ModFlag.Sword, ModFlag.Weapon1H) and not skill.skillCfg.skillCond["usedByMirage"] then
local uuid = cacheSkillUUID(skill, env)
if not GlobalCache.cachedData["CACHE"][uuid] or GlobalCache.noCache then
calcs.buildActiveSkill(env, "CACHE", skill)
if not GlobalCache.cachedData[env.mode][uuid] then
calcs.buildActiveSkill(env, env.mode, skill)
end

if GlobalCache.cachedData["CACHE"][uuid] and GlobalCache.cachedData["CACHE"][uuid].CritChance and GlobalCache.cachedData["CACHE"][uuid].CritChance > 0 then
if GlobalCache.cachedData[env.mode][uuid] and GlobalCache.cachedData[env.mode][uuid].CritChance and GlobalCache.cachedData[env.mode][uuid].CritChance > 0 then
if not mirageSkill then
usedSkillBestDps = GlobalCache.cachedData["CACHE"][uuid].TotalDPS
return GlobalCache.cachedData["CACHE"][uuid].ActiveSkill
elseif GlobalCache.cachedData["CACHE"][uuid].TotalDPS > usedSkillBestDps then
usedSkillBestDps = GlobalCache.cachedData["CACHE"][uuid].TotalDPS
return GlobalCache.cachedData["CACHE"][uuid].ActiveSkill
usedSkillBestDps = GlobalCache.cachedData[env.mode][uuid].TotalDPS
return GlobalCache.cachedData[env.mode][uuid].ActiveSkill
elseif GlobalCache.cachedData[env.mode][uuid].TotalDPS > usedSkillBestDps then
usedSkillBestDps = GlobalCache.cachedData[env.mode][uuid].TotalDPS
return GlobalCache.cachedData[env.mode][uuid].ActiveSkill
end
end
end
Expand Down Expand Up @@ -191,21 +191,21 @@ function calcs.mirages(env)
local isDisabled = skill.skillFlags and skill.skillFlags.disable
if skill ~= env.player.mainSkill and (skill.skillTypes[SkillType.Slam] or skill.skillTypes[SkillType.Melee]) and skill.skillTypes[SkillType.Attack] and not skill.skillTypes[SkillType.Vaal] and not isTriggered(skill) and not isDisabled and not skill.skillTypes[SkillType.Totem] and not skill.skillTypes[SkillType.SummonsTotem] and not skill.skillCfg.skillCond["usedByMirage"] then
local uuid = cacheSkillUUID(skill, env)
if not GlobalCache.cachedData["CACHE"][uuid] or GlobalCache.noCache then
calcs.buildActiveSkill(env, "CACHE", skill)
if not GlobalCache.cachedData[env.mode][uuid] or env.mode == "CALCULATOR" then
calcs.buildActiveSkill(env, env.mode, skill)
end

if GlobalCache.cachedData["CACHE"][uuid] then
if GlobalCache.cachedData[env.mode][uuid] then
if not mirageSkill then
usedSkillBestDps = GlobalCache.cachedData["CACHE"][uuid].TotalDPS
EffectiveSourceRate = GlobalCache.cachedData["CACHE"][uuid].Speed
return GlobalCache.cachedData["CACHE"][uuid].ActiveSkill
usedSkillBestDps = GlobalCache.cachedData[env.mode][uuid].TotalDPS
EffectiveSourceRate = GlobalCache.cachedData[env.mode][uuid].Speed
return GlobalCache.cachedData[env.mode][uuid].ActiveSkill

else
if GlobalCache.cachedData["CACHE"][uuid].TotalDPS > usedSkillBestDps then
usedSkillBestDps = GlobalCache.cachedData["CACHE"][uuid].TotalDPS
EffectiveSourceRate = GlobalCache.cachedData["CACHE"][uuid].Speed
return GlobalCache.cachedData["CACHE"][uuid].ActiveSkill
if GlobalCache.cachedData[env.mode][uuid].TotalDPS > usedSkillBestDps then
usedSkillBestDps = GlobalCache.cachedData[env.mode][uuid].TotalDPS
EffectiveSourceRate = GlobalCache.cachedData[env.mode][uuid].Speed
return GlobalCache.cachedData[env.mode][uuid].ActiveSkill
end
end
end
Expand Down
10 changes: 4 additions & 6 deletions src/Modules/CalcPerform.lua
Original file line number Diff line number Diff line change
Expand Up @@ -925,12 +925,10 @@ end
-- 8. Processes buffs and debuffs
-- 9. Processes charges and misc buffs (doActorCharges, doActorMisc)
-- 10. Calculates defence and offence stats (calcs.defence, calcs.offence)
function calcs.perform(env, fullDPSSkipEHP)
function calcs.perform(env, skipEHP)
local modDB = env.modDB
local enemyDB = env.enemyDB

local fullDPSSkipEHP = fullDPSSkipEHP or false

-- Merge keystone modifiers
env.keystonesAdded = { }
mergeKeystones(env)
Expand All @@ -952,7 +950,7 @@ function calcs.perform(env, fullDPSSkipEHP)

env.partyMembers = env.build.partyTab.actor
env.player.partyMembers = env.partyMembers
local partyTabEnableExportBuffs = env.build.partyTab.enableExportBuffs
local partyTabEnableExportBuffs = env.build.partyTab.enableExportBuffs and env.mode ~= "CALCULATOR"

env.minion = env.player.mainSkill.minion
if env.minion then
Expand Down Expand Up @@ -3010,7 +3008,7 @@ function calcs.perform(env, fullDPSSkipEHP)

-- Defence/offence calculations
calcs.defence(env, env.player)
if not fullDPSSkipEHP then
if not skipEHP then
calcs.buildDefenceEstimations(env, env.player)
end

Expand All @@ -3021,7 +3019,7 @@ function calcs.perform(env, fullDPSSkipEHP)

if env.minion then
calcs.defence(env, env.minion)
if not fullDPSSkipEHP then -- main.build.calcsTab.input.showMinion and -- should be disabled unless "calcsTab.input.showMinion" is true
if not skipEHP then -- main.build.calcsTab.input.showMinion and -- should be disabled unless "calcsTab.input.showMinion" is true
calcs.buildDefenceEstimations(env, env.minion)
end
calcs.triggers(env, env.minion)
Expand Down
62 changes: 30 additions & 32 deletions src/Modules/CalcTriggers.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,17 @@ end
-- Identify the trigger action skill for trigger conditions, take highest Attack Per Second
local function findTriggerSkill(env, skill, source, triggerRate, comparer)
local comparer = comparer or function(uuid, source, triggerRate)
local cachedSpeed = GlobalCache.cachedData["CACHE"][uuid].HitSpeed or GlobalCache.cachedData["CACHE"][uuid].Speed
local cachedSpeed = GlobalCache.cachedData[env.mode][uuid].HitSpeed or GlobalCache.cachedData[env.mode][uuid].Speed
return (not source and cachedSpeed) or (cachedSpeed and cachedSpeed > (triggerRate or 0))
end

local uuid = cacheSkillUUID(skill, env)
if not GlobalCache.cachedData["CACHE"][uuid] or GlobalCache.noCache then
calcs.buildActiveSkill(env, "CACHE", skill)
if not GlobalCache.cachedData[env.mode][uuid] or env.mode == "CALCULATOR" then
calcs.buildActiveSkill(env, env.mode, skill)
end

if GlobalCache.cachedData["CACHE"][uuid] and comparer(uuid, source, triggerRate) and (skill.skillFlags and not skill.skillFlags.disable) and (skill.skillCfg and not skill.skillCfg.skillCond["usedByMirage"]) and not skill.skillTypes[SkillType.OtherThingUsesSkill] then
return skill, GlobalCache.cachedData["CACHE"][uuid].HitSpeed or GlobalCache.cachedData["CACHE"][uuid].Speed, uuid
if GlobalCache.cachedData[env.mode][uuid] and comparer(uuid, source, triggerRate) and (skill.skillFlags and not skill.skillFlags.disable) and (skill.skillCfg and not skill.skillCfg.skillCond["usedByMirage"]) and not skill.skillTypes[SkillType.OtherThingUsesSkill] then
return skill, GlobalCache.cachedData[env.mode][uuid].HitSpeed or GlobalCache.cachedData[env.mode][uuid].Speed, uuid
end
return source, triggerRate, source and cacheSkillUUID(source, env)
end
Expand Down Expand Up @@ -460,8 +460,8 @@ local function defaultTriggerHandler(env, config)
actor.mainSkill.skillData.ignoresTickRate = actor.mainSkill.skillData.ignoresTickRate or (actor.mainSkill.skillData.storedUses and actor.mainSkill.skillData.storedUses > 1)

--Account for source unleash
if source and GlobalCache.cachedData["CACHE"][uuid] and source.skillModList:Flag(nil, "HasSeals") and source.skillTypes[SkillType.CanRapidFire] then
local unleashDpsMult = GlobalCache.cachedData["CACHE"][uuid].ActiveSkill.skillData.dpsMultiplier or 1
if source and GlobalCache.cachedData[env.mode][uuid] and source.skillModList:Flag(nil, "HasSeals") and source.skillTypes[SkillType.CanRapidFire] then
local unleashDpsMult = GlobalCache.cachedData[env.mode][uuid].ActiveSkill.skillData.dpsMultiplier or 1
trigRate = trigRate * unleashDpsMult
actor.mainSkill.skillFlags.HasSeals = true
actor.mainSkill.skillData.ignoresTickRate = true
Expand All @@ -471,44 +471,44 @@ local function defaultTriggerHandler(env, config)
end

-- Battlemage's Cry uptime
if actor.mainSkill.skillData.triggeredByBattleMageCry and GlobalCache.cachedData["CACHE"][uuid] and source and source.skillTypes[SkillType.Melee] then
local battleMageUptime = GlobalCache.cachedData["CACHE"][uuid].Env.player.output.BattlemageUpTimeRatio or 100
if actor.mainSkill.skillData.triggeredByBattleMageCry and GlobalCache.cachedData[env.mode][uuid] and source and source.skillTypes[SkillType.Melee] then
local battleMageUptime = GlobalCache.cachedData[env.mode][uuid].Env.player.output.BattlemageUpTimeRatio or 100
trigRate = trigRate * battleMageUptime / 100
if breakdown then
t_insert(breakdown.EffectiveSourceRate, s_format("x %d%% ^8(Battlemage's Cry uptime)", battleMageUptime))
end
end

-- Infernal Cry uptime
if actor.mainSkill.activeEffect.grantedEffect.name == "Combust" and GlobalCache.cachedData["CACHE"][uuid] and source and source.skillTypes[SkillType.Melee] then
local InfernalUpTime = GlobalCache.cachedData["CACHE"][uuid].Env.player.output.InfernalUpTimeRatio or 100
if actor.mainSkill.activeEffect.grantedEffect.name == "Combust" and GlobalCache.cachedData[env.mode][uuid] and source and source.skillTypes[SkillType.Melee] then
local InfernalUpTime = GlobalCache.cachedData[env.mode][uuid].Env.player.output.InfernalUpTimeRatio or 100
trigRate = trigRate * InfernalUpTime / 100
if breakdown then
t_insert(breakdown.EffectiveSourceRate, s_format("x %d%% ^8(Infernal Cry uptime)", InfernalUpTime))
end
end

--Account for skills that can hit multiple times per use
if source and GlobalCache.cachedData["CACHE"][uuid] and source.skillPartName and source.skillPartName:match("(.*)All(.*)Projectiles(.*)") and source.skillFlags.projectile then
local multiHitDpsMult = GlobalCache.cachedData["CACHE"][uuid].Env.player.output.ProjectileCount or 1
if source and GlobalCache.cachedData[env.mode][uuid] and source.skillPartName and source.skillPartName:match("(.*)All(.*)Projectiles(.*)") and source.skillFlags.projectile then
local multiHitDpsMult = GlobalCache.cachedData[env.mode][uuid].Env.player.output.ProjectileCount or 1
trigRate = trigRate * multiHitDpsMult
if breakdown then
t_insert(breakdown.EffectiveSourceRate, s_format("x %.2f ^8(%d projectiles hit)", multiHitDpsMult, multiHitDpsMult))
end
end

--Accuracy and crit chance
if source and (source.skillTypes[SkillType.Melee] or source.skillTypes[SkillType.Attack]) and GlobalCache.cachedData["CACHE"][uuid] and not config.triggerOnUse then
local sourceHitChance = GlobalCache.cachedData["CACHE"][uuid].HitChance
if source and (source.skillTypes[SkillType.Melee] or source.skillTypes[SkillType.Attack]) and GlobalCache.cachedData[env.mode][uuid] and not config.triggerOnUse then
local sourceHitChance = GlobalCache.cachedData[env.mode][uuid].HitChance
trigRate = trigRate * (sourceHitChance or 0) / 100
if breakdown then
t_insert(breakdown.EffectiveSourceRate, s_format("x %.0f%% ^8(%s hit chance)", sourceHitChance, source.activeEffect.grantedEffect.name))
end
if actor.mainSkill.skillData.triggerOnCrit then
local onCritChance = actor.mainSkill.skillData.chanceToTriggerOnCrit or (GlobalCache.cachedData["CACHE"][uuid] and GlobalCache.cachedData["CACHE"][uuid].Env.player.mainSkill.skillData.chanceToTriggerOnCrit)
local onCritChance = actor.mainSkill.skillData.chanceToTriggerOnCrit or (GlobalCache.cachedData[env.mode][uuid] and GlobalCache.cachedData[env.mode][uuid].Env.player.mainSkill.skillData.chanceToTriggerOnCrit)
config.triggerChance = config.triggerChance or actor.mainSkill.skillData.chanceToTriggerOnCrit or onCritChance

local sourceCritChance = GlobalCache.cachedData["CACHE"][uuid].CritChance
local sourceCritChance = GlobalCache.cachedData[env.mode][uuid].CritChance
trigRate = trigRate * (sourceCritChance or 0) / 100
if breakdown then
t_insert(breakdown.EffectiveSourceRate, s_format("x %.2f%% ^8(%s effective crit chance)", sourceCritChance, source.activeEffect.grantedEffect.name))
Expand All @@ -528,15 +528,14 @@ local function defaultTriggerHandler(env, config)

-- Handling for mana spending rate for Manaforged Arrows Support
if actor.mainSkill.skillData.triggeredByManaforged and trigRate > 0 then
local mode = env.mode == "CALCS" and "CALCS" or "MAIN"
local triggeredUUID = cacheSkillUUID(actor.mainSkill, env)
if not GlobalCache.cachedData[mode][triggeredUUID] then
calcs.buildActiveSkill(env, mode, actor.mainSkill, {[triggeredUUID] = true})
if not GlobalCache.cachedData[env.mode][triggeredUUID] then
calcs.buildActiveSkill(env, env.mode, actor.mainSkill, {[triggeredUUID] = true})
end
local triggeredManaCost = GlobalCache.cachedData[mode][triggeredUUID].Env.player.output.ManaCost or 0
local triggeredManaCost = GlobalCache.cachedData[env.mode][triggeredUUID].Env.player.output.ManaCost or 0
if triggeredManaCost > 0 then
local manaSpentThreshold = triggeredManaCost * actor.mainSkill.skillData.ManaForgedArrowsPercentThreshold
local sourceManaCost = GlobalCache.cachedData["CACHE"][uuid].Env.player.output.ManaCost or 0
local sourceManaCost = GlobalCache.cachedData[env.mode][uuid].Env.player.output.ManaCost or 0
if sourceManaCost > 0 then
if breakdown then
t_insert(breakdown.EffectiveSourceRate, s_format("* %.2f ^8(Mana cost of trigger source)", sourceManaCost))
Expand Down Expand Up @@ -599,9 +598,9 @@ local function defaultTriggerHandler(env, config)
output.TriggerRateCap = 1 / actionCooldownTickRounded
end
if config.triggerName == "Doom Blast" and env.build.configTab.input["doomBlastSource"] == "expiration" then
local expirationRate = 1 / GlobalCache.cachedData["CACHE"][uuid].Env.player.output.Duration
local expirationRate = 1 / GlobalCache.cachedData[env.mode][uuid].Env.player.output.Duration
if breakdown and breakdown.EffectiveSourceRate then
breakdown.EffectiveSourceRate[1] = s_format("1 / %.2f ^8(source curse duration)", GlobalCache.cachedData["CACHE"][uuid].Env.player.output.Duration)
breakdown.EffectiveSourceRate[1] = s_format("1 / %.2f ^8(source curse duration)", GlobalCache.cachedData[env.mode][uuid].Env.player.output.Duration)
end
if expirationRate > trigRate then
env.player.modDB:NewMod("UsesCurseOverlaps", "FLAG", true, "Config")
Expand Down Expand Up @@ -1017,8 +1016,8 @@ local configTable = {
return {triggerChance = env.player.modDB:Sum("BASE", nil, "KitavaTriggerChance"),
triggerName = "Kitava's Thirst",
comparer = function(uuid, source, triggerRate)
local cachedSpeed = GlobalCache.cachedData["CACHE"][uuid].HitSpeed or GlobalCache.cachedData["CACHE"][uuid].Speed
local cachedManaCost = GlobalCache.cachedData["CACHE"][uuid].ManaCost
local cachedSpeed = GlobalCache.cachedData[env.mode][uuid].HitSpeed or GlobalCache.cachedData[env.mode][uuid].Speed
local cachedManaCost = GlobalCache.cachedData[env.mode][uuid].ManaCost
return ( (not source and cachedSpeed) or (cachedSpeed and cachedSpeed > (triggerRate or 0)) ) and ( (cachedManaCost or 0) > requiredManaCost )
end,
triggerSkillCond = function(env, skill)
Expand Down Expand Up @@ -1234,20 +1233,19 @@ local configTable = {
if currentSkillSnipeIndex and currentSkillSnipeIndex <= snipeStages then
local source
local trigRate
local mode = env.mode == "CALCS" and "CALCS" or "MAIN"
env.player.mainSkill.skillModList:NewMod("Damage", "MORE", snipeHitMulti * snipeStages , "Snipe", ModFlag.Hit, 0)
env.player.mainSkill.skillModList:NewMod("Damage", "MORE", snipeAilmentMulti * snipeStages , "Snipe", ModFlag.Ailment, 0)
for _, skill in ipairs(env.player.activeSkillList) do
if skill.activeEffect.grantedEffect.name == "Snipe" and skill.socketGroup and skill.socketGroup.slot == env.player.mainSkill.socketGroup.slot then
skill.skillData.hitTimeMultiplier = snipeStages - 0.5
local uuid = cacheSkillUUID(skill, env)
if not GlobalCache.cachedData[mode][uuid] or GlobalCache.noCache then
calcs.buildActiveSkill(env, mode, skill)
if not GlobalCache.cachedData[env.mode][uuid] or env.mode == "CALCULATOR" then
calcs.buildActiveSkill(env, env.mode, skill)
end
local cachedSpeed = GlobalCache.cachedData[mode][uuid].Env.player.output.HitSpeed
local cachedSpeed = GlobalCache.cachedData[env.mode][uuid].Env.player.output.HitSpeed
if (skill.skillFlags and not skill.skillFlags.disable) and (skill.skillCfg and not skill.skillCfg.skillCond["usedByMirage"]) and not skill.skillTypes[SkillType.OtherThingUsesSkill] and ((not source and cachedSpeed) or (cachedSpeed and cachedSpeed > (trigRate or 0))) then
trigRate = cachedSpeed
env.player.output.ChannelTimeToTrigger = GlobalCache.cachedData[mode][uuid].Env.player.output.HitTime
env.player.output.ChannelTimeToTrigger = GlobalCache.cachedData[env.mode][uuid].Env.player.output.HitTime
source = skill
end
end
Expand All @@ -1265,7 +1263,7 @@ local configTable = {
["avenging flame"] = function(env)
return {triggerSkillCond = function(env, skill) return skill.skillFlags.totem and slotMatch(env, skill) end,
comparer = function(uuid, source, currentTotemLife)
local totemLife = GlobalCache.cachedData["CACHE"][uuid].Env.player.output.TotemLife
local totemLife = GlobalCache.cachedData[env.mode][uuid].Env.player.output.TotemLife
return (not source and totemLife) or (totemLife and totemLife > (currentTotemLife or 0))
end,
ignoreSourceRate = true}
Expand Down
Loading

0 comments on commit 8f20e3d

Please sign in to comment.