Added a new unique item, The Savior Added the ability to show only non-Awakened supports (or only Awakened supports!); the option can be found in the Skills tab under the socket group list Added sources of increased maximum resistances to now show up in the resistance breakdown window Add unique changes from 3.7 Fix issue where gem levels would get reset on loading or importing a build Implicits on items that are copied from in-game are now correctly handled. Additionally, the ability of the program to determine if modifiers on copied items are enchantments, implicits or explicits has been greatly improved, and should almost always be correct; also, applying enchantments to items with implicits will now work correctly. Fix + gem level mods on new influence amulets to now work properly Fix Fractal Thoughts increased dex mod to now work properly Fix support for old Red Nightmare mod wording
591 lines
21 KiB
Lua
591 lines
21 KiB
Lua
-- Path of Building
|
|
--
|
|
-- Class: Gem Select
|
|
-- Gem selection combobox
|
|
--
|
|
|
|
local t_insert = table.insert
|
|
local t_sort = table.sort
|
|
local m_min = math.min
|
|
local m_max = math.max
|
|
local m_floor = math.floor
|
|
|
|
local GemSelectClass = newClass("GemSelectControl", "EditControl", function(self, anchor, x, y, width, height, skillsTab, index, changeFunc)
|
|
self.EditControl(anchor, x, y, width, height, nil, nil, "^ %a'")
|
|
self.controls.scrollBar = new("ScrollBarControl", {"TOPRIGHT",self,"TOPRIGHT"}, -1, 0, 18, 0, (height - 4) * 4)
|
|
self.controls.scrollBar.y = function()
|
|
local width, height = self:GetSize()
|
|
return height + 1
|
|
end
|
|
self.controls.scrollBar.height = function()
|
|
return (height - 4) * m_min(#self.list, 15) + 2
|
|
end
|
|
self.controls.scrollBar.shown = function()
|
|
return self.dropped and self.controls.scrollBar.enabled
|
|
end
|
|
self.skillsTab = skillsTab
|
|
self.gems = skillsTab.build.data.gems
|
|
self.index = index
|
|
self.gemChangeFunc = changeFunc
|
|
self.list = { }
|
|
self.changeFunc = function()
|
|
if not self.dropped then
|
|
self.dropped = true
|
|
self:UpdateSortCache()
|
|
end
|
|
self.selIndex = 0
|
|
self:BuildList(self.buf)
|
|
self:UpdateGem()
|
|
end
|
|
end)
|
|
|
|
function GemSelectClass:FilterSupport(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)
|
|
end
|
|
|
|
function GemSelectClass:BuildList(buf)
|
|
self.controls.scrollBar.offset = 0
|
|
wipeTable(self.list)
|
|
self.searchStr = buf
|
|
if self.searchStr:match("%S") then
|
|
-- Search for gem name using increasingly broad search patterns
|
|
local patternList = {
|
|
"^ "..self.searchStr:lower().."$", -- Exact match
|
|
"^"..self.searchStr:lower():gsub("%a", " %0%%l+").."$", -- Simple abbreviation ("CtF" -> "Cold to Fire")
|
|
"^ "..self.searchStr:lower(), -- Starts with
|
|
self.searchStr:lower(), -- Contains
|
|
}
|
|
local added = { }
|
|
for i, pattern in ipairs(patternList) do
|
|
local matchList = { }
|
|
for gemId, gemData in pairs(self.gems) do
|
|
if self:FilterSupport(gemData) and not added[gemId] and (" "..gemData.name:lower()):match(pattern) then
|
|
t_insert(matchList, gemId)
|
|
added[gemId] = true
|
|
end
|
|
end
|
|
self:SortGemList(matchList)
|
|
for _, gemId in ipairs(matchList) do
|
|
t_insert(self.list, gemId)
|
|
end
|
|
end
|
|
local tagName = self.searchStr:match("^%s*(%a+)%s*$")
|
|
if tagName then
|
|
local matchList = { }
|
|
if tagName == "active" then
|
|
tagName = "active_skill"
|
|
end
|
|
for gemId, gemData in pairs(self.gems) do
|
|
if self:FilterSupport(gemData) and not added[gemId] and gemData.tags[tagName:lower()] == true then
|
|
t_insert(matchList, gemId)
|
|
added[gemId] = true
|
|
end
|
|
end
|
|
self:SortGemList(matchList)
|
|
for _, gemId in ipairs(matchList) do
|
|
t_insert(self.list, gemId)
|
|
end
|
|
end
|
|
else
|
|
for gemId, gemData in pairs(self.gems) do
|
|
if self:FilterSupport(gemData) then
|
|
t_insert(self.list, gemId)
|
|
end
|
|
end
|
|
self:SortGemList(self.list)
|
|
end
|
|
if not self.list[1] then
|
|
self.list[1] = ""
|
|
self.noMatches = true
|
|
else
|
|
self.noMatches = false
|
|
end
|
|
end
|
|
|
|
function GemSelectClass:UpdateSortCache()
|
|
local sortCache = self.sortCache
|
|
if sortCache and sortCache.socketGroup == self.skillsTab.displayGroup and sortCache.gemInstance == self.skillsTab.displayGroup.gemList[self.index] and
|
|
sortCache.outputRevision == self.skillsTab.build.outputRevision and sortCache.defaultLevel == self.skillsTab.defaultGemLevel and sortCache.defaultQuality == self.skillsTab.defaultGemQuality then
|
|
return
|
|
end
|
|
sortCache = {
|
|
socketGroup = self.skillsTab.displayGroup,
|
|
gemInstance = self.skillsTab.displayGroup.gemList[self.index],
|
|
outputRevision = self.skillsTab.build.outputRevision,
|
|
defaultLevel = self.skillsTab.defaultGemLevel,
|
|
defaultQuality = self.skillsTab.defaultGemQuality,
|
|
canSupport = { },
|
|
dps = { },
|
|
dpsColor = { },
|
|
}
|
|
self.sortCache = sortCache
|
|
if self.skillsTab.displayGroup.displaySkillList and self.skillsTab.displayGroup.displaySkillList[1] then
|
|
for gemId, gemData in pairs(self.gems) do
|
|
if gemData.grantedEffect.support then
|
|
for _, activeSkill in ipairs(self.skillsTab.displayGroup.displaySkillList) do
|
|
if calcLib.canGrantedEffectSupportActiveSkill(gemData.grantedEffect, activeSkill) then
|
|
sortCache.canSupport[gemId] = true
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
local calcFunc, calcBase = self.skillsTab.build.calcsTab:GetMiscCalculator(self.build)
|
|
local baseDPS = calcBase.Minion and calcBase.Minion.CombinedDPS or calcBase.CombinedDPS
|
|
for gemId, gemData in pairs(self.gems) do
|
|
sortCache.dps[gemId] = baseDPS
|
|
if sortCache.canSupport[gemId] or gemData.grantedEffect.hasGlobalEffect then
|
|
local gemList = self.skillsTab.displayGroup.gemList
|
|
local oldGem
|
|
if gemList[self.index] then
|
|
oldGem = copyTable(gemList[self.index], true)
|
|
else
|
|
gemList[self.index] = { level = self.skillsTab.defaultGemLevel or 20, quality = self.skillsTab.defaultGemQuality or 0, enabled = true, enableGlobal1 = true }
|
|
end
|
|
local gemInstance = gemList[self.index]
|
|
if gemInstance.gemData and gemInstance.gemData.defaultLevel ~= gemData.defaultLevel then
|
|
gemInstance.level = self.skillsTab.defaultGemLevel or 20
|
|
end
|
|
gemInstance.gemData = gemData
|
|
if not gemData.grantedEffect.levels[gemInstance.level] then
|
|
gemInstance.level = gemData.defaultLevel
|
|
end
|
|
local output = calcFunc()
|
|
if oldGem then
|
|
gemInstance.gemData = oldGem.gemData
|
|
gemInstance.level = oldGem.level
|
|
else
|
|
gemList[self.index] = nil
|
|
end
|
|
sortCache.dps[gemId] = output.Minion and output.Minion.CombinedDPS or output.CombinedDPS
|
|
end
|
|
if sortCache.dps[gemId] > baseDPS then
|
|
sortCache.dpsColor[gemId] = "^x228866"
|
|
elseif sortCache.dps[gemId] < baseDPS then
|
|
sortCache.dpsColor[gemId] = "^xFF4422"
|
|
else
|
|
sortCache.dpsColor[gemId] = "^xFFFF66"
|
|
end
|
|
end
|
|
end
|
|
|
|
function GemSelectClass:SortGemList(gemList)
|
|
local sortCache = self.sortCache
|
|
t_sort(gemList, function(a, b)
|
|
if sortCache.canSupport[a] == sortCache.canSupport[b] then
|
|
if self.skillsTab.sortGemsByDPS and sortCache.dps[a] ~= sortCache.dps[b] then
|
|
return sortCache.dps[a] > sortCache.dps[b]
|
|
else
|
|
return a < b
|
|
end
|
|
else
|
|
return sortCache.canSupport[a]
|
|
end
|
|
end)
|
|
end
|
|
|
|
function GemSelectClass:UpdateGem(setText, addUndo)
|
|
local gemId = self.list[m_max(self.selIndex, 1)]
|
|
if self.buf:match("%S") and self.gems[gemId] then
|
|
self.gemId = gemId
|
|
else
|
|
self.gemId = nil
|
|
end
|
|
self.gemName = self.gemId and self.gems[self.gemId].name or ""
|
|
if setText then
|
|
self:SetText(self.gemName)
|
|
end
|
|
self.gemChangeFunc(self.gemId, addUndo and self.gemName ~= self.initialBuf)
|
|
end
|
|
|
|
function GemSelectClass:ScrollSelIntoView()
|
|
local width, height = self:GetSize()
|
|
local scrollBar = self.controls.scrollBar
|
|
local dropHeight = (height - 4) * m_min(#self.list, 15)
|
|
scrollBar:SetContentDimension((height - 4) * #self.list, dropHeight)
|
|
scrollBar:ScrollIntoView((self.selIndex - 2) * (height - 4), 3 * (height - 4))
|
|
end
|
|
|
|
function GemSelectClass:IsMouseOver()
|
|
if not self:IsShown() then
|
|
return false
|
|
end
|
|
if self:GetMouseOverControl() then
|
|
return true
|
|
end
|
|
local x, y = self:GetPos()
|
|
local width, height = self:GetSize()
|
|
local cursorX, cursorY = GetCursorPos()
|
|
local dropExtra = self.dropped and (height - 4) * m_min(#self.list, 15) + 2 or 0
|
|
local mOver = cursorX >= x and cursorY >= y and cursorX < x + width and cursorY < y + height + dropExtra
|
|
local mOverComp
|
|
if mOver then
|
|
if cursorY < y + height then
|
|
mOverComp = "BODY"
|
|
else
|
|
mOverComp = "DROP"
|
|
end
|
|
end
|
|
return mOver, mOverComp
|
|
end
|
|
|
|
function GemSelectClass:Draw(viewPort)
|
|
self.EditControl:Draw(viewPort)
|
|
local x, y = self:GetPos()
|
|
local width, height = self:GetSize()
|
|
local enabled = self:IsEnabled()
|
|
local mOver, mOverComp = self:IsMouseOver()
|
|
local dropHeight = (height - 4) * m_min(#self.list, 15)
|
|
local scrollBar = self.controls.scrollBar
|
|
scrollBar:SetContentDimension((height - 4) * #self.list, dropHeight)
|
|
if self.dropped then
|
|
SetDrawLayer(nil, 5)
|
|
SetDrawColor(1, 1, 1)
|
|
DrawImage(nil, x, y + height, width, dropHeight + 4)
|
|
SetDrawColor(0, 0, 0)
|
|
DrawImage(nil, x + 1, y + height + 1, width - 2, dropHeight + 2)
|
|
SetDrawLayer(nil, 0)
|
|
end
|
|
if self.dropped then
|
|
SetDrawLayer(nil, 5)
|
|
local cursorX, cursorY = GetCursorPos()
|
|
self.hoverSel = mOverComp == "DROP" and math.floor((cursorY - y - height + scrollBar.offset) / (height - 4)) + 1
|
|
if self.hoverSel and not self.gems[self.list[self.hoverSel]] then
|
|
self.hoverSel = nil
|
|
end
|
|
SetViewport(x + 2, y + height + 2, width - 4, dropHeight)
|
|
local minIndex = m_floor(scrollBar.offset / 16 + 1)
|
|
local maxIndex = m_min(m_floor((scrollBar.offset + dropHeight) / 16 + 1), #self.list)
|
|
for index = minIndex, maxIndex do
|
|
local y = (index - 1) * (height - 4) - scrollBar.offset
|
|
if index == self.hoverSel or index == self.selIndex or (index == 1 and self.selIndex == 0) then
|
|
SetDrawColor(0.33, 0.33, 0.33)
|
|
DrawImage(nil, 0, y, width - 4, height - 4)
|
|
end
|
|
SetDrawColor(1, 1, 1)
|
|
local gemId = self.list[index]
|
|
local gemData = self.gems[gemId]
|
|
if gemData then
|
|
if gemData.grantedEffect.color == 1 then
|
|
SetDrawColor(colorCodes.STRENGTH)
|
|
elseif gemData.grantedEffect.color == 2 then
|
|
SetDrawColor(colorCodes.DEXTERITY)
|
|
elseif gemData.grantedEffect.color == 3 then
|
|
SetDrawColor(colorCodes.INTELLIGENCE)
|
|
end
|
|
end
|
|
DrawString(0, y, "LEFT", height - 4, "VAR", gemData and gemData.name or "<No matches>")
|
|
if gemData then
|
|
if gemData.grantedEffect.support and self.skillsTab.displayGroup.displaySkillList then
|
|
for _, activeSkill in ipairs(self.skillsTab.displayGroup.displaySkillList) do
|
|
if calcLib.canGrantedEffectSupportActiveSkill(gemData.grantedEffect, activeSkill) then
|
|
SetDrawColor(self.sortCache.dpsColor[gemId])
|
|
main:DrawCheckMark(width - 4 - height / 2 - (scrollBar.enabled and 18 or 0), y + (height - 4) / 2, (height - 4) * 0.8)
|
|
break
|
|
end
|
|
end
|
|
elseif gemData.grantedEffect.hasGlobalEffect then
|
|
SetDrawColor(self.sortCache.dpsColor[gemId])
|
|
DrawString(width - 4 - height / 2 - (scrollBar.enabled and 18 or 0), y - 2, "CENTER_X", height, "VAR", "+")
|
|
end
|
|
end
|
|
end
|
|
SetViewport()
|
|
self:DrawControls(viewPort)
|
|
if self.hoverSel then
|
|
local calcFunc, calcBase = self.skillsTab.build.calcsTab:GetMiscCalculator(self.build)
|
|
if calcFunc then
|
|
self.tooltip:Clear()
|
|
local gemList = self.skillsTab.displayGroup.gemList
|
|
local gemData = self.gems[self.list[self.hoverSel]]
|
|
local oldGem
|
|
if gemList[self.index] then
|
|
oldGem = copyTable(gemList[self.index], true)
|
|
else
|
|
gemList[self.index] = { level = self.skillsTab.defaultGemLevel or 20, quality = self.skillsTab.defaultGemQuality or 0, enabled = true, enableGlobal1 = true }
|
|
end
|
|
local gemInstance = gemList[self.index]
|
|
if gemInstance.gemData and gemInstance.gemData.defaultLevel ~= gemData.defaultLevel then
|
|
gemData.level = self.skillsTab.defaultGemLevel or 20
|
|
end
|
|
gemInstance.gemData = gemData
|
|
if not gemData.grantedEffect.levels[gemInstance.level] then
|
|
gemInstance.level = gemData.defaultLevel
|
|
end
|
|
local output = calcFunc()
|
|
if oldGem then
|
|
gemInstance.gemData = oldGem.gemData
|
|
gemInstance.level = oldGem.level
|
|
else
|
|
gemList[self.index] = nil
|
|
end
|
|
self.skillsTab.build:AddStatComparesToTooltip(self.tooltip, calcBase, output, "^7Selecting this gem will give you:")
|
|
self.tooltip:Draw(x, y + height + 2 + (self.hoverSel - 1) * (height - 4) - scrollBar.offset, width, height - 4, viewPort)
|
|
end
|
|
end
|
|
SetDrawLayer(nil, 0)
|
|
else
|
|
local hoverControl
|
|
if self.skillsTab.selControl and self.skillsTab.selControl._className == "GemSelectControl" then
|
|
hoverControl = self.skillsTab.selControl
|
|
else
|
|
hoverControl = self.skillsTab:GetMouseOverControl()
|
|
end
|
|
if hoverControl and hoverControl._className == "GemSelectControl" then
|
|
local thisGem = self.skillsTab.displayGroup.gemList[self.index]
|
|
local hoverGem = self.skillsTab.displayGroup.gemList[hoverControl.index]
|
|
if thisGem and hoverGem and thisGem.enabled and hoverGem.enabled and thisGem.gemData and hoverGem.gemData and
|
|
(self:CheckSupporting(thisGem, hoverGem) or self:CheckSupporting(hoverGem, thisGem)) then
|
|
SetDrawColor(0.33, 1, 0.33, 0.25)
|
|
DrawImage(nil, x, y, width, height)
|
|
end
|
|
end
|
|
if mOver and (not self.skillsTab.selControl or self.skillsTab.selControl._className ~= "GemSelectControl" or not self.skillsTab.selControl.dropped) then
|
|
local gemInstance = self.skillsTab.displayGroup.gemList[self.index]
|
|
if gemInstance and gemInstance.gemData then
|
|
SetDrawLayer(nil, 10)
|
|
self.tooltip:Clear()
|
|
self:AddGemTooltip(gemInstance)
|
|
self.tooltip:Draw(x, y, width, height, viewPort)
|
|
SetDrawLayer(nil, 0)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function GemSelectClass:CheckSupporting(gemA, gemB)
|
|
return (gemA.gemData.grantedEffect.support and not gemB.gemData.grantedEffect.support and gemA.supportEffect and gemA.supportEffect.isSupporting and gemA.supportEffect.isSupporting[gemB]) or
|
|
(gemA.gemData.secondaryGrantedEffect and gemA.gemData.secondaryGrantedEffect.support and not gemB.gemData.grantedEffect.support and gemA.supportEffect and gemA.supportEffect.isSupporting and gemA.supportEffect.isSupporting[gemB])
|
|
end
|
|
|
|
function GemSelectClass:AddGemTooltip(gemInstance)
|
|
self.tooltip.center = true
|
|
self.tooltip.color = colorCodes.GEM
|
|
local primary = gemInstance.gemData.grantedEffect
|
|
local secondary = gemInstance.gemData.secondaryGrantedEffect
|
|
if secondary and not secondary.support then
|
|
local grantedEffect = primary.support and primary or secondary
|
|
local grantedEffectVaal = primary.support and secondary or primary
|
|
self.tooltip:AddLine(20, colorCodes.GEM..grantedEffect.name)
|
|
self.tooltip:AddSeparator(10)
|
|
self.tooltip:AddLine(16, "^x7F7F7F"..gemInstance.gemData.tagString)
|
|
self:AddCommonGemInfo(gemInstance, grantedEffect, true)
|
|
self.tooltip:AddSeparator(10)
|
|
self.tooltip:AddLine(20, colorCodes.GEM..grantedEffectVaal.name)
|
|
self.tooltip:AddSeparator(10)
|
|
self:AddCommonGemInfo(gemInstance, grantedEffectVaal)
|
|
else
|
|
local grantedEffect = gemInstance.gemData.grantedEffect
|
|
self.tooltip:AddLine(20, colorCodes.GEM..grantedEffect.name)
|
|
self.tooltip:AddSeparator(10)
|
|
self.tooltip:AddLine(16, "^x7F7F7F"..gemInstance.gemData.tagString)
|
|
self:AddCommonGemInfo(gemInstance, grantedEffect, true, secondary and secondary.support and secondary)
|
|
end
|
|
end
|
|
|
|
function GemSelectClass:AddCommonGemInfo(gemInstance, grantedEffect, addReq, mergeStatsFrom)
|
|
local displayInstance = gemInstance.displayEffect or gemInstance
|
|
local grantedEffectLevel = grantedEffect.levels[displayInstance.level]
|
|
if addReq then
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FLevel: ^7%d%s%s",
|
|
gemInstance.level,
|
|
(displayInstance.level > gemInstance.level) and " ("..colorCodes.MAGIC.."+"..(displayInstance.level - gemInstance.level).."^7)" or "",
|
|
(gemInstance.level >= gemInstance.gemData.defaultLevel) and " (Max)" or ""
|
|
))
|
|
end
|
|
if grantedEffect.support then
|
|
if grantedEffectLevel.manaMultiplier then
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FMana Multiplier: ^7%d%%", grantedEffectLevel.manaMultiplier + 100))
|
|
end
|
|
if grantedEffectLevel.manaCostOverride then
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FMana Reservation Override: ^7%d%%", grantedEffectLevel.manaCostOverride))
|
|
end
|
|
if grantedEffectLevel.cooldown then
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FCooldown Time: ^7%.2f sec", grantedEffectLevel.cooldown))
|
|
end
|
|
else
|
|
if grantedEffectLevel.manaCost then
|
|
if grantedEffect.skillTypes[SkillType.ManaCostReserved] then
|
|
if grantedEffect.skillTypes[SkillType.ManaCostPercent] then
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FMana Reserved: ^7%d%%", grantedEffectLevel.manaCost))
|
|
else
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FMana Reserved: ^7%d", grantedEffectLevel.manaCost))
|
|
end
|
|
else
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FMana Cost: ^7%d", grantedEffectLevel.manaCost))
|
|
end
|
|
end
|
|
if grantedEffectLevel.cooldown then
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FCooldown Time: ^7%.2f sec", grantedEffectLevel.cooldown))
|
|
end
|
|
if gemInstance.gemData.tags.attack then
|
|
if grantedEffectLevel.attackSpeedMultiplier then
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FAttack Speed Multiplier: ^7%d%% of base", grantedEffectLevel.attackSpeedMultiplier + 100))
|
|
end
|
|
else
|
|
if grantedEffect.castTime > 0 then
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FCast Time: ^7%.2f sec", grantedEffect.castTime))
|
|
else
|
|
self.tooltip:AddLine(16, "^x7F7F7FCast Time: ^7Instant")
|
|
end
|
|
if grantedEffectLevel.critChance then
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FCritical Strike Chance: ^7%.2f%%", grantedEffectLevel.critChance))
|
|
end
|
|
end
|
|
if grantedEffectLevel.damageEffectiveness then
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FEffectiveness of Added Damage: ^7%d%%", grantedEffectLevel.damageEffectiveness * 100))
|
|
end
|
|
end
|
|
if addReq and displayInstance.quality > 0 then
|
|
self.tooltip:AddLine(16, string.format("^x7F7F7FQuality: "..colorCodes.MAGIC.."+%d%%^7%s",
|
|
gemInstance.quality,
|
|
(displayInstance.quality > gemInstance.quality) and " ("..colorCodes.MAGIC.."+"..(displayInstance.quality - gemInstance.quality).."^7)" or ""
|
|
))
|
|
end
|
|
self.tooltip:AddSeparator(10)
|
|
if addReq then
|
|
self.skillsTab.build:AddRequirementsToTooltip(self.tooltip, gemInstance.reqLevel, gemInstance.reqStr, gemInstance.reqDex, gemInstance.reqInt)
|
|
end
|
|
if grantedEffect.description then
|
|
local wrap = main:WrapString(grantedEffect.description, 16, m_max(DrawStringWidth(16, "VAR", gemInstance.gemData.tagString), 400))
|
|
for _, line in ipairs(wrap) do
|
|
self.tooltip:AddLine(16, colorCodes.GEM..line)
|
|
end
|
|
end
|
|
if self.skillsTab.build.data.describeStats then
|
|
self.tooltip:AddSeparator(10)
|
|
local stats = calcLib.buildSkillInstanceStats(displayInstance, grantedEffect)
|
|
if grantedEffectLevel.baseMultiplier then
|
|
stats["active_skill_attack_damage_final_permyriad"] = (grantedEffectLevel.baseMultiplier - 1) * 10000
|
|
end
|
|
if mergeStatsFrom then
|
|
for stat, val in pairs(calcLib.buildSkillInstanceStats(displayInstance, mergeStatsFrom)) do
|
|
stats[stat] = (stats[stat] or 0) + val
|
|
end
|
|
end
|
|
local descriptions = self.skillsTab.build.data.describeStats(stats, grantedEffect.statDescriptionScope)
|
|
for _, line in ipairs(descriptions) do
|
|
self.tooltip:AddLine(16, colorCodes.MAGIC..line)
|
|
end
|
|
end
|
|
end
|
|
|
|
function GemSelectClass:OnFocusGained()
|
|
self.EditControl:OnFocusGained()
|
|
self.dropped = true
|
|
self.selIndex = 0
|
|
self:UpdateSortCache()
|
|
self:BuildList("")
|
|
for index, gemId in pairs(self.list) do
|
|
if self.gems[gemId].name == self.buf then
|
|
self.selIndex = index
|
|
self:ScrollSelIntoView()
|
|
break
|
|
end
|
|
end
|
|
self.initialBuf = self.buf
|
|
self.initialIndex = self.selIndex
|
|
end
|
|
|
|
function GemSelectClass:OnFocusLost()
|
|
if self.dropped then
|
|
self.dropped = false
|
|
if self.noMatches then
|
|
self:SetText("")
|
|
end
|
|
self:UpdateGem(true, true)
|
|
end
|
|
end
|
|
|
|
function GemSelectClass:OnKeyDown(key, doubleClick)
|
|
if not self:IsShown() or not self:IsEnabled() then
|
|
return
|
|
end
|
|
local mOverControl = self:GetMouseOverControl()
|
|
if mOverControl and mOverControl.OnKeyDown then
|
|
self.selControl = mOverControl
|
|
return mOverControl:OnKeyDown(key) and self
|
|
else
|
|
self.selControl = nil
|
|
end
|
|
if self.dropped then
|
|
if key:match("BUTTON") and not self:IsMouseOver() then
|
|
return
|
|
end
|
|
if key == "LEFTBUTTON" then
|
|
if self.hoverSel and self.gems[self.list[self.hoverSel]] then
|
|
self.dropped = false
|
|
self.selIndex = self.hoverSel
|
|
self:SetText(self.gems[self.list[self.selIndex]].name)
|
|
self:UpdateGem(false, true)
|
|
return self
|
|
end
|
|
elseif key == "RETURN" then
|
|
self.dropped = false
|
|
if self.noMatches then
|
|
self:SetText("")
|
|
end
|
|
self.selIndex = m_max(self.selIndex, 1)
|
|
self:UpdateGem(true, true)
|
|
return self
|
|
elseif key == "ESCAPE" then
|
|
self.dropped = false
|
|
self:BuildList("")
|
|
self.buf = self.initialBuf
|
|
self.selIndex = self.initialIndex
|
|
self:UpdateGem(false, true)
|
|
return
|
|
elseif key == "WHEELUP" then
|
|
self.controls.scrollBar:Scroll(-1)
|
|
elseif key == "WHEELDOWN" then
|
|
self.controls.scrollBar:Scroll(1)
|
|
elseif key == "DOWN" then
|
|
if self.selIndex < #self.list and not self.noMatches then
|
|
self.selIndex = self.selIndex + 1
|
|
self:SetText(self.gems[self.list[self.selIndex]].name)
|
|
self:UpdateGem()
|
|
self:ScrollSelIntoView()
|
|
end
|
|
elseif key == "UP" then
|
|
if self.selIndex > 0 and not self.noMatches then
|
|
self.selIndex = self.selIndex - 1
|
|
if self.selIndex == 0 then
|
|
self:SetText(self.searchStr)
|
|
else
|
|
self:SetText(self.gems[self.list[self.selIndex]].name)
|
|
end
|
|
self:UpdateGem()
|
|
self:ScrollSelIntoView()
|
|
end
|
|
end
|
|
elseif key == "RETURN" or key == "RIGHTBUTTON" then
|
|
self.dropped = true
|
|
self:UpdateSortCache()
|
|
self.initialIndex = self.selIndex
|
|
self.initialBuf = self.buf
|
|
return self
|
|
end
|
|
local newSel = self.EditControl:OnKeyDown(key, doubleClick)
|
|
return newSel == self.EditControl and self or newSel
|
|
end
|
|
|
|
function GemSelectClass:OnKeyUp(key)
|
|
if not self:IsShown() or not self:IsEnabled() then
|
|
return
|
|
end
|
|
if self.selControl then
|
|
local newSel = self.selControl:OnKeyUp(key)
|
|
if newSel then
|
|
return self
|
|
else
|
|
self.selControl = nil
|
|
end
|
|
end
|
|
local newSel = self.EditControl:OnKeyUp(key)
|
|
return newSel == self.EditControl and self or newSel
|
|
end |