feat: sort gray items at the end

This commit is contained in:
Salikh Gurgenidze
2025-11-23 18:13:16 +04:00
parent 869830c28f
commit 9ff34ca583
+123 -34
View File
@@ -664,6 +664,66 @@ local function ApplySort(bagIDs, items, targetPositions)
return moveCount
end
--===========================================================================
-- GREY ITEM HANDLING HELPERS
--===========================================================================
-- Build tail positions (end-to-start) for a given count across the provided bags,
-- starting from the "last" regular bag (lowest priority, then highest bagID),
-- and spilling into previous bags when needed.
local function BuildGreyTailPositions(bagIDs, greyCount)
local positions = {}
local index = 1
if greyCount <= 0 then return positions end
-- Order bags: lowest priority first (these are considered "last"),
-- and for stable, pick higher bagID later within same priority.
local ordered = {}
for _, bagID in ipairs(bagIDs) do
table.insert(ordered, {
bagID = bagID,
priority = tonumber(addon.Modules.Utils:GetContainerPriority(bagID)) or 0,
numSlots = addon.Modules.Utils:GetBagSlotCount(bagID) or 0,
})
end
table.sort(ordered, function(a, b)
if a.priority ~= b.priority then
return a.priority < b.priority -- lowest first
end
return a.bagID > b.bagID -- higher bagID later (treated as further to the right)
end)
-- Collect tail slots from end to start, spilling to previous bags as needed.
for _, info in ipairs(ordered) do
for slot = info.numSlots, 1, -1 do
if index <= greyCount then
positions[index] = { bag = info.bagID, slot = slot }
index = index + 1
else
break
end
end
if index > greyCount then break end
end
return positions
end
-- Split a list of collected items into non-greys and greys (quality 0)
local function SplitGreyItems(items)
local nonGreys, greys = {}, {}
for _, item in ipairs(items) do
if tonumber(item.quality or 0) == 0 then
table.insert(greys, item)
else
table.insert(nonGreys, item)
end
end
return nonGreys, greys
end
--===========================================================================
-- PHASE 6: Sort Complexity Analysis
--===========================================================================
@@ -836,7 +896,7 @@ function SortEngine:AnalyzeBank()
end
function SortEngine:SortBags()
local bagIDs = addon.Constants.BAGS
local bagIDs = addon.Constants.BAGS
-- Phase 1: Detect specialized bags
local containers = DetectSpecializedBags(bagIDs)
@@ -863,24 +923,40 @@ function SortEngine:SortBags()
end
end
-- Phase 5: Categorical sort regular bags TOGETHER
-- Run multiple passes to resolve intermediate holes (e.g., an empty slot left before a filled one)
local regularMoves = 0
local regularBagIDs = containers.regular
if table.getn(regularBagIDs) > 0 then
-- Use a conservative cap on passes to avoid infinite loops in edge cases
local maxPasses = 6
for pass = 1, maxPasses do
local items = CollectItems(regularBagIDs)
if table.getn(items) == 0 then break end
items = SortItems(items)
local targetPositions = BuildTargetPositions(regularBagIDs, table.getn(items))
local moved = ApplySort(regularBagIDs, items, targetPositions)
regularMoves = regularMoves + moved
-- If nothing moved this pass, we're done
if moved == 0 then break end
end
end
-- Phase 5: Two-phase sort for regular bags:
-- 1) Sort non-grey items normally across all regular bags (front-compaction)
-- 2) Pack grey items (quality 0) at the end tail (last bag backwards), spilling into previous bags.
local regularMoves = 0
local regularBagIDs = containers.regular
if table.getn(regularBagIDs) > 0 then
local maxPasses = 6
for pass = 1, maxPasses do
local passMoves = 0
-- Re-collect current state from regular bags
local allItems = CollectItems(regularBagIDs)
local nonGreys, greys = SplitGreyItems(allItems)
-- 1) Non-greys: standard sort to the front positions only
if table.getn(nonGreys) > 0 then
local sortedNonGreys = SortItems(nonGreys)
local frontPositions = BuildTargetPositions(regularBagIDs, table.getn(sortedNonGreys))
passMoves = passMoves + (ApplySort(regularBagIDs, sortedNonGreys, frontPositions) or 0)
end
-- 2) Greys: ignore all other sorting rules; place end->start across bags
-- Re-collect after possible movements above for accurate positions
local afterItems = CollectItems(regularBagIDs)
local _, greysNow = SplitGreyItems(afterItems)
if table.getn(greysNow) > 0 then
local tailPositions = BuildGreyTailPositions(regularBagIDs, table.getn(greysNow))
passMoves = passMoves + (ApplySort(regularBagIDs, greysNow, tailPositions) or 0)
end
regularMoves = regularMoves + passMoves
if passMoves == 0 then break end
end
end
-- Return total moves made
return routeCount + consolidateCount + specializedMoves + regularMoves
@@ -921,21 +997,34 @@ function SortEngine:SortBank()
end
end
-- Phase 5: Sort regular bags TOGETHER (multi-pass)
local regularBagIDs = containers.regular
local regularMoves = 0
if table.getn(regularBagIDs) > 0 then
local maxPasses = 6
for pass = 1, maxPasses do
local items = CollectItems(regularBagIDs)
if table.getn(items) == 0 then break end
items = SortItems(items)
local targetPositions = BuildTargetPositions(regularBagIDs, table.getn(items))
local moved = ApplySort(regularBagIDs, items, targetPositions)
regularMoves = regularMoves + moved
if moved == 0 then break end
end
end
-- Phase 5: Regular bank bags — same two-phase approach (non-greys first, greys to tail)
local regularBagIDs = containers.regular
local regularMoves = 0
if table.getn(regularBagIDs) > 0 then
local maxPasses = 6
for pass = 1, maxPasses do
local passMoves = 0
local allItems = CollectItems(regularBagIDs)
local nonGreys, greys = SplitGreyItems(allItems)
if table.getn(nonGreys) > 0 then
local sortedNonGreys = SortItems(nonGreys)
local frontPositions = BuildTargetPositions(regularBagIDs, table.getn(sortedNonGreys))
passMoves = passMoves + (ApplySort(regularBagIDs, sortedNonGreys, frontPositions) or 0)
end
local afterItems = CollectItems(regularBagIDs)
local _, greysNow = SplitGreyItems(afterItems)
if table.getn(greysNow) > 0 then
local tailPositions = BuildGreyTailPositions(regularBagIDs, table.getn(greysNow))
passMoves = passMoves + (ApplySort(regularBagIDs, greysNow, tailPositions) or 0)
end
regularMoves = regularMoves + passMoves
if passMoves == 0 then break end
end
end
-- Return total moves made
return routeCount + consolidateCount + specializedMoves + regularMoves