Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions spec/System/TestItemParse_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -270,4 +270,16 @@ describe("TestItemParse", function()
assert.are.equals(2, #item.runeModLines)

end)

it("jewel sockets", function()
local item = new("Item", [[
Six Socket Body
Garment
Quality: 20
Sockets: J J J J J J
]])
item:BuildAndParseRaw()

assert.are.equals(6, item.jewelSocketCount)
end)
end)
15 changes: 12 additions & 3 deletions src/Classes/ImportTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1109,9 +1109,14 @@ function ImportTabClass:ImportItem(itemData, slotName)
if itemData.sockets and itemData.sockets[1] then
item.sockets = { }
item.itemSocketCount = 0
item.jewelSocketCount = 0
for i, socket in pairs(itemData.sockets) do
item.sockets[i] = { }
item.itemSocketCount = item.itemSocketCount + 1
if socket.type == "jewel" then
item.jewelSocketCount = item.jewelSocketCount + 1
else
item.sockets[i] = { }
item.itemSocketCount = item.itemSocketCount + 1
end
end
end

Expand Down Expand Up @@ -1263,7 +1268,11 @@ end
function ImportTabClass:ImportSocketedItems(item, socketedItems, slotName)
-- Build socket group list
for _, socketedItem in ipairs(socketedItems) do
t_insert(item.runes, socketedItem.baseType)
if isValueInTable({ "Diamond", "Emerald", "Ruby", "Sapphire" }, socketedItem.baseType) then
self:ImportItem(socketedItem, slotName .. " Jewel Socket "..socketedItem.socket + 1)
else
t_insert(item.runes, socketedItem.baseType)
end
end
end

Expand Down
19 changes: 19 additions & 0 deletions src/Classes/Item.lua
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,7 @@ function ItemClass:ParseRaw(raw, rarity, highQuality)
self.sockets = { }
self.runes = { }
self.itemSocketCount = 0
self.jewelSocketCount = 0
self.classRequirementModLines = { }
self.buffModLines = { }
self.enchantModLines = { }
Expand Down Expand Up @@ -440,6 +441,8 @@ function ItemClass:ParseRaw(raw, rarity, highQuality)
if c:match("[S]") then
t_insert(self.sockets, { group = group })
group = group + 1
elseif c:match("[J]") then -- e.g. specVal = "Sockets: J J J J J J"
self.jewelSocketCount = self.jewelSocketCount + 1
end
end
self.itemSocketCount = #self.sockets
Expand Down Expand Up @@ -1268,6 +1271,14 @@ function ItemClass:BuildRaw()
t_insert(rawLines, "Rune: "..(self.runes[i] or "None"))
end
end
if self.jewelSocketCount and self.jewelSocketCount > 0 then
local socketString = ""
for _ = 1, self.jewelSocketCount do
socketString = socketString .. "J "
end
socketString = socketString:gsub(" $", "")
t_insert(rawLines, "Sockets: " .. socketString)
end
if self.requirements and self.requirements.level then
t_insert(rawLines, "LevelReq: " .. self.requirements.level)
end
Expand Down Expand Up @@ -1832,6 +1843,14 @@ function ItemClass:BuildModList()
})
end
end
--Sekhema's Resolve
if baseList:Flag(nil, "JewelSocketRestriction") then
self.canSocketJewelBase = { }
self.canSocketJewelBase["Diamond"] = calcLocal(baseList, "CanSocketJewelBaseDiamond", "FLAG", 0)
self.canSocketJewelBase["Sapphire"] = calcLocal(baseList, "CanSocketJewelBaseSapphire", "FLAG", 0)
self.canSocketJewelBase["Emerald"] = calcLocal(baseList, "CanSocketJewelBaseEmerald", "FLAG", 0)
self.canSocketJewelBase["Ruby"] = calcLocal(baseList, "CanSocketJewelBaseRuby", "FLAG", 0)
end

