From 3b617b8aa15aed0b82c63cc95f2b826810e24c71 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Mon, 3 Nov 2025 10:49:50 +1100 Subject: [PATCH 1/4] Fix crash when sorting some gems by Full DPS When we were checking to see if a gem could be affected by a possible support gem we were not considering if the gem had a additional granted effect which was the supporting part of the gem Instead of using the granted effect of the support, we were using the granted effect of the gem which caused a bunch of issues for the code that only expects to deal with supports Also applied this logic to cross linked supports too as I noticed it had a similar issue Also made cross link supports skip it's own socketgroup as it's trying to look for other socketgroups that can support it e.g. Ngamahu's Flame was checking it's own Molten Burst gem group which couldn't possible have supports --- src/Modules/CalcActiveSkill.lua | 53 ++++++++++++++++++++------------- src/Modules/CalcSetup.lua | 10 +++++-- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/Modules/CalcActiveSkill.lua b/src/Modules/CalcActiveSkill.lua index e4da02f025..833c693ed1 100644 --- a/src/Modules/CalcActiveSkill.lua +++ b/src/Modules/CalcActiveSkill.lua @@ -108,13 +108,18 @@ function calcs.createActiveSkill(activeEffect, supportList, actor, socketGroup, local rejectedSupportsIndices = {} for index, supportEffect in ipairs(supportList) do - -- Pass 1: Add skill types from compatible supports - if calcLib.canGrantedEffectSupportActiveSkill(supportEffect.grantedEffect, activeSkill) then - for _, skillType in pairs(supportEffect.grantedEffect.addSkillTypes) do - activeSkill.skillTypes[skillType] = true + -- Loop through grantedEffectList until we find a support gem if the gem has an active and support component e.g. Autoexertion + for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do + if grantedEffect.support then + -- Pass 1: Add skill types from compatible supports + if calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then + for _, skillType in pairs(grantedEffect.addSkillTypes) do + activeSkill.skillTypes[skillType] = true + end + else + t_insert(rejectedSupportsIndices, index) + end end - else - t_insert(rejectedSupportsIndices, index) end end @@ -125,11 +130,15 @@ function calcs.createActiveSkill(activeEffect, supportList, actor, socketGroup, notAddedNewSupport = true for index, supportEffectIndex in ipairs(rejectedSupportsIndices) do local supportEffect = supportList[supportEffectIndex] - if calcLib.canGrantedEffectSupportActiveSkill(supportEffect.grantedEffect, activeSkill) then - notAddedNewSupport = false - rejectedSupportsIndices[index] = nil - for _, skillType in pairs(supportEffect.grantedEffect.addSkillTypes) do - activeSkill.skillTypes[skillType] = true + for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do + if grantedEffect.support then + if calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then + notAddedNewSupport = false + rejectedSupportsIndices[index] = nil + for _, skillType in pairs(grantedEffect.addSkillTypes) do + activeSkill.skillTypes[skillType] = true + end + end end end end @@ -137,15 +146,19 @@ function calcs.createActiveSkill(activeEffect, supportList, actor, socketGroup, for _, supportEffect in ipairs(supportList) do -- Pass 2: Add all compatible supports - if calcLib.canGrantedEffectSupportActiveSkill(supportEffect.grantedEffect, activeSkill) then - t_insert(activeSkill.effectList, supportEffect) - if supportEffect.isSupporting and activeEffect.srcInstance then - supportEffect.isSupporting[activeEffect.srcInstance] = true - end - if supportEffect.grantedEffect.addFlags and not summonSkill then - -- Support skill adds flags to supported skills (eg. Remote Mine adds 'mine') - for k in pairs(supportEffect.grantedEffect.addFlags) do - skillFlags[k] = true + for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do + if grantedEffect.support then + if calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then + t_insert(activeSkill.effectList, supportEffect) + if supportEffect.isSupporting and activeEffect.srcInstance then + supportEffect.isSupporting[activeEffect.srcInstance] = true + end + if grantedEffect.addFlags and not summonSkill then + -- Support skill adds flags to supported skills (eg. Remote Mine adds 'mine') + for k in pairs(grantedEffect.addFlags) do + skillFlags[k] = true + end + end end end end diff --git a/src/Modules/CalcSetup.lua b/src/Modules/CalcSetup.lua index fd0243a4c0..130ad39de7 100644 --- a/src/Modules/CalcSetup.lua +++ b/src/Modules/CalcSetup.lua @@ -1578,10 +1578,14 @@ function calcs.initEnv(build, mode, override, specEnv) if supportLists[slotName] then -- add socketed supports from other socketGroups for _, otherSocketGroup in ipairs(build.skillsTab.socketGroupList) do - if otherSocketGroup.slot and otherSocketGroup.slot == group.slot then + if otherSocketGroup.slot and otherSocketGroup.slot == group.slot and not (otherSocketGroup.source and otherSocketGroup.source == group.source) then for _, gem in ipairs(otherSocketGroup.gemList) do - if gem.gemData and gem.gemData.grantedEffect and gem.gemData.grantedEffect.support then - t_insert(group.displayGemList, gem) + if gem.gemData and gem.gemData.grantedEffectList then + for _, grantedEffect in ipairs(gem.gemData.grantedEffectList) do + if grantedEffect.support then + t_insert(group.displayGemList, gem) + end + end end end end From 5a6a7bf6da5cf746e3aec16da8d4e402b5d7ab0f Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Mon, 3 Nov 2025 12:44:20 +1100 Subject: [PATCH 2/4] Fix error with supports granted by items Supports granted by many items do not have any gemData as they are just a grantedEffect --- src/Modules/CalcActiveSkill.lua | 87 +++++++++++++++++++++++---------- 1 file changed, 61 insertions(+), 26 deletions(-) diff --git a/src/Modules/CalcActiveSkill.lua b/src/Modules/CalcActiveSkill.lua index 833c693ed1..8792380215 100644 --- a/src/Modules/CalcActiveSkill.lua +++ b/src/Modules/CalcActiveSkill.lua @@ -109,17 +109,28 @@ function calcs.createActiveSkill(activeEffect, supportList, actor, socketGroup, for index, supportEffect in ipairs(supportList) do -- Loop through grantedEffectList until we find a support gem if the gem has an active and support component e.g. Autoexertion - for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do - if grantedEffect.support then - -- Pass 1: Add skill types from compatible supports - if calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then - for _, skillType in pairs(grantedEffect.addSkillTypes) do - activeSkill.skillTypes[skillType] = true + if supportEffect.gemData then + for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do + if grantedEffect.support then + -- Pass 1: Add skill types from compatible supports + if calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then + for _, skillType in pairs(grantedEffect.addSkillTypes) do + activeSkill.skillTypes[skillType] = true + end + else + t_insert(rejectedSupportsIndices, index) end - else - t_insert(rejectedSupportsIndices, index) end end + else + -- Skill with no GemData e.g. Item granted supports + if calcLib.canGrantedEffectSupportActiveSkill(supportEffect.grantedEffect, activeSkill) then + for _, skillType in pairs(supportEffect.grantedEffect.addSkillTypes) do + activeSkill.skillTypes[skillType] = true + end + else + t_insert(rejectedSupportsIndices, index) + end end end @@ -130,34 +141,58 @@ function calcs.createActiveSkill(activeEffect, supportList, actor, socketGroup, notAddedNewSupport = true for index, supportEffectIndex in ipairs(rejectedSupportsIndices) do local supportEffect = supportList[supportEffectIndex] - for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do - if grantedEffect.support then - if calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then - notAddedNewSupport = false - rejectedSupportsIndices[index] = nil - for _, skillType in pairs(grantedEffect.addSkillTypes) do - activeSkill.skillTypes[skillType] = true + if supportEffect.gemData then + for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do + if grantedEffect.support then + if calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then + notAddedNewSupport = false + rejectedSupportsIndices[index] = nil + for _, skillType in pairs(grantedEffect.addSkillTypes) do + activeSkill.skillTypes[skillType] = true + end end end end + else + if calcLib.canGrantedEffectSupportActiveSkill(supportEffect.grantedEffect, activeSkill) then + notAddedNewSupport = false + rejectedSupportsIndices[index] = nil + for _, skillType in pairs(supportEffect.grantedEffect.addSkillTypes) do + activeSkill.skillTypes[skillType] = true + end + end end end until (notAddedNewSupport) for _, supportEffect in ipairs(supportList) do -- Pass 2: Add all compatible supports - for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do - if grantedEffect.support then - if calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then - t_insert(activeSkill.effectList, supportEffect) - if supportEffect.isSupporting and activeEffect.srcInstance then - supportEffect.isSupporting[activeEffect.srcInstance] = true - end - if grantedEffect.addFlags and not summonSkill then - -- Support skill adds flags to supported skills (eg. Remote Mine adds 'mine') - for k in pairs(grantedEffect.addFlags) do - skillFlags[k] = true + if supportEffect.gemData then + for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do + if grantedEffect.support then + if calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then + t_insert(activeSkill.effectList, supportEffect) + if supportEffect.isSupporting and activeEffect.srcInstance then + supportEffect.isSupporting[activeEffect.srcInstance] = true end + if grantedEffect.addFlags and not summonSkill then + -- Support skill adds flags to supported skills (eg. Remote Mine adds 'mine') + for k in pairs(grantedEffect.addFlags) do + skillFlags[k] = true + end + end + end + end + end + if calcLib.canGrantedEffectSupportActiveSkill(supportEffect.grantedEffect, activeSkill) then + t_insert(activeSkill.effectList, supportEffect) + if supportEffect.isSupporting and activeEffect.srcInstance then + supportEffect.isSupporting[activeEffect.srcInstance] = true + end + if supportEffect.grantedEffect.addFlags and not summonSkill then + -- Support skill adds flags to supported skills (eg. Remote Mine adds 'mine') + for k in pairs(supportEffect.grantedEffect.addFlags) do + skillFlags[k] = true end end end From 38a9a7d7c004dad88a968b70e6f7803ae40f05bc Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Sun, 23 Nov 2025 00:20:59 +1100 Subject: [PATCH 3/4] Fix test issues --- src/Modules/CalcActiveSkill.lua | 39 ++++++++++++++------------------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/src/Modules/CalcActiveSkill.lua b/src/Modules/CalcActiveSkill.lua index 8792380215..dc61042088 100644 --- a/src/Modules/CalcActiveSkill.lua +++ b/src/Modules/CalcActiveSkill.lua @@ -167,33 +167,26 @@ function calcs.createActiveSkill(activeEffect, supportList, actor, socketGroup, for _, supportEffect in ipairs(supportList) do -- Pass 2: Add all compatible supports + local grantedSupportEffect if supportEffect.gemData then for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do - if grantedEffect.support then - if calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then - t_insert(activeSkill.effectList, supportEffect) - if supportEffect.isSupporting and activeEffect.srcInstance then - supportEffect.isSupporting[activeEffect.srcInstance] = true - end - if grantedEffect.addFlags and not summonSkill then - -- Support skill adds flags to supported skills (eg. Remote Mine adds 'mine') - for k in pairs(grantedEffect.addFlags) do - skillFlags[k] = true - end - end - end + if grantedEffect and grantedEffect.support and calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then + grantedSupportEffect = grantedEffect + break end end - if calcLib.canGrantedEffectSupportActiveSkill(supportEffect.grantedEffect, activeSkill) then - t_insert(activeSkill.effectList, supportEffect) - if supportEffect.isSupporting and activeEffect.srcInstance then - supportEffect.isSupporting[activeEffect.srcInstance] = true - end - if supportEffect.grantedEffect.addFlags and not summonSkill then - -- Support skill adds flags to supported skills (eg. Remote Mine adds 'mine') - for k in pairs(supportEffect.grantedEffect.addFlags) do - skillFlags[k] = true - end + elseif calcLib.canGrantedEffectSupportActiveSkill(supportEffect.grantedEffect, activeSkill) then + grantedSupportEffect = supportEffect.grantedEffect + end + if grantedSupportEffect then + t_insert(activeSkill.effectList, supportEffect) + if supportEffect.isSupporting and activeEffect.srcInstance then + supportEffect.isSupporting[activeEffect.srcInstance] = true + end + if grantedSupportEffect.addFlags and not summonSkill then + -- Support skill adds flags to supported skills (eg. Remote Mine adds 'mine') + for k in pairs(grantedSupportEffect.addFlags) do + skillFlags[k] = true end end end From 5a25f82a0402c483bde06d6c0e867006565de004 Mon Sep 17 00:00:00 2001 From: LocalIdentity Date: Sun, 23 Nov 2025 00:42:27 +1100 Subject: [PATCH 4/4] Use function to remove duplicate code --- src/Modules/CalcActiveSkill.lua | 76 +++++++++++++-------------------- 1 file changed, 30 insertions(+), 46 deletions(-) diff --git a/src/Modules/CalcActiveSkill.lua b/src/Modules/CalcActiveSkill.lua index dc61042088..fe355de914 100644 --- a/src/Modules/CalcActiveSkill.lua +++ b/src/Modules/CalcActiveSkill.lua @@ -107,31 +107,38 @@ function calcs.createActiveSkill(activeEffect, supportList, actor, socketGroup, activeSkill.effectList = { activeEffect } local rejectedSupportsIndices = {} - for index, supportEffect in ipairs(supportList) do - -- Loop through grantedEffectList until we find a support gem if the gem has an active and support component e.g. Autoexertion + -- Return first compatible support grantedEffect plus a flag indicating the support has a support component + local function getGrantedSupportEffect(supportEffect) + local hasSupport = false if supportEffect.gemData then for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do - if grantedEffect.support then - -- Pass 1: Add skill types from compatible supports + if grantedEffect and grantedEffect.support then + hasSupport = true if calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then - for _, skillType in pairs(grantedEffect.addSkillTypes) do - activeSkill.skillTypes[skillType] = true - end - else - t_insert(rejectedSupportsIndices, index) + return grantedEffect, true end end end - else - -- Skill with no GemData e.g. Item granted supports + elseif supportEffect.grantedEffect then + hasSupport = true if calcLib.canGrantedEffectSupportActiveSkill(supportEffect.grantedEffect, activeSkill) then - for _, skillType in pairs(supportEffect.grantedEffect.addSkillTypes) do - activeSkill.skillTypes[skillType] = true - end - else - t_insert(rejectedSupportsIndices, index) + return supportEffect.grantedEffect, true end end + return nil, hasSupport + end + + for index, supportEffect in ipairs(supportList) do + -- Loop through grantedEffectList until we find a support gem if the gem has an active and support component e.g. Autoexertion + local grantedSupportEffect, hasSupport = getGrantedSupportEffect(supportEffect) + if grantedSupportEffect then + -- Pass 1: Add skill types from compatible supports + for _, skillType in pairs(grantedSupportEffect.addSkillTypes) do + activeSkill.skillTypes[skillType] = true + end + elseif hasSupport then + t_insert(rejectedSupportsIndices, index) + end end -- loop over rejected supports until none are added. @@ -141,25 +148,12 @@ function calcs.createActiveSkill(activeEffect, supportList, actor, socketGroup, notAddedNewSupport = true for index, supportEffectIndex in ipairs(rejectedSupportsIndices) do local supportEffect = supportList[supportEffectIndex] - if supportEffect.gemData then - for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do - if grantedEffect.support then - if calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then - notAddedNewSupport = false - rejectedSupportsIndices[index] = nil - for _, skillType in pairs(grantedEffect.addSkillTypes) do - activeSkill.skillTypes[skillType] = true - end - end - end - end - else - if calcLib.canGrantedEffectSupportActiveSkill(supportEffect.grantedEffect, activeSkill) then - notAddedNewSupport = false - rejectedSupportsIndices[index] = nil - for _, skillType in pairs(supportEffect.grantedEffect.addSkillTypes) do - activeSkill.skillTypes[skillType] = true - end + local grantedSupportEffect = getGrantedSupportEffect(supportEffect) + if grantedSupportEffect then + notAddedNewSupport = false + rejectedSupportsIndices[index] = nil + for _, skillType in pairs(grantedSupportEffect.addSkillTypes) do + activeSkill.skillTypes[skillType] = true end end end @@ -167,17 +161,7 @@ function calcs.createActiveSkill(activeEffect, supportList, actor, socketGroup, for _, supportEffect in ipairs(supportList) do -- Pass 2: Add all compatible supports - local grantedSupportEffect - if supportEffect.gemData then - for _, grantedEffect in ipairs(supportEffect.gemData.grantedEffectList) do - if grantedEffect and grantedEffect.support and calcLib.canGrantedEffectSupportActiveSkill(grantedEffect, activeSkill) then - grantedSupportEffect = grantedEffect - break - end - end - elseif calcLib.canGrantedEffectSupportActiveSkill(supportEffect.grantedEffect, activeSkill) then - grantedSupportEffect = supportEffect.grantedEffect - end + local grantedSupportEffect = getGrantedSupportEffect(supportEffect) if grantedSupportEffect then t_insert(activeSkill.effectList, supportEffect) if supportEffect.isSupporting and activeEffect.srcInstance then