Skip to content

Commit 16d7e40

Browse files
vaisestLocalIdentity
andauthored
Respect socket-bound augments in trader and add copy tests (#2157)
* Prevent overwriting socket-bound augments and add tests for copyanointsandaugments * Fix copying of items and remove augments trader --------- Co-authored-by: LocalIdentity <localidentity2@gmail.com>
1 parent c123209 commit 16d7e40

6 files changed

Lines changed: 819 additions & 9 deletions

File tree

spec/System/TestItemsTab_spec.lua

Lines changed: 213 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -408,4 +408,217 @@ describe("TestItemsTab", function()
408408
end)
409409
end)
410410
end)
411+
412+
describe("TestCopyAnointsAndAugments", function ()
413+
before_each(function ()
414+
newBuild()
415+
end)
416+
417+
-- Equips an item into the active item set's appropriate slot
418+
local function equip(raw)
419+
local item = new("Item", raw)
420+
build.itemsTab:AddItem(item)
421+
build.itemsTab:EquipItemInSet(item, build.itemsTab.activeItemSetId)
422+
return item
423+
end
424+
425+
describe("Anoints", function ()
426+
it("copies an anoint from the equipped item onto a new item", function ()
427+
equip([[
428+
Rarity: RARE
429+
Equipped
430+
Crimson Amulet
431+
Allocates Serrated Edges (enchant)
432+
]])
433+
434+
local newItem = new("Item", [[
435+
Rarity: RARE
436+
New
437+
Azure Amulet
438+
]])
439+
build.itemsTab:CopyAnointsAndAugments(newItem, false, false)
440+
441+
assert.are.equals(1, #newItem.enchantModLines)
442+
end)
443+
444+
it("does not overwrite an existing anoint when overwrite is false", function ()
445+
equip([[
446+
Rarity: RARE
447+
Equipped
448+
Crimson Amulet
449+
Allocates Serrated Edges (enchant)
450+
]])
451+
452+
local newItem = new("Item", [[
453+
Rarity: RARE
454+
New
455+
Azure Amulet
456+
Allocates Unbound Forces (enchant)
457+
]])
458+
build.itemsTab:CopyAnointsAndAugments(newItem, false, false)
459+
460+
assert.are.equals(1, #newItem.enchantModLines)
461+
assert.is_not_nil(newItem.enchantModLines[1].line:find("Unbound Forces"))
462+
end)
463+
464+
it("overwrites an existing anoint when overwrite is true", function ()
465+
equip([[
466+
Rarity: RARE
467+
Equipped
468+
Crimson Amulet
469+
Allocates Serrated Edges (enchant)
470+
]])
471+
472+
local newItem = new("Item", [[
473+
Rarity: RARE
474+
New
475+
Azure Amulet
476+
Allocates Unbound Forces (enchant)
477+
]])
478+
build.itemsTab:CopyAnointsAndAugments(newItem, false, true)
479+
480+
assert.are.equals(1, #newItem.enchantModLines)
481+
assert.is_not_nil(newItem.enchantModLines[1].line:find("Serrated Edges"))
482+
end)
483+
484+
it("does not modify a corrupted item", function ()
485+
equip([[
486+
Rarity: RARE
487+
Equipped
488+
Crimson Amulet
489+
Allocates Serrated Edges (enchant)
490+
]])
491+
492+
for _, status in ipairs({ "Corrupted", "Mirrored", "Sanctified" }) do
493+
local newItem = new("Item", string.format([[
494+
Rarity: RARE
495+
New
496+
Azure Amulet
497+
%s
498+
]], status))
499+
build.itemsTab:CopyAnointsAndAugments(newItem, false, false)
500+
501+
assert.are.equals(0, #newItem.enchantModLines)
502+
end
503+
end)
504+
end)
505+
506+
describe("Augments", function ()
507+
local rune = "Greater Robust Rune"
508+
509+
local existingItemText = string.format([[
510+
Rarity: RARE
511+
Equipped
512+
Stocky Mitts
513+
Sockets: S
514+
Rune: %s
515+
]], rune)
516+
517+
local newItemText = [[
518+
Rarity: RARE
519+
New
520+
Stocky Mitts
521+
]]
522+
523+
it("copies runes from the equipped item when copyAugments is true", function ()
524+
equip(existingItemText)
525+
526+
local newItem = new("Item", [[
527+
Rarity: RARE
528+
New
529+
Stocky Mitts
530+
]])
531+
build.itemsTab:CopyAnointsAndAugments(newItem, true, false)
532+
533+
assert.are.equals(rune, newItem.runes[1])
534+
end)
535+
536+
it("adds sockets to the new item to fit the copied runes", function ()
537+
equip(existingItemText)
538+
539+
local newItem = new("Item", newItemText)
540+
assert.are.equals(0, #newItem.sockets)
541+
542+
build.itemsTab:CopyAnointsAndAugments(newItem, true, false)
543+
544+
assert.are.equals(1, #newItem.sockets)
545+
end)
546+
547+
it("does not copy runes when copyAugments is false", function ()
548+
equip(existingItemText)
549+
550+
local newItem = new("Item", newItemText)
551+
build.itemsTab:CopyAnointsAndAugments(newItem, false, false)
552+
553+
assert.are.equals(0, #newItem.sockets)
554+
end)
555+
556+
it("does not replace socket bound runes", function ()
557+
equip(existingItemText)
558+
559+
local newItem = new("Item", [[
560+
Rarity: RARE
561+
Equipped
562+
Stocky Mitts
563+
Sockets: S
564+
Rune: Kolr's Hunt
565+
]])
566+
build.itemsTab:CopyAnointsAndAugments(newItem, true, true)
567+
assert.are.equals(newItem.runes[1], "Kolr's Hunt")
568+
569+
local newItem = new("Item", [[
570+
Rarity: RARE
571+
Equipped
572+
Stocky Mitts
573+
Sockets: S S
574+
Rune: Kolr's Hunt
575+
]])
576+
build.itemsTab:CopyAnointsAndAugments(newItem, true, true)
577+
assert.are.equals(newItem.runes[1], "Kolr's Hunt")
578+
assert.are.equals(newItem.runes[2], rune)
579+
end)
580+
581+
it("replaces runes when overwrite is true", function ()
582+
equip(existingItemText)
583+
584+
local newItem = new("Item", [[
585+
Rarity: RARE
586+
Equipped
587+
Stocky Mitts
588+
Sockets: S S
589+
Rune: Lesser Robust Rune
590+
]])
591+
build.itemsTab:CopyAnointsAndAugments(newItem, true, true)
592+
assert.are.equals(newItem.runes[1], rune)
593+
assert.are.equals(newItem.runes[2], "None")
594+
end)
595+
596+
it("identifies socket bound runes", function ()
597+
local item = new("Item", [[
598+
Rarity: RARE
599+
Equipped
600+
Stocky Mitts
601+
Sockets: S S
602+
Rune: Kolr's Hunt
603+
Rune: Lesser Robust Rune
604+
]])
605+
local validRunes = build.itemsTab:GetValidRunesForItem(item)
606+
607+
assert.is_true(build.itemsTab:IsSocketBoundRune(item, item.runes[1], validRunes))
608+
assert.is_false(build.itemsTab:IsSocketBoundRune(item, item.runes[2], validRunes))
609+
end)
610+
end)
611+
612+
it("does nothing when no matching item is equipped", function ()
613+
local newItem = new("Item", [[
614+
Rarity: RARE
615+
New
616+
Azure Amulet
617+
+8 to Strength (enchant)
618+
]])
619+
build.itemsTab:CopyAnointsAndAugments(newItem, true, false)
620+
621+
assert.are.equals(1, #newItem.enchantModLines)
622+
end)
623+
end)
411624
end)

src/Classes/ItemsTab.lua

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1758,18 +1758,28 @@ function ItemsTabClass:CopyAnointsAndAugments(newItem, copyAugments, overwrite,
17581758
local validRunes = self:GetValidRunesForItem(newItem)
17591759

17601760
-- replace runes with current ones, or set to none
1761+
local skipped = 0
17611762
if shouldChangeAugments then
17621763
for i = 1, #newItem.sockets do
1764+
-- avoid overwriting socket bound runes as removing these from e.g. trade results
1765+
-- will be confusing
1766+
if self:IsSocketBoundRune(newItem, newItem.runes[i], validRunes) then
1767+
-- if the new item has more slots than the old item, we still copy old
1768+
-- runes in order after skipping the socket bound rune
1769+
skipped = skipped + 1
1770+
goto continue
1771+
end
17631772
newItem.runes[i] = "None"
1764-
if currentRunes[i] then
1773+
if currentRunes[i - skipped] then
17651774
for _, rune in ipairs(validRunes) do
17661775
-- we only copy runes which fit the new item type
1767-
if rune.name == currentRunes[i] then
1768-
newItem.runes[i] = currentRunes[i]
1776+
if rune.name == currentRunes[i - skipped] then
1777+
newItem.runes[i] = currentRunes[i - skipped]
17691778
break
17701779
end
17711780
end
17721781
end
1782+
::continue::
17731783
end
17741784
newItem:UpdateRunes()
17751785
end
@@ -1921,11 +1931,11 @@ function ItemsTabClass:UpdateAffixControls()
19211931
self:UpdateCustomControls()
19221932
end
19231933

1924-
local runeModLines = { { name = "None", label = "None", lines = { "None" }, order = -1, slot = "None", group = -1 } }
1934+
local runeModLines = { { name = "None", label = "None", lines = { "None" }, order = -1, slot = "None", group = -1, isSocketBound = false } }
19251935
for name, runeMods in pairs(data.itemMods.Runes) do
19261936
-- Some runes have multiple mod lines; insert each as separate entry
19271937
for slotType, runeMod in pairs(runeMods) do
1928-
t_insert(runeModLines, { name = name, label = runeMod[1], lines = runeMod, req = runeMod.rank[1], order = runeMod.statOrder[1], slot = slotType, type = runeMod.type, group = #runeMod })
1938+
t_insert(runeModLines, { name = name, label = runeMod[1], lines = runeMod, req = runeMod.rank[1], order = runeMod.statOrder[1], slot = slotType, type = runeMod.type, group = #runeMod, isSocketBound = runeMod.isSocketBound })
19291939
end
19301940
end
19311941
table.sort(runeModLines, function(a, b)
@@ -1977,6 +1987,18 @@ function ItemsTabClass:GetValidRunesForItem(item)
19771987
return runes
19781988
end
19791989

1990+
function ItemsTabClass:IsSocketBoundRune(item, runeName, validRunes)
1991+
if not runeName or runeName == "None" then
1992+
return false
1993+
end
1994+
for _, rune in ipairs(validRunes or self:GetValidRunesForItem(item)) do
1995+
if rune.name == runeName then
1996+
return rune.isSocketBound
1997+
end
1998+
end
1999+
return false
2000+
end
2001+
19802002
-- Update rune selection controls
19812003
function ItemsTabClass:UpdateRuneControls()
19822004
local item = self.displayItem

src/Classes/TradeQuery.lua

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1050,8 +1050,11 @@ function TradeQueryClass:PriceItemRowDisplay(row_idx, top_pane_alignment_ref, ro
10501050
for item_idx, _ in ipairs(itemsSafe) do
10511051
local item = new("Item", itemsSafe[item_idx].item_string)
10521052
-- sockets are kept as-is so the user can see e.g. exceptional or corrupted sockets
1053+
local validRunes = self.itemsTab:GetValidRunesForItem(item)
10531054
for rune_idx, _ in ipairs(item.runes or {}) do
1054-
item.runes[rune_idx] = "None"
1055+
if not self.itemsTab:IsSocketBoundRune(item, item.runes[rune_idx], validRunes) then
1056+
item.runes[rune_idx] = "None"
1057+
end
10551058
end
10561059
item:UpdateRunes()
10571060
itemsSafe[item_idx].item_string = item:BuildRaw()

0 commit comments

Comments
 (0)