local reqLevel = 0
local minReqLevel
Expand Down
11 changes: 11 additions & 0 deletions src/Classes/ItemSlotControl.lua
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ local ItemSlotClass = newClass("ItemSlotControl", "DropDownControl", function(se
self.labelOffset = -2
end
self.socketList = { }
self.jewelSocketList = { }
self.tooltipFunc = function(tooltip, mode, index, itemId)
local item = itemsTab.items[self.items[index]]
-- not selControl.ListControl allows hover when All Items or Unique/Rare DB Sections are in focus
Expand Down Expand Up @@ -101,6 +102,16 @@ function ItemSlotClass:Populate()
if not self.selItemId or not self.itemsTab.items[self.selItemId] or not self.itemsTab:IsItemValidForSlot(self.itemsTab.items[self.selItemId], self.slotName) then
self:SetSelItemId(0)
end

-- Update Jewel Sockets
local jewelSocketCount = 0
if self.selItemId > 0 then
local selItem = self.itemsTab.items[self.selItemId]
jewelSocketCount = selItem.jewelSocketCount or 0
end
for i, jewelSocket in ipairs(self.jewelSocketList) do
jewelSocket.inactive = i > jewelSocketCount
end
end

function ItemSlotClass:CanReceiveDrag(type, value)
Expand Down
53 changes: 47 additions & 6 deletions src/Classes/ItemsTab.lua
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,21 @@ local ItemsTabClass = newClass("ItemsTab", "UndoHandler", "ControlHost", "Contro
return self.build.calcsTab.mainEnv.modDB:Flag(nil, "AdditionalRingSlot")
end
end
if slotName == "Weapon 1" or slotName == "Weapon 2" or slotName == "Helmet" or slotName == "Gloves" or slotName == "Body Armour" or slotName == "Boots" or slotName == "Belt" or slotName == "Ring 1" or slotName == "Ring 2" or slotName == "Ring 3" then
-- Add Jewel Socket slots
for i = 1, 6 do
local jewel = new("ItemSlotControl", {"TOPLEFT",prevSlot,"BOTTOMLEFT"}, 0, 2, self, slotName.." Jewel Socket "..i, "Jewel #"..i)
addSlot(jewel)
jewel.parentSlot = slot
if slotName:match("Weapon") then
jewel.weaponSet = 1
jewel.shown = function()
return not jewel.inactive and not self.activeItemSet.useSecondWeaponSet
end
end
slot.jewelSocketList[i] = jewel
end
end
end

-- Passive tree dropdown controls
Expand Down Expand Up @@ -949,11 +964,20 @@ function ItemsTabClass:Load(xml, dbFileName)
end
end
end
-- backwards compat or fallback if the item doesn't have "Sockets: J ..." on Load
-- maybe at some point we won't need this at all
local fallBackJewelSocketCount = {
["Tabula Rasa"] = 6,
["Sekhema's Resolve"] = 1,
}
if item.base then
if fallBackJewelSocketCount[item.title] and item.jewelSocketCount == 0 then
item.jewelSocketCount = fallBackJewelSocketCount[item.title]
end
item:BuildModList()
self.items[item.id] = item
t_insert(self.itemOrderList, item.id)
end
end
-- Below is OBE and left for legacy compatibility (all Slots are part of ItemSets now)
elseif node.elem == "Slot" then
local slot = self.slots[node.attrib.name or ""]
Expand Down Expand Up @@ -1058,11 +1082,13 @@ function ItemsTabClass:Save(xml)
local itemSet = self.itemSets[itemSetId]
local child = { elem = "ItemSet", attrib = { id = tostring(itemSetId), title = itemSet.title, useSecondWeaponSet = tostring(itemSet.useSecondWeaponSet) } }
for slotName, slot in pairs(self.slots) do
if not slot.nodeId then
t_insert(child, { elem = "Slot", attrib = { name = slotName, itemId = tostring(itemSet[slotName].selItemId), itemPbURL = itemSet[slotName].pbURL or "", active = itemSet[slotName].active and "true" }})
else
if self.build.spec.allocNodes[slot.nodeId] then
t_insert(child, { elem = "SocketIdURL", attrib = { name = slotName, nodeId = tostring(slot.nodeId), itemPbURL = itemSet[slot.nodeId] and itemSet[slot.nodeId].pbURL or ""}})
if slot.shown() then -- only save slots that are shown, avoid bloat with Jewel Sockets
if not slot.nodeId then
t_insert(child, { elem = "Slot", attrib = { name = slotName, itemId = tostring(itemSet[slotName].selItemId), itemPbURL = itemSet[slotName].pbURL or "", active = itemSet[slotName].active and "true" }})
else
if self.build.spec.allocNodes[slot.nodeId] then
t_insert(child, { elem = "SocketIdURL", attrib = { name = slotName, nodeId = tostring(slot.nodeId), itemPbURL = itemSet[slot.nodeId] and itemSet[slot.nodeId].pbURL or ""}})
end
end
end
end
Expand Down Expand Up @@ -1994,6 +2020,13 @@ function ItemsTabClass:IsItemValidForSlot(item, slotName, itemSet, flagState)
return true
elseif item.type == slotType then
return true
elseif item.type == "Jewel" and slotName:match("Jewel Socket") and not (item.rarity == "UNIQUE") then
local parentSlotName = slotName:gsub(" Jewel Socket %d", "") -- Ring 1 Jewel Socket 1 -> Ring 1
local slotItem = itemSet[parentSlotName] and self.items[itemSet[parentSlotName].selItemId]
-- Sekhema's Resolve restricts which base jewel can be socketed, other items (Tabula only for now) have no restriction
if slotItem and (not slotItem.canSocketJewelBase or (slotItem.canSocketJewelBase and slotItem.canSocketJewelBase[item.baseName])) then
return true
end
elseif slotName == "Weapon 1" or slotName == "Weapon 1 Swap" or slotName == "Weapon" then
return item.base.tags.onehand or item.base.tags.twohand
elseif slotName == "Weapon 2" or slotName == "Weapon 2 Swap" then
Expand Down Expand Up @@ -3009,6 +3042,14 @@ function ItemsTabClass:AddItemTooltip(tooltip, item, slot, dbMode)
socketString = socketString:gsub(" $", "")
tooltip:AddLine(fontSizeBig, "^x7F7F7FSockets: " .. socketString, "FONTIN SC")
end
if item.jewelSocketCount > 0 then
local socketString = ""
for _ = 1, item.jewelSocketCount do
socketString = socketString .. "J "
end
socketString = socketString:gsub(" $", "")
tooltip:AddLine(fontSizeBig, "^x7F7F7FSockets: " .. socketString, "FONTIN SC")
end
tooltip:AddSeparator(10)

if item.talismanTier then
Expand Down
27 changes: 26 additions & 1 deletion src/Classes/TradeQuery.lua
Original file line number Diff line number Diff line change
Expand Up @@ -415,12 +415,35 @@ Highest Weight - Displays the order retrieved from trade]]
self:UpdateRealms()
end

local activeJewelSockets = {
["Weapon 1"] = { }, ["Weapon 2"] = { }, ["Helmet"] = { },
["Body Armour"] = { }, ["Gloves"] = { }, ["Boots"] = { },
["Belt"] = { }, ["Ring 1"] = { }, ["Ring 2"] = { }, ["Ring 3"] = { },
}
-- loop all slots, set any active jewel sockets
for index, slot in pairs(self.itemsTab.slots) do
if index:find("Jewel") and slot.shown() then
t_insert(activeJewelSockets[slot.parentSlot.slotName], slot)
end
end
for _, jewel in pairs(activeJewelSockets) do -- sort Jewel #1 > Jewel #2
t_sort(jewel, function(a, b)
return a.label < b.label
end)
end

-- Individual slot rows
local slotTables = {}
for _, slotName in ipairs(baseSlots) do
if self.itemsTab.slots[slotName].shown() then
t_insert(slotTables, { slotName = slotName })
end
-- add jewel sockets to slotTables if exist for this slot
if activeJewelSockets[slotName] then
for _, jewelSocket in pairs(activeJewelSockets[slotName]) do
t_insert(slotTables, { slotName = jewelSocket.label, fullName = jewelSocket.slotName }) -- actual slotName doesn't fit/excessive in slotName on popup but is needed for exact matching later
end
end
end
local activeSocketList = { }
for nodeId, slot in pairs(self.itemsTab.sockets) do
Expand Down Expand Up @@ -840,7 +863,9 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
local controls = self.controls
local slotTbl = self.slotTables[row_idx]
local activeSlotRef = slotTbl.nodeId and self.itemsTab.activeItemSet[slotTbl.nodeId] or self.itemsTab.activeItemSet[slotTbl.slotName]
local activeSlot = slotTbl.nodeId and self.itemsTab.sockets[slotTbl.nodeId] or slotTbl.slotName and self.itemsTab.slots[slotTbl.slotName]
local activeSlot = slotTbl.nodeId and self.itemsTab.sockets[slotTbl.nodeId]
or slotTbl.slotName and (self.itemsTab.slots[slotTbl.slotName]
or slotTbl.fullName and self.itemsTab.slots[slotTbl.fullName]) -- fullName for Jewel Sockets
local nameColor = slotTbl.unique and colorCodes.UNIQUE or "^7"
controls["name"..row_idx] = new("LabelControl", top_pane_alignment_ref, {0, row_idx*(row_height + row_vertical_padding), 100, row_height - 4}, nameColor..slotTbl.slotName)
controls["bestButton"..row_idx] = new("ButtonControl", { "LEFT", controls["name"..row_idx], "LEFT"}, {100 + 8, 0, 80, row_height}, "Find best", function()
Expand Down
9 changes: 3 additions & 6 deletions src/Data/ModCache.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5295,7 +5295,6 @@ c["Has 2 Charm Slots"]={{[1]={flags=0,keywordFlags=0,name="CharmLimit",type="BAS
c["Has 3 Charm Slot"]={{[1]={flags=0,keywordFlags=0,name="CharmLimit",type="BASE",value=3}},nil}
c["Has 3 Charm Slots"]={{[1]={flags=0,keywordFlags=0,name="CharmLimit",type="BASE",value=3}},nil}
c["Has 4 Augment Sockets"]={nil,"Has 4 Augment Sockets "}
c["Has 6 Rune Sockets"]={nil,"Has 6 Rune Sockets "}
c["Hazards have 15% chance to rearm after they are triggered"]={{[1]={[1]={skillType=203,type="SkillType"},flags=0,keywordFlags=0,name="HazardRearmChance",type="BASE",value=15}},nil}
c["Hazards have 5% chance to rearm after they are triggered"]={{[1]={[1]={skillType=203,type="SkillType"},flags=0,keywordFlags=0,name="HazardRearmChance",type="BASE",value=5}},nil}
c["Heavy Stuns Enemies that are on Full Life"]={{[1]={flags=0,keywordFlags=0,name="EnemyModifier",type="LIST",value={mod={[1]={type="Condition",var="FullLife"},flags=0,keywordFlags=0,name="Condition:HeavyStunned",type="FLAG",value=true}}}},nil}
Expand Down Expand Up @@ -6164,11 +6163,9 @@ c["You can have two Companions of different types"]={nil,"You can have two Compa
c["You can have two Companions of different types 60% reduced Duration of Bleeding on You"]={nil,"You can have two Companions of different types 60% reduced Duration of Bleeding on You "}
c["You can have two Companions of different types You have 30% less Defences"]={nil,"You can have two Companions of different types You have 30% less Defences "}
c["You can have two Companions of different types You have 30% less Defences Companions have +1 to each Defence for every 2 of that Defence you have"]={nil,"You can have two Companions of different types You have 30% less Defences Companions have +1 to each Defence for every 2 of that Defence you have "}
c["You can only Socket Emerald Jewels in this item"]={nil,"You can only Socket Emerald Jewels in this item "}
c["You can only Socket Emerald Jewels in this item You can only Socket Ruby Jewels in this item"]={nil,"You can only Socket Emerald Jewels in this item You can only Socket Ruby Jewels in this item "}
c["You can only Socket Ruby Jewels in this item"]={nil,"You can only Socket Ruby Jewels in this item "}
c["You can only Socket Ruby Jewels in this item You can only Socket Sapphire Jewels in this item"]={nil,"You can only Socket Ruby Jewels in this item You can only Socket Sapphire Jewels in this item "}
c["You can only Socket Sapphire Jewels in this item"]={nil,"You can only Socket Sapphire Jewels in this item "}
c["You can only Socket Emerald Jewels in this item"]={{[1]={flags=0,keywordFlags=0,name="JewelSocketRestriction",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="CanSocketJewelBaseEmerald",type="FLAG",value=true}},nil}
c["You can only Socket Ruby Jewels in this item"]={{[1]={flags=0,keywordFlags=0,name="JewelSocketRestriction",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="CanSocketJewelBaseRuby",type="FLAG",value=true}},nil}
c["You can only Socket Sapphire Jewels in this item"]={{[1]={flags=0,keywordFlags=0,name="JewelSocketRestriction",type="FLAG",value=true},[2]={flags=0,keywordFlags=0,name="CanSocketJewelBaseSapphire",type="FLAG",value=true}},nil}
c["You can wield Two-Handed Axes, Maces and Swords in one hand"]={{[1]={flags=0,keywordFlags=0,name="GiantsBlood",type="FLAG",value=true}},nil}
c["You cannot Recover Energy Shield from Regeneration"]={nil,"You cannot Recover Energy Shield from Regeneration "}
c["You cannot Recover Energy Shield from Regeneration You cannot Recover Energy Shield to above Armour"]={nil,"You cannot Recover Energy Shield from Regeneration You cannot Recover Energy Shield to above Armour "}
Expand Down
3 changes: 1 addition & 2 deletions src/Data/Uniques/body.lua
Original file line number Diff line number Diff line change
Expand Up @@ -767,7 +767,6 @@ Evasion Rating is increased by Uncapped Lightning Resistance
Tabula Rasa
Garment
League: Dawn of the Hunt
Sockets: S S S S S S
Has 6 Rune Sockets
Sockets: J J J J J J
]],
}
1 change: 1 addition & 0 deletions src/Data/Uniques/ring.lua
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ Implicits: 1
]],[[
Sekhema's Resolve
Ring
Sockets: J
Source: Drops from unique{Zarokh, the Temporal}
Variant: Ruby
Variant: Emerald
Expand Down
3 changes: 1 addition & 2 deletions src/Export/Uniques/body.lua
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,6 @@ UniqueEvasionOvercappedLightningResistance1
Tabula Rasa
Garment
League: Dawn of the Hunt
Sockets: S S S S S S
Has 6 Rune Sockets
Sockets: J J J J J J
]],
}
1 change: 1 addition & 0 deletions src/Export/Uniques/ring.lua
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,7 @@ UniqueManaCostReduction2
]],[[
Sekhema's Resolve
Ring
Sockets: J
Source: Drops from unique{Zarokh, the Temporal}
Variant: Ruby
Variant: Emerald
Expand Down
10 changes: 10 additions & 0 deletions src/Modules/CalcSetup.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1009,6 +1009,16 @@ function calcs.initEnv(build, mode, override, specEnv)
item = nil
end
local scale = 1
-- unequips Jewel if parentSlot providing the socket is removed
if item and item.type == "Jewel" and slot.parentSlot then
-- Check if the item in the parent slot has enough Jewel Sockets
local parentItem = env.player.itemList[slot.parentSlot.slotName]
if not parentItem or parentItem.jewelSocketCount < slot.slotNum then
item = nil
else
scale = parentItem.socketedJewelEffectModifier
end
end
if slot.nodeId and item and item.type == "Jewel" and item.jewelData and item.jewelData.jewelIncEffectFromClassStart then
local node = env.spec.nodes[slot.nodeId]
if node and node.distanceToClassStart then
Expand Down
4 changes: 4 additions & 0 deletions src/Modules/ModParser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5362,6 +5362,10 @@ local specialModList = {
["(%d+) added passive skills are jewel sockets"] = function(num) return { mod("JewelData", "LIST", { key = "clusterJewelSocketCount", value = num }) } end,
["adds (%d+) jewel socket passive skills"] = function(num) return { mod("JewelData", "LIST", { key = "clusterJewelSocketCountOverride", value = num }) } end,
["adds (%d+) small passive skills? which grants? nothing"] = function(num) return { mod("JewelData", "LIST", { key = "clusterJewelNothingnessCount", value = num }) } end,
["you can only socket (%a+) jewels in this item"] = function(_, jewelType) return {
flag("JewelSocketRestriction"),
flag("CanSocketJewelBase"..firstToUpper(jewelType))
} end,
["added small passive skills grant nothing"] = { mod("JewelData", "LIST", { key = "clusterJewelSmallsAreNothingness", value = true }) },
["added small passive skills have (%d+)%% increased effect"] = function(num) return { mod("JewelData", "LIST", { key = "clusterJewelIncEffect", value = num }) } end,
["this jewel's socket has (%d+)%% increased effect per allocated passive skill between it and your class' starting location"] = function(num) return { mod("JewelData", "LIST", { key = "jewelIncEffectFromClassStart", value = num }) } end,
Expand Down
Loading