From 7a7fdc2975272f884742cb151324b066fe1d1bdb Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Sun, 18 Jan 2026 19:55:04 -0600 Subject: [PATCH 01/10] Show where levels came from --- src/Classes/GemSelectControl.lua | 11 +++++++++++ src/Classes/ImportTab.lua | 1 + 2 files changed, 12 insertions(+) diff --git a/src/Classes/GemSelectControl.lua b/src/Classes/GemSelectControl.lua index 66834b7d2..6b595e180 100644 --- a/src/Classes/GemSelectControl.lua +++ b/src/Classes/GemSelectControl.lua @@ -605,6 +605,17 @@ function GemSelectClass:AddGrantedEffectInfo(gemInstance, grantedEffect, addReq) ((displayInstance.level > gemInstance.level) and " (" .. colorCodes.MAGIC .. "+" .. (displayInstance.level - gemInstance.level) .. "^7)") or ((displayInstance.level < gemInstance.level) and " (" .. colorCodes.WARNING .. "-" .. (gemInstance.level - displayInstance.level) .. "^7)") or "", (gemInstance.level >= gemInstance.gemData.naturalMaxLevel) and " (Max)" or "" ),"FONTIN SC") + if displayInstance.level - gemInstance.level > 0 then + self.tooltip:AddLine(fontSizeBig, gemInstance.level .. " Levels from Gem", "FONTIN SC") + if displayInstance.gemPropertyInfo and displayInstance.gemPropertyInfo[1].value.value > 0 then + self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.gemPropertyInfo[1].value.value .. " Levels from Global Modifiers", "FONTIN SC") + if displayInstance.level - gemInstance.level - displayInstance.gemPropertyInfo[1].value.value > 0 then + self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.level - gemInstance.level - displayInstance.gemPropertyInfo[1].value.value .. " Levels from Supports", "FONTIN SC") + end + else + self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.level - gemInstance.level .. " Levels from Supports", "FONTIN SC") + end + end end if grantedEffect.support then if grantedEffectLevel.manaMultiplier and grantedEffectLevel.reservationMultiplier and grantedEffectLevel.manaMultiplier == grantedEffectLevel.reservationMultiplier then diff --git a/src/Classes/ImportTab.lua b/src/Classes/ImportTab.lua index ef26f786b..f10432516 100644 --- a/src/Classes/ImportTab.lua +++ b/src/Classes/ImportTab.lua @@ -775,6 +775,7 @@ function ImportTabClass:ImportItemsAndSkills(charData) if gemId then local gemInstance = { level = 20, quality = 0, enabled = true, enableGlobal1 = true, enableGlobal2 = true, count = 1, gemId = gemId } gemInstance.support = skillData.support + gemInstance.corrupted = skillData.corrupted local spectreList = data.spectres if typeLine:sub(1, 8) == "Spectre:" then From 1942ebe5ad2083d7ac80622d799f7f182c419396 Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Mon, 19 Jan 2026 23:17:26 -0600 Subject: [PATCH 02/10] Add corruption dropdown to skills tab, import corrupted, and fix Sacrificial Regalia --- src/Classes/GemSelectControl.lua | 44 ++++++--- src/Classes/ImportTab.lua | 4 +- src/Classes/SkillsTab.lua | 155 +++++++++++++++++++++++++++++-- src/Modules/CalcActiveSkill.lua | 4 + src/Modules/CalcPerform.lua | 8 +- src/Modules/CalcSections.lua | 2 +- src/Modules/CalcSetup.lua | 5 + 7 files changed, 194 insertions(+), 28 deletions(-) diff --git a/src/Classes/GemSelectControl.lua b/src/Classes/GemSelectControl.lua index 6b595e180..41efb391f 100644 --- a/src/Classes/GemSelectControl.lua +++ b/src/Classes/GemSelectControl.lua @@ -462,7 +462,9 @@ function GemSelectClass:Draw(viewPort, noTooltip) nameSpec = gemData.name, skillId = gemData.grantedEffectId, displayEffect = nil, - gemData = gemData + gemData = gemData, + corruptLevel = 0, + corrupted = false, } self:AddGemTooltip(gemInstance) self.tooltip:AddSeparator(10) @@ -600,21 +602,29 @@ function GemSelectClass:AddGrantedEffectInfo(gemInstance, grantedEffect, addReq) self.tooltip:AddLine(fontSizeBig, string.format("^x7F7F7FTier: ^7%d", gemInstance.gemData.Tier), "FONTIN SC") end if addReq and not grantedEffect.support then - self.tooltip:AddLine(fontSizeBig, string.format("^x7F7F7FLevel: ^7%d%s%s", - gemInstance.level, - ((displayInstance.level > gemInstance.level) and " (" .. colorCodes.MAGIC .. "+" .. (displayInstance.level - gemInstance.level) .. "^7)") or ((displayInstance.level < gemInstance.level) and " (" .. colorCodes.WARNING .. "-" .. (gemInstance.level - displayInstance.level) .. "^7)") or "", - (gemInstance.level >= gemInstance.gemData.naturalMaxLevel) and " (Max)" or "" - ),"FONTIN SC") - if displayInstance.level - gemInstance.level > 0 then - self.tooltip:AddLine(fontSizeBig, gemInstance.level .. " Levels from Gem", "FONTIN SC") - if displayInstance.gemPropertyInfo and displayInstance.gemPropertyInfo[1].value.value > 0 then - self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.gemPropertyInfo[1].value.value .. " Levels from Global Modifiers", "FONTIN SC") - if displayInstance.level - gemInstance.level - displayInstance.gemPropertyInfo[1].value.value > 0 then - self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.level - gemInstance.level - displayInstance.gemPropertyInfo[1].value.value .. " Levels from Supports", "FONTIN SC") - end - else - self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.level - gemInstance.level .. " Levels from Supports", "FONTIN SC") + local totalLevel + totalLevel = displayInstance.level + if displayInstance.corruptLevel ~= 0 or + (displayInstance.gemPropertyInfo and displayInstance.gemPropertyInfo[1].value.value > 0 ) or + (displayInstance.level - gemInstance.level - displayInstance.corruptLevel > 0) + then + self.tooltip:AddLine(fontSizeBig, string.format("^x7F7F7FLevel: ^7" .. colorCodes.MAGIC .. totalLevel), "FONTIN SC") + self.tooltip:AddLine(fontSizeBig, "^7" .. gemInstance.level .. " Levels from Gem", "FONTIN SC") + else + self.tooltip:AddLine(fontSizeBig, string.format("^x7F7F7FLevel: ^7" .. totalLevel), "FONTIN SC") + end + if displayInstance.gemPropertyInfo and displayInstance.gemPropertyInfo[1].value.value > 0 then + self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.gemPropertyInfo[1].value.value .. " Levels from Global Modifiers", "FONTIN SC") + if displayInstance.level - gemInstance.level - displayInstance.corruptLevel - displayInstance.gemPropertyInfo[1].value.value > 0 then + self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.level - gemInstance.level - displayInstance.corruptLevel - displayInstance.gemPropertyInfo[1].value.value .. " Levels from Supports", "FONTIN SC") end + elseif displayInstance.level - gemInstance.level - displayInstance.corruptLevel > 0 then + self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.level - gemInstance.level - displayInstance.corruptLevel .. " Levels from Supports", "FONTIN SC") + end + if displayInstance.corruptLevel > 0 then + self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.corruptLevel .. " Level from Corruption", "FONTIN SC") + elseif displayInstance.corruptLevel < 0 then + self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. displayInstance.corruptLevel .. " Level from Corruption", "FONTIN SC") end end if grantedEffect.support then @@ -718,6 +728,10 @@ function GemSelectClass:AddGrantedEffectInfo(gemInstance, grantedEffect, addReq) for _, line in ipairs(wrap) do self.tooltip:AddLine(fontSizeBig, colorCodes.GEMDESCRIPTION..line, "FONTIN ITALIC") end + if displayInstance.corrupted == true then + self.tooltip:AddSeparator(10) + self.tooltip:AddLine(fontSizeBig, colorCodes.NEGATIVE .. "Corrupted", "FONTIN SC") + end end end function GemSelectClass:AddStatSetInfo(gemInstance, grantedEffect, statSet, noLabel, index) diff --git a/src/Classes/ImportTab.lua b/src/Classes/ImportTab.lua index f10432516..f40a98a84 100644 --- a/src/Classes/ImportTab.lua +++ b/src/Classes/ImportTab.lua @@ -831,8 +831,8 @@ function ImportTabClass:ImportItemsAndSkills(charData) else gemInstance.level = tonumber(property.values[1][1]:match("%d+")) end - if skillData.properties[_ + 2] and skillData.properties[_ + 2].values[1][1]:match("(%d+) Level[s]? from Corruption") then - gemInstance.level = gemInstance.level + tonumber(skillData.properties[_ + 2].values[1][1]:match("(%d+) Level[s]? from Corruption")) + if skillData.properties[_ + 2] and skillData.properties[_ + 2].values[1][1]:match("(-?%d+) Level[s]? from Corruption") then + gemInstance.corruptLevel = tonumber(skillData.properties[_ + 2].values[1][1]:match("(-?%d+) Level[s]? from Corruption")) end elseif escapeGGGString(property.name) == "Quality" then gemInstance.quality = tonumber(property.values[1][1]:match("%d+")) diff --git a/src/Classes/SkillsTab.lua b/src/Classes/SkillsTab.lua index 5d203a27a..2b240dc3c 100644 --- a/src/Classes/SkillsTab.lua +++ b/src/Classes/SkillsTab.lua @@ -58,6 +58,13 @@ local showSupportGemTypeList = { { label = "Awakened", show = "AWAKENED" }, } +local corruptOption = { + { label = "Not Corrupted", level = 0 }, + { label = "+1 to Gem Level", level = 1 }, + { label = "Corrupted", level = 0 }, + { label = "-1 to Gem Level", level = -1 }, +} + local sortGemTypeList = { { label = "Full DPS", type = "FullDPS" }, { label = "Combined DPS", type = "CombinedDPS" }, @@ -260,6 +267,7 @@ will automatically apply to the skill.]] self.controls.gemNameHeader = new("LabelControl", {"BOTTOMLEFT", self.gemSlots[1].nameSpec, "TOPLEFT"}, {0, -2, 0, 16}, "^7Gem name:") self.controls.gemLevelHeader = new("LabelControl", {"BOTTOMLEFT", self.gemSlots[1].level, "TOPLEFT"}, {0, -2, 0, 16}, "^7Level:") self.controls.gemQualityHeader = new("LabelControl", {"BOTTOMLEFT", self.gemSlots[1].quality, "TOPLEFT"}, {0, -2, 0, 16}, "^7Quality:") + self.controls.gemCorruptHeader = new("LabelControl", {"BOTTOMLEFT", self.gemSlots[1].corruptLevel, "TOPLEFT"}, {0, -2, 0, 16}, "^7Corrupt:") self.controls.gemEnableHeader = new("LabelControl", {"BOTTOMLEFT", self.gemSlots[1].enabled, "TOPLEFT"}, {-16, -2, 0, 16}, "^7Enabled:") self.controls.gemCountHeader = new("LabelControl", {"BOTTOMLEFT", self.gemSlots[1].count, "TOPLEFT"}, {8, -2, 0, 16}, "^7Count:") end) @@ -333,6 +341,8 @@ function SkillsTabClass:LoadSkill(node, skillSetId) gemInstance.skillMinionItemSetCalcs = tonumber(child.attrib.skillMinionItemSetCalcs) gemInstance.skillMinionSkill = tonumber(child.attrib.skillMinionSkill) gemInstance.skillMinionSkillCalcs = tonumber(child.attrib.skillMinionSkillCalcs) + gemInstance.corrupted = child.attrib.corrupted + gemInstance.corruptLevel = tonumber(child.attrib.corruptLevel) gemInstance.statSet = { } gemInstance.statSetCalcs = { } gemInstance.skillMinionSkillStatSetIndexLookup = { } @@ -461,6 +471,8 @@ function SkillsTabClass:Save(xml) skillMinionItemSetCalcs = gemInstance.skillMinionItemSetCalcs and tostring(gemInstance.skillMinionItemSetCalcs), skillMinionSkill = gemInstance.skillMinionSkill and tostring(gemInstance.skillMinionSkill), skillMinionSkillCalcs = gemInstance.skillMinionSkillCalcs and tostring(gemInstance.skillMinionSkillCalcs), + corrupted = tostring(gemInstance.corrupted), + corruptLevel = tostring(gemInstance.corruptLevel), } } if gemInstance.statSet then for grantedEffect, index in pairs(gemInstance.statSet) do @@ -575,8 +587,15 @@ function SkillsTabClass:CopySocketGroup(socketGroup) skillText = skillText .. "Slot: " .. socketGroup.slot .. "\r\n" end for _, gemInstance in ipairs(socketGroup.gemList) do - skillText = skillText .. string.format("%s %d/%d %s %d\r\n", gemInstance.nameSpec, gemInstance.level, gemInstance.quality, gemInstance.enabled and "" or "DISABLED", gemInstance.count or 1) - end + skillText = skillText .. string.format( + "%s %d/%d %s %d%s\r\n", + gemInstance.nameSpec, + gemInstance.level, + gemInstance.quality, + gemInstance.enabled and "" or "DISABLED", + gemInstance.count or 1, + gemInstance.corrupted and (" C" .. ((gemInstance.corruptLevel or 0) ~= 0 and ((gemInstance.corruptLevel > 0 and "+" or "") .. gemInstance.corruptLevel) or "")) or "" + ) end Copy(skillText) end @@ -632,6 +651,17 @@ function SkillsTabClass:CreateGemSlot(index) self.gemSlots[index2].enableGlobal1.state = gemInstance.enableGlobal1 self.gemSlots[index2].enableGlobal2.state = gemInstance.enableGlobal2 self.gemSlots[index2].count:SetText(gemInstance.count or 1) + local selIndex + if gemInstance.corruptLevel == 1 then + selIndex = 2 -- +1 to Gem Level + elseif gemInstance.corruptLevel == -1 then + selIndex = 4 -- -1 to Gem Level + elseif gemInstance.corrupted then + selIndex = 3 -- Corrupted + else + selIndex = 1 -- Not Corrupted + end + self.gemSlots[index2].corruptLevel.selIndex = selIndex end self:AddUndoState() self.build.buildFlag = true @@ -671,11 +701,24 @@ function SkillsTabClass:CreateGemSlot(index) enableGlobal1 = true, enableGlobal2 = true, count = 1, - new = true + new = true, + corrupted = false, + corruptLevel = 0, } self.displayGroup.gemList[index] = gemInstance slot.level:SetText(gemInstance.level) slot.quality:SetText(gemInstance.quality) + local selIndex + if gemInstance.corruptLevel == 1 then + selIndex = 2 -- +1 to Gem Level + elseif gemInstance.corruptLevel == -1 then + selIndex = 4 -- -1 to Gem Level + elseif gemInstance.corrupted and gemInstance.corruptLevel == 0 then + selIndex = 3 -- Corrupted + else + selIndex = 1 -- Not Corrupted + end + slot.corruptLevel.selIndex = selIndex slot.enabled.state = true slot.enableGlobal1.state = true slot.enableGlobal2.state = true @@ -707,12 +750,23 @@ function SkillsTabClass:CreateGemSlot(index) slot.level = new("EditControl", { "LEFT", slot.nameSpec, "RIGHT" }, { 2, 0, 60, 20 }, nil, nil, "%D", 2, function(buf) local gemInstance = self.displayGroup.gemList[index] if not gemInstance then - gemInstance = { nameSpec = "", level = self.defaultGemLevel or 20, quality = self.defaultGemQuality or 0, enabled = true, enableGlobal1 = true, enableGlobal2 = true, count = 1, new = true } + gemInstance = { nameSpec = "", level = self.defaultGemLevel or 20, quality = self.defaultGemQuality or 0, enabled = true, enableGlobal1 = true, enableGlobal2 = true, count = 1, new = true, corruptLevel = 0, corrupted = false } self.displayGroup.gemList[index] = gemInstance slot.quality:SetText(gemInstance.quality) slot.enabled.state = true slot.enableGlobal1.state = true slot.count:SetText(gemInstance.count) + local selIndex + if gemInstance.corruptLevel == 1 then + selIndex = 2 -- +1 to Gem Level + elseif gemInstance.corruptLevel == -1 then + selIndex = 4 -- -1 to Gem Level + elseif gemInstance.corrupted and gemInstance.corruptLevel == 0 then + selIndex = 3 -- Corrupted + else + selIndex = 1 -- Not Corrupted + end + slot.corruptLevel = selIndex end gemInstance.level = tonumber(buf) or self.displayGroup.gemList[index].naturalMaxLevel or self:ProcessGemLevel(gemInstance.gemData) or 20 self:ProcessSocketGroup(self.displayGroup) @@ -729,12 +783,23 @@ function SkillsTabClass:CreateGemSlot(index) slot.quality = new("EditControl", {"LEFT",slot.level,"RIGHT"}, {2, 0, 60, 20}, nil, nil, "%D", 2, function(buf) local gemInstance = self.displayGroup.gemList[index] if not gemInstance then - gemInstance = { nameSpec = "", level = self.defaultGemLevel or 20, quality = self.defaultGemQuality or 0, enabled = true, enableGlobal1 = true, enableGlobal2 = true, count = 1, new = true } + gemInstance = { nameSpec = "", level = self.defaultGemLevel or 20, quality = self.defaultGemQuality or 0, enabled = true, enableGlobal1 = true, enableGlobal2 = true, count = 1, new = true, corruptLevel = 0, corrupted = false } self.displayGroup.gemList[index] = gemInstance slot.level:SetText(gemInstance.level) slot.enabled.state = true slot.enableGlobal1.state = true slot.count:SetText(gemInstance.count) + local selIndex + if gemInstance.corruptLevel == 1 then + selIndex = 2 -- +1 to Gem Level + elseif gemInstance.corruptLevel == -1 then + selIndex = 4 -- -1 to Gem Level + elseif gemInstance.corrupted and gemInstance.corruptLevel == 0 then + selIndex = 3 -- Corrupted + else + selIndex = 1 -- Not Corrupted + end + slot.corruptLevel = selIndex end gemInstance.quality = tonumber(buf) or self.defaultGemQuality or 0 self:ProcessSocketGroup(self.displayGroup) @@ -824,11 +889,22 @@ function SkillsTabClass:CreateGemSlot(index) slot.enabled = new("CheckBoxControl", {"LEFT",slot.quality,"RIGHT"}, {18, 0, 20}, nil, function(state) local gemInstance = self.displayGroup.gemList[index] if not gemInstance then - gemInstance = { nameSpec = "", level = self.defaultGemLevel or 20, quality = self.defaultGemQuality or 0, enabled = true, enableGlobal1 = true, enableGlobal2 = true, count = 1, new = true } + gemInstance = { nameSpec = "", level = self.defaultGemLevel or 20, quality = self.defaultGemQuality or 0, enabled = true, enableGlobal1 = true, enableGlobal2 = true, count = 1, new = true, corruptLevel = 0, corrupted = false } self.displayGroup.gemList[index] = gemInstance slot.level:SetText(gemInstance.level) slot.quality:SetText(gemInstance.quality) slot.count:SetText(gemInstance.count) + local selIndex + if gemInstance.corruptLevel == 1 then + selIndex = 2 -- +1 to Gem Level + elseif gemInstance.corruptLevel == -1 then + selIndex = 4 -- -1 to Gem Level + elseif gemInstance.corrupted and gemInstance.corruptLevel == 0 then + selIndex = 3 -- Corrupted + else + selIndex = 1 -- Not Corrupted + end + slot.corruptLevel = selIndex end if not gemInstance.gemData.vaalGem then slot.enableGlobal1.state = true @@ -863,12 +939,23 @@ function SkillsTabClass:CreateGemSlot(index) slot.count = new("EditControl", {"LEFT",slot.enabled,"RIGHT"}, {18, 0, 60, 20}, nil, nil, "%D", 2, function(buf) local gemInstance = self.displayGroup.gemList[index] if not gemInstance then - gemInstance = { nameSpec = "", level = self.defaultGemLevel or 20, quality = self.defaultGemQuality or 0, enabled = true, enableGlobal1 = true, count = 1, new = true } + gemInstance = { nameSpec = "", level = self.defaultGemLevel or 20, quality = self.defaultGemQuality or 0, enabled = true, enableGlobal1 = true, count = 1, new = true, corruptLevel = 0, corrupted = false } self.displayGroup.gemList[index] = gemInstance slot.level:SetText(gemInstance.level) slot.quality:SetText(gemInstance.quality) slot.enabled.state = true slot.enableGlobal1.state = true + local selIndex + if gemInstance.corruptLevel == 1 then + selIndex = 2 -- +1 to Gem Level + elseif gemInstance.corruptLevel == -1 then + selIndex = 4 -- -1 to Gem Level + elseif gemInstance.corrupted and gemInstance.corruptLevel == 0 then + selIndex = 3 -- Corrupted + else + selIndex = 1 -- Not Corrupted + end + slot.corruptLevel = selIndex end gemInstance.count = tonumber(buf) or 1 slot.count.buf = tostring(gemInstance.count) @@ -900,6 +987,43 @@ function SkillsTabClass:CreateGemSlot(index) end self.controls["gemSlot"..index.."Count"] = slot.count + slot.corruptLevel = new("DropDownControl", {"LEFT",slot.count,"RIGHT"}, {18, 0, 140, 20}, corruptOption, function(indexSel, value) + local gemInstance = self.displayGroup.gemList[index] + if not gemInstance then + gemInstance = { nameSpec = "", level = 20, quality = 0, enabled = true, enableGlobal1 = true, count = 1, new = true, corruptLevel = 0, corrupted = false } + self.displayGroup.gemList[index] = gemInstance + slot.level:SetText(gemInstance.level) + slot.quality:SetText(gemInstance.quality) + slot.enabled.state = true + slot.enableGlobal1.state = true + end + gemInstance.corruptLevel = value.level + gemInstance.corrupted = (value.label ~= "Not Corrupted") + slot.corruptLevel.selIndex = indexSel + self:ProcessSocketGroup(self.displayGroup) + self:AddUndoState() + self.build.buildFlag = true + end) + + slot.corruptLevel.shown = function() + local gemInstance = self.displayGroup and self.displayGroup.gemList[index] + if gemInstance then + local grantedEffectList = gemInstance.gemData and gemInstance.gemData.grantedEffectList or { gemInstance.grantedEffect } + for index, grantedEffect in ipairs(grantedEffectList) do + if not grantedEffect.support and not grantedEffect.unsupported and (not grantedEffect.hasGlobalEffect or gemInstance["enableGlobal"..index]) then + return true + end + end + end + return false + end + + slot.corruptLevel.enabled = function() + return index <= #self.displayGroup.gemList + end + + self.controls["gemSlot"..index.."CorruptLevel"] = slot.corruptLevel + -- Parser/calculator error message slot.errMsg = new("LabelControl", {"LEFT",slot.count,"RIGHT"}, {2, 2, 0, 16}, function() local gemInstance = self.displayGroup and self.displayGroup.gemList[index] @@ -962,6 +1086,7 @@ function SkillsTabClass:UpdateGemSlots() slot.quality:SetText("") slot.enabled.state = false slot.count:SetText(1) + slot.corruptLevel.selIndex = 1 else slot.nameSpec.inactiveCol = self.displayGroup.gemList[slotIndex].color end @@ -1133,6 +1258,17 @@ function SkillsTabClass:SetDisplayGroup(socketGroup) self.gemSlots[index].enableGlobal1.state = gemInstance.enableGlobal1 self.gemSlots[index].enableGlobal2.state = gemInstance.enableGlobal2 self.gemSlots[index].count:SetText(gemInstance.count or 1) + local selIndex = 1 + if gemInstance.corruptLevel == 1 then + selIndex = 2 -- +1 to Gem Level + elseif gemInstance.corruptLevel == -1 then + selIndex = 4 -- -1 to Gem Level + elseif gemInstance.corrupted and gemInstance.corruptLevel == 0 then + selIndex = 3 -- Corrupted + else + selIndex = 1 -- Not Corrupted + end + self.gemSlots[index].corruptLevel.selIndex = selIndex end end end @@ -1159,13 +1295,14 @@ function SkillsTabClass:AddSocketGroupTooltip(tooltip, socketGroup) end tooltip:AddLine(16, "^7Active Skill #"..index..":") for _, skillEffect in ipairs(activeSkill.effectList) do - tooltip:AddLine(20, string.format("%s%s ^7%d%s/%d%s", + tooltip:AddLine(20, string.format("%s%s ^7%d%s/%d%s%s", data.skillColorMap[skillEffect.grantedEffect.color or skillEffect.gemData and skillEffect.gemData.grantedEffect.color], skillEffect.srcInstance.nameSpec or skillEffect.grantedEffect.name, skillEffect.srcInstance and skillEffect.srcInstance.level or skillEffect.level, (skillEffect.srcInstance and skillEffect.level > skillEffect.srcInstance.level) and colorCodes.MAGIC.."+"..(skillEffect.level - skillEffect.srcInstance.level).."^7" or "", skillEffect.srcInstance and skillEffect.srcInstance.quality or skillEffect.quality, - (skillEffect.srcInstance and skillEffect.quality > skillEffect.srcInstance.quality) and colorCodes.MAGIC.."+"..(skillEffect.quality - skillEffect.srcInstance.quality).."^7" or "" + (skillEffect.srcInstance and skillEffect.quality > skillEffect.srcInstance.quality) and colorCodes.MAGIC.."+"..(skillEffect.quality - skillEffect.srcInstance.quality).."^7" or "", + (skillEffect.srcInstance and skillEffect.srcInstance.corrupted == true) and (colorCodes.NEGATIVE.." C"..((skillEffect.srcInstance.corruptLevel or 0) ~= 0 and ((skillEffect.srcInstance.corruptLevel > 0 and "+" or "")..skillEffect.srcInstance.corruptLevel) or "")) or "" )) if skillEffect.srcInstance then gemShown[skillEffect.srcInstance] = true diff --git a/src/Modules/CalcActiveSkill.lua b/src/Modules/CalcActiveSkill.lua index dd999c834..8c9ac5650 100644 --- a/src/Modules/CalcActiveSkill.lua +++ b/src/Modules/CalcActiveSkill.lua @@ -636,6 +636,10 @@ function calcs.buildActiveSkillModList(env, activeSkill) -- Apply gem/quality modifiers from support gems skillModList:NewMod("GemLevel", "BASE", activeSkill.activeEffect.srcInstance and activeSkill.activeEffect.srcInstance.level or activeSkill.activeEffect.level, "Max Level") + if activeSkill.activeEffect.srcInstance and activeSkill.activeEffect.srcInstance.corruptLevel then + skillModList:NewMod("GemCorruptionLevel", "BASE", activeSkill.activeEffect.srcInstance.corruptLevel, "Corruption") + activeSkill.activeEffect.gemData.tags.corrupted = true + end for _, supportProperty in ipairs(skillModList:Tabulate("LIST", activeSkill.skillCfg, "SupportedGemProperty")) do local value = supportProperty.value if value.keyword == "grants_active_skill" and activeSkill.activeEffect.gemData and not activeSkill.activeEffect.gemData.tags.support then diff --git a/src/Modules/CalcPerform.lua b/src/Modules/CalcPerform.lua index cd5a2bc12..64afe63f4 100644 --- a/src/Modules/CalcPerform.lua +++ b/src/Modules/CalcPerform.lua @@ -3231,9 +3231,10 @@ function calcs.perform(env, skipEHP) local baseLevel = mainSkill.skillModList:Sum("BASE", mainSkill.skillCfg, "GemLevel") local totalItemLevel = mainSkill.skillModList:Sum("BASE", mainSkill.skillCfg, "GemItemLevel") local totalSupportLevel = mainSkill.skillModList:Sum("BASE", mainSkill.skillCfg, "GemSupportLevel") + local totalCorruptionLevel = mainSkill.skillModList:Sum("BASE", mainSkill.skillCfg, "GemCorruptionLevel") output.GemHasLevel = true - output.GemLevel = baseLevel + totalSupportLevel + totalItemLevel + output.GemLevel = baseLevel + totalSupportLevel + totalItemLevel + totalCorruptionLevel if env.player.breakdown then env.player.breakdown.GemLevel = {} @@ -3244,6 +3245,11 @@ function calcs.perform(env, skipEHP) if totalItemLevel > 0 then t_insert(env.player.breakdown.GemLevel, s_format("+ %d ^8(level from items)", totalItemLevel)) end + if totalCorruptionLevel > 0 then + t_insert(env.player.breakdown.GemLevel, s_format("+ %d ^8(level from corruption)", totalCorruptionLevel)) + elseif totalCorruptionLevel < 0 then + t_insert(env.player.breakdown.GemLevel, s_format("%d ^8(level from corruption)", totalCorruptionLevel)) + end t_insert(env.player.breakdown.GemLevel, s_format("= %d", output.GemLevel)) end end diff --git a/src/Modules/CalcSections.lua b/src/Modules/CalcSections.lua index ab1596c29..92229d165 100644 --- a/src/Modules/CalcSections.lua +++ b/src/Modules/CalcSections.lua @@ -623,7 +623,7 @@ return { } } } }, { 1, "SkillTypeStats", 1, colorCodes.OFFENCE, {{ defaultCollapsed = false, label = "Skill type-specific Stats", data = { - { label = "Gem Level", haveOutput = "GemHasLevel", { format = "{0:output:GemLevel}", { breakdown = "GemLevel" }, { modName = { "GemLevel" }, cfg = "skill" },{ modName = { "GemSupportLevel" }, cfg = "skill" }, { modName = { "GemItemLevel" }, cfg = "skill" }, }, }, + { label = "Gem Level", haveOutput = "GemHasLevel", { format = "{0:output:GemLevel}", { breakdown = "GemLevel" }, { modName = { "GemLevel" }, cfg = "skill" },{ modName = { "GemSupportLevel" }, cfg = "skill" }, { modName = { "GemItemLevel" }, cfg = "skill" }, { modName = { "GemCorruptionLevel" }, cfg = "skill" } }, }, { label = "Spirit Cost", color = colorCodes.SPIRIT, haveOutput = "SpiritHasCost", { format = "{0:output:SpiritCost}", { breakdown = "SpiritCost" }, { modName = { "SpiritCost", "Cost", "SpiritCostNoMult" }, cfg = "skill" }, }, }, { label = "Spirit % Cost", color = colorCodes.SPIRIT, haveOutput = "SpiritPercentHasCost", { format = "{0:output:SpiritPercentCost}", { breakdown = "SpiritPercentCost" }, { modName = { "SpiritCost", "Cost", "SpiritCostNoMult" }, cfg = "skill" }, }, }, { label = "Mana Cost", color = colorCodes.MANA, haveOutput = "ManaHasCost", { format = "{0:output:ManaCost}", { breakdown = "ManaCost" }, { modName = { "ManaCost", "Cost", "ManaCostNoMult" }, cfg = "skill" }, }, }, diff --git a/src/Modules/CalcSetup.lua b/src/Modules/CalcSetup.lua index 3cdb977be..680380111 100644 --- a/src/Modules/CalcSetup.lua +++ b/src/Modules/CalcSetup.lua @@ -1653,9 +1653,14 @@ function calcs.initEnv(build, mode, override, specEnv) level = gemInstance.level, quality = gemInstance.quality, qualityId = gemInstance.qualityId, + corrupted = gemInstance.corrupted, + corruptLevel = gemInstance.corruptLevel, srcInstance = gemInstance, gemData = gemInstance.gemData, } + if activeEffect.corruptLevel then + activeEffect.level = activeEffect.level + activeEffect.corruptLevel + end if env.mode == "CALCS" then activeEffect.statSetCalcs = { index = gemInstance.statSetCalcs and gemInstance.statSetCalcs[grantedEffect.id] or 1} else From 757016b6730b0092b5f1d0c6b642f5e0f9ac0b82 Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Mon, 19 Jan 2026 23:30:55 -0600 Subject: [PATCH 03/10] Fix import missing corruptLevel --- src/Classes/ImportTab.lua | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Classes/ImportTab.lua b/src/Classes/ImportTab.lua index f40a98a84..25c0a6f31 100644 --- a/src/Classes/ImportTab.lua +++ b/src/Classes/ImportTab.lua @@ -833,6 +833,8 @@ function ImportTabClass:ImportItemsAndSkills(charData) end if skillData.properties[_ + 2] and skillData.properties[_ + 2].values[1][1]:match("(-?%d+) Level[s]? from Corruption") then gemInstance.corruptLevel = tonumber(skillData.properties[_ + 2].values[1][1]:match("(-?%d+) Level[s]? from Corruption")) + else + gemInstance.corruptLevel = 0 end elseif escapeGGGString(property.name) == "Quality" then gemInstance.quality = tonumber(property.values[1][1]:match("%d+")) From 140ffb0ac973a03d47a65a5714ef3a3efa58c6bf Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Tue, 20 Jan 2026 01:23:35 -0600 Subject: [PATCH 04/10] Some cleanup and tooltip fixes --- src/Classes/GemSelectControl.lua | 14 ++--- src/Classes/SkillsTab.lua | 96 +++++++------------------------- 2 files changed, 26 insertions(+), 84 deletions(-) diff --git a/src/Classes/GemSelectControl.lua b/src/Classes/GemSelectControl.lua index 41efb391f..80d686e17 100644 --- a/src/Classes/GemSelectControl.lua +++ b/src/Classes/GemSelectControl.lua @@ -609,9 +609,14 @@ function GemSelectClass:AddGrantedEffectInfo(gemInstance, grantedEffect, addReq) (displayInstance.level - gemInstance.level - displayInstance.corruptLevel > 0) then self.tooltip:AddLine(fontSizeBig, string.format("^x7F7F7FLevel: ^7" .. colorCodes.MAGIC .. totalLevel), "FONTIN SC") - self.tooltip:AddLine(fontSizeBig, "^7" .. gemInstance.level .. " Levels from Gem", "FONTIN SC") + self.tooltip:AddLine(fontSizeBig, "^7" .. gemInstance.level .. " Levels from Gem" .. ((gemInstance.level >= gemInstance.gemData.naturalMaxLevel) and " (Max)" or ""), "FONTIN SC") else - self.tooltip:AddLine(fontSizeBig, string.format("^x7F7F7FLevel: ^7" .. totalLevel), "FONTIN SC") + self.tooltip:AddLine(fontSizeBig, string.format("^x7F7F7FLevel: ^7" .. totalLevel .. ((gemInstance.level >= gemInstance.gemData.naturalMaxLevel) and " (Max)" or "")), "FONTIN SC") + end + if displayInstance.corruptLevel > 0 then + self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.corruptLevel .. " Level from Corruption", "FONTIN SC") + elseif displayInstance.corruptLevel < 0 then + self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. displayInstance.corruptLevel .. " Level from Corruption", "FONTIN SC") end if displayInstance.gemPropertyInfo and displayInstance.gemPropertyInfo[1].value.value > 0 then self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.gemPropertyInfo[1].value.value .. " Levels from Global Modifiers", "FONTIN SC") @@ -621,11 +626,6 @@ function GemSelectClass:AddGrantedEffectInfo(gemInstance, grantedEffect, addReq) elseif displayInstance.level - gemInstance.level - displayInstance.corruptLevel > 0 then self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.level - gemInstance.level - displayInstance.corruptLevel .. " Levels from Supports", "FONTIN SC") end - if displayInstance.corruptLevel > 0 then - self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.corruptLevel .. " Level from Corruption", "FONTIN SC") - elseif displayInstance.corruptLevel < 0 then - self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. displayInstance.corruptLevel .. " Level from Corruption", "FONTIN SC") - end end if grantedEffect.support then if grantedEffectLevel.manaMultiplier and grantedEffectLevel.reservationMultiplier and grantedEffectLevel.manaMultiplier == grantedEffectLevel.reservationMultiplier then diff --git a/src/Classes/SkillsTab.lua b/src/Classes/SkillsTab.lua index 2b240dc3c..d97b019d4 100644 --- a/src/Classes/SkillsTab.lua +++ b/src/Classes/SkillsTab.lua @@ -272,6 +272,18 @@ will automatically apply to the skill.]] self.controls.gemCountHeader = new("LabelControl", {"BOTTOMLEFT", self.gemSlots[1].count, "TOPLEFT"}, {8, -2, 0, 16}, "^7Count:") end) +function SkillsTabClass:GetCorruptIndex(gemInstance) + if gemInstance.corruptLevel == 1 then + return 2 -- +1 to Gem Level + elseif gemInstance.corruptLevel == -1 then + return 4 -- -1 to Gem Level + elseif gemInstance.corrupted then + return 3 -- Corrupted + else + return 1 -- Not Corrupted + end +end + function SkillsTabClass:LoadSkill(node, skillSetId) if node.elem ~= "Skill" then return @@ -651,17 +663,7 @@ function SkillsTabClass:CreateGemSlot(index) self.gemSlots[index2].enableGlobal1.state = gemInstance.enableGlobal1 self.gemSlots[index2].enableGlobal2.state = gemInstance.enableGlobal2 self.gemSlots[index2].count:SetText(gemInstance.count or 1) - local selIndex - if gemInstance.corruptLevel == 1 then - selIndex = 2 -- +1 to Gem Level - elseif gemInstance.corruptLevel == -1 then - selIndex = 4 -- -1 to Gem Level - elseif gemInstance.corrupted then - selIndex = 3 -- Corrupted - else - selIndex = 1 -- Not Corrupted - end - self.gemSlots[index2].corruptLevel.selIndex = selIndex + self.gemSlots[index2].corruptLevel.selIndex = self:GetCorruptIndex(gemInstance) end self:AddUndoState() self.build.buildFlag = true @@ -708,17 +710,7 @@ function SkillsTabClass:CreateGemSlot(index) self.displayGroup.gemList[index] = gemInstance slot.level:SetText(gemInstance.level) slot.quality:SetText(gemInstance.quality) - local selIndex - if gemInstance.corruptLevel == 1 then - selIndex = 2 -- +1 to Gem Level - elseif gemInstance.corruptLevel == -1 then - selIndex = 4 -- -1 to Gem Level - elseif gemInstance.corrupted and gemInstance.corruptLevel == 0 then - selIndex = 3 -- Corrupted - else - selIndex = 1 -- Not Corrupted - end - slot.corruptLevel.selIndex = selIndex + slot.corruptLevel.selIndex = self:GetCorruptIndex(gemInstance) slot.enabled.state = true slot.enableGlobal1.state = true slot.enableGlobal2.state = true @@ -756,17 +748,7 @@ function SkillsTabClass:CreateGemSlot(index) slot.enabled.state = true slot.enableGlobal1.state = true slot.count:SetText(gemInstance.count) - local selIndex - if gemInstance.corruptLevel == 1 then - selIndex = 2 -- +1 to Gem Level - elseif gemInstance.corruptLevel == -1 then - selIndex = 4 -- -1 to Gem Level - elseif gemInstance.corrupted and gemInstance.corruptLevel == 0 then - selIndex = 3 -- Corrupted - else - selIndex = 1 -- Not Corrupted - end - slot.corruptLevel = selIndex + slot.corruptLevel = self:GetCorruptIndex(gemInstance) end gemInstance.level = tonumber(buf) or self.displayGroup.gemList[index].naturalMaxLevel or self:ProcessGemLevel(gemInstance.gemData) or 20 self:ProcessSocketGroup(self.displayGroup) @@ -789,17 +771,7 @@ function SkillsTabClass:CreateGemSlot(index) slot.enabled.state = true slot.enableGlobal1.state = true slot.count:SetText(gemInstance.count) - local selIndex - if gemInstance.corruptLevel == 1 then - selIndex = 2 -- +1 to Gem Level - elseif gemInstance.corruptLevel == -1 then - selIndex = 4 -- -1 to Gem Level - elseif gemInstance.corrupted and gemInstance.corruptLevel == 0 then - selIndex = 3 -- Corrupted - else - selIndex = 1 -- Not Corrupted - end - slot.corruptLevel = selIndex + slot.corruptLevel = self:GetCorruptIndex(gemInstance) end gemInstance.quality = tonumber(buf) or self.defaultGemQuality or 0 self:ProcessSocketGroup(self.displayGroup) @@ -894,17 +866,7 @@ function SkillsTabClass:CreateGemSlot(index) slot.level:SetText(gemInstance.level) slot.quality:SetText(gemInstance.quality) slot.count:SetText(gemInstance.count) - local selIndex - if gemInstance.corruptLevel == 1 then - selIndex = 2 -- +1 to Gem Level - elseif gemInstance.corruptLevel == -1 then - selIndex = 4 -- -1 to Gem Level - elseif gemInstance.corrupted and gemInstance.corruptLevel == 0 then - selIndex = 3 -- Corrupted - else - selIndex = 1 -- Not Corrupted - end - slot.corruptLevel = selIndex + slot.corruptLevel = self:GetCorruptIndex(gemInstance) end if not gemInstance.gemData.vaalGem then slot.enableGlobal1.state = true @@ -945,17 +907,7 @@ function SkillsTabClass:CreateGemSlot(index) slot.quality:SetText(gemInstance.quality) slot.enabled.state = true slot.enableGlobal1.state = true - local selIndex - if gemInstance.corruptLevel == 1 then - selIndex = 2 -- +1 to Gem Level - elseif gemInstance.corruptLevel == -1 then - selIndex = 4 -- -1 to Gem Level - elseif gemInstance.corrupted and gemInstance.corruptLevel == 0 then - selIndex = 3 -- Corrupted - else - selIndex = 1 -- Not Corrupted - end - slot.corruptLevel = selIndex + slot.corruptLevel = self:GetCorruptIndex(gemInstance) end gemInstance.count = tonumber(buf) or 1 slot.count.buf = tostring(gemInstance.count) @@ -1258,17 +1210,7 @@ function SkillsTabClass:SetDisplayGroup(socketGroup) self.gemSlots[index].enableGlobal1.state = gemInstance.enableGlobal1 self.gemSlots[index].enableGlobal2.state = gemInstance.enableGlobal2 self.gemSlots[index].count:SetText(gemInstance.count or 1) - local selIndex = 1 - if gemInstance.corruptLevel == 1 then - selIndex = 2 -- +1 to Gem Level - elseif gemInstance.corruptLevel == -1 then - selIndex = 4 -- -1 to Gem Level - elseif gemInstance.corrupted and gemInstance.corruptLevel == 0 then - selIndex = 3 -- Corrupted - else - selIndex = 1 -- Not Corrupted - end - self.gemSlots[index].corruptLevel.selIndex = selIndex + self.gemSlots[index].corruptLevel.selIndex = self:GetCorruptIndex(gemInstance) end end end From aa0539a0d434b18820344e7ab112de2e941b20b0 Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Tue, 20 Jan 2026 01:41:33 -0600 Subject: [PATCH 05/10] Fix corrupted check --- src/Classes/SkillsTab.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Classes/SkillsTab.lua b/src/Classes/SkillsTab.lua index d97b019d4..4a4523d87 100644 --- a/src/Classes/SkillsTab.lua +++ b/src/Classes/SkillsTab.lua @@ -277,7 +277,7 @@ function SkillsTabClass:GetCorruptIndex(gemInstance) return 2 -- +1 to Gem Level elseif gemInstance.corruptLevel == -1 then return 4 -- -1 to Gem Level - elseif gemInstance.corrupted then + elseif gemInstance.corrupted == true then return 3 -- Corrupted else return 1 -- Not Corrupted @@ -353,7 +353,7 @@ function SkillsTabClass:LoadSkill(node, skillSetId) gemInstance.skillMinionItemSetCalcs = tonumber(child.attrib.skillMinionItemSetCalcs) gemInstance.skillMinionSkill = tonumber(child.attrib.skillMinionSkill) gemInstance.skillMinionSkillCalcs = tonumber(child.attrib.skillMinionSkillCalcs) - gemInstance.corrupted = child.attrib.corrupted + gemInstance.corrupted = child.attrib.corrupted == "true" gemInstance.corruptLevel = tonumber(child.attrib.corruptLevel) gemInstance.statSet = { } gemInstance.statSetCalcs = { } From b0c73e6b202315e65f28da673ac9098239711dd6 Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Wed, 21 Jan 2026 18:00:38 -0600 Subject: [PATCH 06/10] Fix pasting corrupted socket group --- src/Classes/SkillsTab.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Classes/SkillsTab.lua b/src/Classes/SkillsTab.lua index 4a4523d87..e89bbecd4 100644 --- a/src/Classes/SkillsTab.lua +++ b/src/Classes/SkillsTab.lua @@ -623,13 +623,17 @@ function SkillsTabClass:PasteSocketGroup(testInput) if slot then newGroup.slot = slot end - for nameSpec, level, quality, state, count in skillText:gmatch("([ %a']+) (%d+)/(%d+) ?(%a*) (%d+)") do + for nameSpec, level, quality, state, count, cFlag, cDelta in + skillText:gmatch("([ %a']+) (%d+)/(%d+) ?(%a*) (%d+) ?(C?)([+-]?%d*)") + do t_insert(newGroup.gemList, { nameSpec = nameSpec, level = tonumber(level) or 20, quality = tonumber(quality) or 0, enabled = state ~= "DISABLED", count = tonumber(count) or 1, + corrupted = cFlag == "C", + corruptLevel = tonumber(cDelta) or 0, enableGlobal1 = true, enableGlobal2 = true }) From e4253270d28a896d53e9fb349548a197a8eb9ae7 Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Wed, 21 Jan 2026 18:38:22 -0600 Subject: [PATCH 07/10] Fix paste for companion and spectre --- src/Classes/SkillsTab.lua | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/src/Classes/SkillsTab.lua b/src/Classes/SkillsTab.lua index e89bbecd4..f0b10ec65 100644 --- a/src/Classes/SkillsTab.lua +++ b/src/Classes/SkillsTab.lua @@ -623,9 +623,38 @@ function SkillsTabClass:PasteSocketGroup(testInput) if slot then newGroup.slot = slot end - for nameSpec, level, quality, state, count, cFlag, cDelta in - skillText:gmatch("([ %a']+) (%d+)/(%d+) ?(%a*) (%d+) ?(C?)([+-]?%d*)") + for nameSpec, level, quality, state, count, cFlag, cLevel in + skillText:gmatch("([ %a':]+) (%d+)/(%d+) ?(%a*) (%d+) ?(C?)([+-]?%d*)") do + local skillMinion = nil + local skillMinionCalcs = nil + local minionName = nil + local minionList = nil + + if nameSpec:find("Spectre") then + minionName = nameSpec:match(": (.+)") + nameSpec = "Summon Spectre" + minionList = self.build.spectreList + elseif nameSpec:find("Companion") then + minionName = nameSpec:match(": (.+)") + nameSpec = "Tamed Companion" + minionList = self.build.beastList + end + + -- Search for the minion if we found a spectre or companion + if minionName then + for id, spectre in pairs(data.spectres) do + if spectre.name == minionName then + if not isValueInArray(minionList, id) then + t_insert(minionList, id) + end + skillMinion = id + skillMinionCalcs = id + break + end + end + end + t_insert(newGroup.gemList, { nameSpec = nameSpec, level = tonumber(level) or 20, @@ -633,9 +662,11 @@ function SkillsTabClass:PasteSocketGroup(testInput) enabled = state ~= "DISABLED", count = tonumber(count) or 1, corrupted = cFlag == "C", - corruptLevel = tonumber(cDelta) or 0, + corruptLevel = tonumber(cLevel) or 0, enableGlobal1 = true, - enableGlobal2 = true + enableGlobal2 = true, + skillMinion = skillMinion, + skillMinionCalcs = skillMinionCalcs }) end if #newGroup.gemList > 0 then From 657586d511ff295ba6f94efef41c67567b7614ca Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Mon, 2 Feb 2026 01:04:39 -0600 Subject: [PATCH 08/10] Set corruption dropdown with default gem level dropdown --- src/Classes/GemSelectControl.lua | 18 ++++++++++-------- src/Classes/SkillsTab.lua | 23 +++++++++++++++++------ 2 files changed, 27 insertions(+), 14 deletions(-) diff --git a/src/Classes/GemSelectControl.lua b/src/Classes/GemSelectControl.lua index 80d686e17..d0ad7a336 100644 --- a/src/Classes/GemSelectControl.lua +++ b/src/Classes/GemSelectControl.lua @@ -62,7 +62,9 @@ function GemSelectClass:CalcOutputWithThisGem(calcFunc, gemData, useFullDPS) enableGlobal2 = true, gemId = gemData.id, nameSpec = gemData.name, - skillId = gemData.grantedEffectId + skillId = gemData.grantedEffectId, + corrupted = self.skillsTab.defaultCorruptionState, + corruptLevel = self.skillsTab.defaultCorruptionLevel, } end @@ -463,8 +465,8 @@ function GemSelectClass:Draw(viewPort, noTooltip) skillId = gemData.grantedEffectId, displayEffect = nil, gemData = gemData, - corruptLevel = 0, - corrupted = false, + corruptLevel = self.skillsTab.defaultCorruptionLevel, + corrupted = self.skillsTab.defaultCorruptionState == true, } self:AddGemTooltip(gemInstance) self.tooltip:AddSeparator(10) @@ -603,7 +605,7 @@ function GemSelectClass:AddGrantedEffectInfo(gemInstance, grantedEffect, addReq) end if addReq and not grantedEffect.support then local totalLevel - totalLevel = displayInstance.level + totalLevel = m_max(displayInstance.level, (gemInstance.level + gemInstance.corruptLevel)) -- Needed for tooltip comparison for dropdown gems. Otherwise they only show level 20 when corrupted. if displayInstance.corruptLevel ~= 0 or (displayInstance.gemPropertyInfo and displayInstance.gemPropertyInfo[1].value.value > 0 ) or (displayInstance.level - gemInstance.level - displayInstance.corruptLevel > 0) @@ -620,11 +622,11 @@ function GemSelectClass:AddGrantedEffectInfo(gemInstance, grantedEffect, addReq) end if displayInstance.gemPropertyInfo and displayInstance.gemPropertyInfo[1].value.value > 0 then self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.gemPropertyInfo[1].value.value .. " Levels from Global Modifiers", "FONTIN SC") - if displayInstance.level - gemInstance.level - displayInstance.corruptLevel - displayInstance.gemPropertyInfo[1].value.value > 0 then - self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.level - gemInstance.level - displayInstance.corruptLevel - displayInstance.gemPropertyInfo[1].value.value .. " Levels from Supports", "FONTIN SC") + if totalLevel - gemInstance.level - displayInstance.corruptLevel*2 - displayInstance.gemPropertyInfo[1].value.value > 0 then + self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. totalLevel - gemInstance.level - displayInstance.corruptLevel - displayInstance.gemPropertyInfo[1].value.value .. " Levels from Supports", "FONTIN SC") end - elseif displayInstance.level - gemInstance.level - displayInstance.corruptLevel > 0 then - self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. displayInstance.level - gemInstance.level - displayInstance.corruptLevel .. " Levels from Supports", "FONTIN SC") + elseif totalLevel - gemInstance.level - displayInstance.corruptLevel > 0 then + self.tooltip:AddLine(fontSizeBig, colorCodes.MAGIC .. "+" .. totalLevel - gemInstance.level - displayInstance.corruptLevel .. " Levels from Supports", "FONTIN SC") end end if grantedEffect.support then diff --git a/src/Classes/SkillsTab.lua b/src/Classes/SkillsTab.lua index f0b10ec65..395077552 100644 --- a/src/Classes/SkillsTab.lua +++ b/src/Classes/SkillsTab.lua @@ -39,11 +39,11 @@ local defaultGemLevelList = { Awakened gems default to their highest valid non-corrupted gem level.]], gemLevel = "corruptedMaximum", }, - { - label = "Awakened Maximum", - description = "All gems default to their highest valid corrupted gem level.", - gemLevel = "awakenedMaximum", - }, + --{ + -- label = "Awakened Maximum", + -- description = "All gems default to their highest valid corrupted gem level.", + -- gemLevel = "awakenedMaximum", + --}, { label = "Match Character Level", description = [[All gems default to their highest valid non-corrupted gem level that your character meets the level requirement for. @@ -98,6 +98,8 @@ local SkillsTabClass = newClass("SkillsTab", "UndoHandler", "ControlHost", "Cont self.showSupportGemTypes = "ALL" self.defaultGemLevel = "normalMaximum" self.defaultGemQuality = main.defaultGemQuality + self.defaultCorruptionLevel = 0 + self.defaultCorruptionState = false -- Set selector self.controls.setSelect = new("DropDownControl", { "TOPLEFT", self, "TOPLEFT" }, { 76, 8, 210, 20 }, nil, function(index, value) @@ -764,6 +766,11 @@ function SkillsTabClass:CreateGemSlot(index) gemInstance.naturalMaxLevel = gemInstance.level -- Gem changed, update the list and default the quality id slot.level:SetText(gemInstance.level) + if self.defaultCorruptionLevel == 1 then + slot.corruptLevel.selIndex = 2 + gemInstance.corrupted = true + gemInstance.corruptLevel = 1 + end slot.count:SetText(gemInstance.count or 1) if addUndo then self:AddUndoState() @@ -1120,9 +1127,13 @@ function SkillsTabClass:ProcessGemLevel(gemData) if grantedEffect.plusVersionOf then return naturalMaxLevel else - return naturalMaxLevel + 1 + self.defaultCorruptionLevel = 1 + self.defaultCorruptionState = true + return naturalMaxLevel end elseif self.defaultGemLevel == "normalMaximum" then + self.defaultCorruptionLevel = 0 + self.defaultCorruptionState = false return naturalMaxLevel else -- self.defaultGemLevel == "characterLevel" local maxGemLevel = naturalMaxLevel From 97af70bb8275e2f92eca4f0980362230b369b7d6 Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Tue, 3 Feb 2026 02:55:30 -0600 Subject: [PATCH 09/10] Support gem sorting --- src/Classes/GemSelectControl.lua | 6 +++--- src/Classes/SkillsTab.lua | 4 ++-- src/Data/Skills/sup_dex.lua | 3 --- src/Data/Skills/sup_int.lua | 7 ------- src/Data/Skills/sup_str.lua | 11 ----------- src/Export/Scripts/skills.lua | 12 +++++------- 6 files changed, 10 insertions(+), 33 deletions(-) diff --git a/src/Classes/GemSelectControl.lua b/src/Classes/GemSelectControl.lua index d0ad7a336..f9cbbbf6f 100644 --- a/src/Classes/GemSelectControl.lua +++ b/src/Classes/GemSelectControl.lua @@ -92,7 +92,7 @@ end function GemSelectClass:PopulateGemList() wipeTable(self.gems) local showAll = self.skillsTab.showSupportGemTypes == "ALL" - local showAwakened = self.skillsTab.showSupportGemTypes == "AWAKENED" + local showLineage = self.skillsTab.showSupportGemTypes == "LINEAGE" local showNormal = self.skillsTab.showSupportGemTypes == "NORMAL" local matchLevel = self.skillsTab.defaultGemLevel == "characterLevel" local characterLevel = self.skillsTab.build and self.skillsTab.build.characterLevel or 1 @@ -115,8 +115,8 @@ function GemSelectClass:FilterSupport(gemId, gemData) local showSupportTypes = self.skillsTab.showSupportGemTypes return (not gemData.grantedEffect.support or showSupportTypes == "ALL" - or (showSupportTypes == "NORMAL" and not gemData.grantedEffect.plusVersionOf) - or (showSupportTypes == "AWAKENED" and gemData.grantedEffect.plusVersionOf)) + or (showSupportTypes == "NORMAL" and not gemData.grantedEffect.isLineage) + or (showSupportTypes == "LINEAGE" and gemData.grantedEffect.isLineage)) end function GemSelectClass:BuildList(buf) diff --git a/src/Classes/SkillsTab.lua b/src/Classes/SkillsTab.lua index 395077552..7b1673cb1 100644 --- a/src/Classes/SkillsTab.lua +++ b/src/Classes/SkillsTab.lua @@ -54,8 +54,8 @@ This hides gems with a minimum level requirement above your character level, pre local showSupportGemTypeList = { { label = "All", show = "ALL" }, - { label = "Non-Awakened", show = "NORMAL" }, - { label = "Awakened", show = "AWAKENED" }, + { label = "Lineage", show = "LINEAGE" }, + { label = "Non-Lineage", show = "NORMAL" }, } local corruptOption = { diff --git a/src/Data/Skills/sup_dex.lua b/src/Data/Skills/sup_dex.lua index 08725bc19..ce241d3c7 100644 --- a/src/Data/Skills/sup_dex.lua +++ b/src/Data/Skills/sup_dex.lua @@ -4234,7 +4234,6 @@ skills["SupportPrecisionPlayer"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Precision",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 10, }, }, @@ -4270,7 +4269,6 @@ skills["SupportPrecisionPlayerTwo"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Precision",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 20, }, }, @@ -5800,7 +5798,6 @@ skills["SupportWarmbloodedPlayer"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "WarmBlooded",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 15, }, }, diff --git a/src/Data/Skills/sup_int.lua b/src/Data/Skills/sup_int.lua index f81bda85e..7feab8d9b 100644 --- a/src/Data/Skills/sup_int.lua +++ b/src/Data/Skills/sup_int.lua @@ -1821,7 +1821,6 @@ skills["SupportClarityPlayer"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Clarity",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 10, }, }, @@ -1857,7 +1856,6 @@ skills["SupportClarityPlayerTwo"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Clarity",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 20, }, }, @@ -6244,7 +6242,6 @@ skills["SupportMysticismPlayer"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Mysticism",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 15, }, }, @@ -6280,7 +6277,6 @@ skills["SupportMysticismPlayerTwo"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Mysticism",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 30, }, }, @@ -7375,7 +7371,6 @@ skills["SupportStrongHeartedPlayer"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "StrongHearted",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 15, }, }, @@ -7622,7 +7617,6 @@ skills["SupportUpwellingPlayer"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Upwellling",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 15, }, }, @@ -7653,7 +7647,6 @@ skills["SupportUpwellingPlayerTwo"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Upwellling",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 30, }, }, diff --git a/src/Data/Skills/sup_str.lua b/src/Data/Skills/sup_str.lua index 2ae5ffcd2..fb2dba752 100644 --- a/src/Data/Skills/sup_str.lua +++ b/src/Data/Skills/sup_str.lua @@ -1282,7 +1282,6 @@ skills["SupportCannibalismPlayer"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Cannibalism",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 15, }, }, @@ -1318,7 +1317,6 @@ skills["SupportCannibalismPlayerTwo"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Cannibalism",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 30, }, }, @@ -1592,7 +1590,6 @@ skills["SupportCoolheadedPlayer"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "CoolHeaded",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 15, }, }, @@ -2117,7 +2114,6 @@ skills["SupportDirestrikePlayer"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Direstrike",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 20, }, }, @@ -2153,7 +2149,6 @@ skills["SupportDirestrikePlayerTwo"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Direstrike",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 40, }, }, @@ -3947,7 +3942,6 @@ skills["SupportHerbalismPlayer"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Herbalism",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 15, }, }, @@ -3983,7 +3977,6 @@ skills["SupportHerbalismPlayerTwo"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Herbalism",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 30, }, }, @@ -6989,7 +6982,6 @@ skills["SupportThornskinPlayer"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Thornskin",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 20, }, }, @@ -7025,7 +7017,6 @@ skills["SupportThornskinPlayerTwo"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Thornskin",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 40, }, }, @@ -7699,7 +7690,6 @@ skills["SupportVitalityPlayer"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Vitality",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 20, }, }, @@ -7736,7 +7726,6 @@ skills["SupportVitalityPlayerTwo"] = { addSkillTypes = { }, excludeSkillTypes = { }, gemFamily = { "Vitality",}, - isLineage = true, levels = { [1] = { levelRequirement = 0, spiritReservationFlat = 40, }, }, diff --git a/src/Export/Scripts/skills.lua b/src/Export/Scripts/skills.lua index a2e315751..4c84fb7eb 100644 --- a/src/Export/Scripts/skills.lua +++ b/src/Export/Scripts/skills.lua @@ -335,15 +335,13 @@ directiveTable.skill = function(state, args, out) end out:write('},\n') end - if supportGem.Lineage then + if supportGem.Lineage and supportGem.FlavourText then out:write('\tisLineage = true,\n') - if supportGem.FlavourText then - out:write('\tflavourText = {') - for _, line in ipairs(cleanAndSplit(supportGem.FlavourText.Text)) do - out:write('"', line, '", ') - end - out:write('},\n') + out:write('\tflavourText = {') + for _, line in ipairs(cleanAndSplit(supportGem.FlavourText.Text)) do + out:write('"', line, '", ') end + out:write('},\n') end end if skill.isTrigger then From fcb9e72c29a43189d2357e7007745f5abbaca48a Mon Sep 17 00:00:00 2001 From: Blitz54 Date: Tue, 3 Feb 2026 03:09:42 -0600 Subject: [PATCH 10/10] Fix Oisins Oath letter --- src/Data/Gems.lua | 2 +- src/Data/Skills/sup_int.lua | 4 ++-- src/Export/Scripts/skills.lua | 4 +++- src/Modules/Common.lua | 1 + 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/Data/Gems.lua b/src/Data/Gems.lua index 0397643fe..5cd4e9def 100644 --- a/src/Data/Gems.lua +++ b/src/Data/Gems.lua @@ -608,7 +608,7 @@ return { naturalMaxLevel = 1, }, ["Metadata/Items/Gems/SkillGemOisinsOathSupport"] = { - name = "Oisín's Oath", + name = "Oisin's Oath", gameId = "Metadata/Items/Gems/SupportGemOisinsOath", variantId = "OisinsOathSupport", grantedEffectId = "SupportOisinsOathPlayer", diff --git a/src/Data/Skills/sup_int.lua b/src/Data/Skills/sup_int.lua index 7feab8d9b..68da0e949 100644 --- a/src/Data/Skills/sup_int.lua +++ b/src/Data/Skills/sup_int.lua @@ -6335,7 +6335,7 @@ skills["SupportNadirPlayer"] = { } } skills["SupportOisinsOathPlayer"] = { - name = "Oisín's Oath", + name = "Oisin's Oath", description = "Supports Skills which Hit enemies, causing their Mana Leech to recover based on Elemental damage instead of Physical damage.", color = 3, support = true, @@ -6350,7 +6350,7 @@ skills["SupportOisinsOathPlayer"] = { }, statSets = { [1] = { - label = "Oisín's Oath", + label = "Oisin's Oath", incrementalEffectiveness = 0.054999999701977, statDescriptionScope = "gem_stat_descriptions", statMap = { diff --git a/src/Export/Scripts/skills.lua b/src/Export/Scripts/skills.lua index 4c84fb7eb..04b7c2d2f 100644 --- a/src/Export/Scripts/skills.lua +++ b/src/Export/Scripts/skills.lua @@ -171,6 +171,7 @@ directiveTable.skill = function(state, args, out) gems[gemEffect.Id] = true if granted.IsSupport then skill.displayName = fullNameGems[skillGem.BaseItemType.Id] and skillGem.BaseItemType.Name or skillGem.BaseItemType.Name:gsub(" Support", "") + skill.displayName = sanitiseText(skill.displayName) out:write('\tname = "', skill.displayName, '",\n') if #gemEffect.Description > 0 then out:write('\tdescription = "', escapeGGGString(gemEffect.Description:gsub('"','\\"'):gsub('\r',''):gsub('\n','\\n')), '",\n') @@ -464,6 +465,7 @@ directiveTable.set = function(state, args, out) local grantedEffectStatSet = copyTableSafe(originalGrantedEffectStatSet, false, true) local statsPerLevel = copyTableSafe(dat("GrantedEffectStatSetsPerLevel"):GetRowList("GrantedEffectStatSets", originalGrantedEffectStatSet), false, true) local label = grantedEffectStatSet.LabelType and grantedEffectStatSet.LabelType.Label or state.skill.displayName + label = sanitiseText(label) local set = { } local skill = state.skill if next(skill.sets) == nil then @@ -889,7 +891,7 @@ for skillGem in dat("SkillGems"):Rows() do for _, gemEffect in ipairs(skillGem.GemEffects) do if gems[gemEffect.Id] then out:write('\t["', "Metadata/Items/Gems/SkillGem" .. gemEffect.Id, '"] = {\n') - out:write('\t\tname = "', fullNameGems[skillGem.BaseItemType.Id] and skillGem.BaseItemType.Name or trueGemNames[gemEffect.Id] or skillGem.BaseItemType.Name:gsub(" Support",""), '",\n') + out:write('\t\tname = "', sanitiseText(fullNameGems[skillGem.BaseItemType.Id] and skillGem.BaseItemType.Name or trueGemNames[gemEffect.Id] or skillGem.BaseItemType.Name:gsub(" Support","")), '",\n') -- Hybrid gems (e.g. Vaal gems) use the display name of the active skill e.g. Vaal Summon Skeletons of Sorcery if not skillGem.IsSupport then out:write('\t\tbaseTypeName = "', gemEffect.GrantedEffect.ActiveSkill.DisplayName, '",\n') diff --git a/src/Modules/Common.lua b/src/Modules/Common.lua index 9dfc78ca1..5054d9c3e 100644 --- a/src/Modules/Common.lua +++ b/src/Modules/Common.lua @@ -264,6 +264,7 @@ function sanitiseText(text) :gsub("\226\128\162 ?", "") -- U+2022 BULLET :gsub("\195\164", "a") -- U+00E4 LATIN SMALL LETTER A WITH DIAERESIS :gsub("\195\182", "o") -- U+00F6 LATIN SMALL LETTER O WITH DIAERESIS + :gsub("\195\173", "i") -- U+00ED LATIN SMALL LETTER I WITH ACUTE -- single-byte: Windows-1252 and similar :gsub("\150", "-") -- U+2013 EN DASH :gsub("\151", "-") -- U+2014 EM DASH