Immensely reduce lag on sorting large recipe lists
This commit is contained in:
1 parent
fcdfbe33f4
commit
f50cffcf8d
1 file changed
+70
-34
+70
-34
@@ -176,6 +176,22 @@ local lockedRecipes = {}
|
|||||||
--If the seed changes, the above two tables will be wiped
|
--If the seed changes, the above two tables will be wiped
|
||||||
local lastSeedUsed = 0
|
local lastSeedUsed = 0
|
||||||
|
|
||||||
|
--A list of item IDs, sorted by quality, then by name, to help with sorting our recipe list faster
|
||||||
|
local sortedIDs = {}
|
||||||
|
for i = 1, EID.XMLMaxItemID do
|
||||||
|
if EID.XMLItemQualities[i] ~= nil then
|
||||||
|
table.insert(sortedIDs, i)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
table.sort(sortedIDs, function(a, b)
|
||||||
|
if EID.XMLItemQualities[a] == EID.XMLItemQualities[b] then
|
||||||
|
return (EID:getObjectName(5, 100, a) < EID:getObjectName(5, 100, b))
|
||||||
|
else
|
||||||
|
return (EID.XMLItemQualities[a] > EID.XMLItemQualities[b])
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
local customRNGSeed = 0x77777770
|
local customRNGSeed = 0x77777770
|
||||||
local customRNGShift = {0,0,0}
|
local customRNGShift = {0,0,0}
|
||||||
|
|
||||||
@@ -457,6 +473,7 @@ end
|
|||||||
|
|
||||||
local randResultCache = {}
|
local randResultCache = {}
|
||||||
local calcResultCache = {}
|
local calcResultCache = {}
|
||||||
|
local numResults = 0
|
||||||
|
|
||||||
EID.bagOfCraftingOffset = 0
|
EID.bagOfCraftingOffset = 0
|
||||||
EID.bagOfCraftingCurPickupCount = -1
|
EID.bagOfCraftingCurPickupCount = -1
|
||||||
@@ -593,6 +610,7 @@ function EID:handleBagOfCraftingRendering()
|
|||||||
elseif calcResultCache[queryString] == nil or EID.refreshNextTick then
|
elseif calcResultCache[queryString] == nil or EID.refreshNextTick then
|
||||||
--build on top of our previous recipe lists, if possible
|
--build on top of our previous recipe lists, if possible
|
||||||
local randResults = randResultCache[queryString] or {}
|
local randResults = randResultCache[queryString] or {}
|
||||||
|
local newResults = {}
|
||||||
local skipRandom = false
|
local skipRandom = false
|
||||||
--check every single possible recipe for our highest value pickups
|
--check every single possible recipe for our highest value pickups
|
||||||
--limit it in the options, since the number of total combinations quickly grows (nCr):
|
--limit it in the options, since the number of total combinations quickly grows (nCr):
|
||||||
@@ -625,7 +643,11 @@ function EID:handleBagOfCraftingRendering()
|
|||||||
local startPos = startPos or 1
|
local startPos = startPos or 1
|
||||||
local tempResult = tempResult or {}
|
local tempResult = tempResult or {}
|
||||||
if (length == 0) then
|
if (length == 0) then
|
||||||
randResults[table.concat(tempResult,",")] = {table.unpack(tempResult)}
|
local resultString = table.concat(tempResult,",")
|
||||||
|
if (randResults[resultString] == nil) then
|
||||||
|
randResults[resultString] = {table.unpack(tempResult)}
|
||||||
|
newResults[resultString] = {table.unpack(tempResult)}
|
||||||
|
end
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
for i = startPos, #arr-length+1 do
|
for i = startPos, #arr-length+1 do
|
||||||
@@ -646,49 +668,54 @@ function EID:handleBagOfCraftingRendering()
|
|||||||
table.remove(tableCopy, pos)
|
table.remove(tableCopy, pos)
|
||||||
end
|
end
|
||||||
table.sort(newTable, qualitySort)
|
table.sort(newTable, qualitySort)
|
||||||
randResults[table.concat(newTable,",")] = newTable
|
local resultString = table.concat(newTable,",")
|
||||||
|
if (randResults[resultString] == nil) then
|
||||||
|
randResults[resultString] = {table.unpack(newTable)}
|
||||||
|
newResults[resultString] = {table.unpack(newTable)}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local calcResults = {}
|
local sortedResults = {}
|
||||||
for k, v in pairs(randResults) do
|
if (calcResultCache[queryString]) then
|
||||||
|
sortedResults = calcResultCache[queryString]
|
||||||
|
else
|
||||||
|
for k, v in ipairs(sortedIDs) do
|
||||||
|
sortedResults[v] = {}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for k, v in pairs(newResults) do
|
||||||
local resultID, lockedAchievementID = EID:calculateBagOfCrafting(v)
|
local resultID, lockedAchievementID = EID:calculateBagOfCrafting(v)
|
||||||
if resultID ~= lockedAchievementID then
|
if resultID ~= lockedAchievementID then
|
||||||
table.insert(calcResults, {v, resultID, lockedAchievementID})
|
table.insert(sortedResults[resultID], {v, resultID, lockedAchievementID})
|
||||||
else
|
else
|
||||||
table.insert(calcResults, {v, resultID})
|
table.insert(sortedResults[resultID], {v, resultID})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
calcResultCache[queryString] = calcResults
|
calcResultCache[queryString] = sortedResults
|
||||||
randResultCache[queryString] = randResults
|
randResultCache[queryString] = randResults
|
||||||
results = calcResults
|
results = sortedResults
|
||||||
--sort our final results by quality, then alphabetical item name
|
|
||||||
table.sort(results, function(a, b)
|
numResults = 0
|
||||||
if EID.XMLItemQualities[a[2]] == EID.XMLItemQualities[b[2]] then
|
for k,v in ipairs(sortedIDs) do
|
||||||
return (EID:getObjectName(5, 100, a[2]) < EID:getObjectName(5, 100, b[2]))
|
if (EID.refreshNextTick and EID.bagOfCraftingOffset > 0 and v == EID.refreshPosition) then
|
||||||
else
|
--jump to the item we were looking at before, so you can more easily refresh for variants of recipes
|
||||||
return (EID.XMLItemQualities[a[2]] > EID.XMLItemQualities[b[2]])
|
EID.bagOfCraftingOffset = numResults
|
||||||
|
end
|
||||||
|
numResults = numResults + #results[v]
|
||||||
end
|
end
|
||||||
end)
|
|
||||||
|
|
||||||
if not EID.refreshNextTick then
|
if not EID.refreshNextTick then
|
||||||
EID.bagOfCraftingOffset = 0
|
EID.bagOfCraftingOffset = 0
|
||||||
EID.bagOfCraftingRefreshes = 0
|
EID.bagOfCraftingRefreshes = 0
|
||||||
--jump to the item we were looking at before, so you can more easily refresh for variants of recipes
|
|
||||||
elseif EID.bagOfCraftingOffset > 0 then
|
|
||||||
for k,v in ipairs(results) do
|
|
||||||
if (v[2] == EID.refreshPosition) then
|
|
||||||
EID.bagOfCraftingOffset = k-1
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
EID.refreshNextTick = false
|
EID.refreshNextTick = false
|
||||||
else
|
else
|
||||||
results = calcResultCache[queryString]
|
results = calcResultCache[queryString]
|
||||||
end
|
end
|
||||||
|
|
||||||
if #results == 0 then
|
if numResults == 0 then
|
||||||
EID.bagOfCraftingOffset = 0
|
EID.bagOfCraftingOffset = 0
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
@@ -726,7 +753,7 @@ function EID:handleBagOfCraftingRendering()
|
|||||||
if Input.IsActionPressed(EID.Config["BagOfCraftingToggleKey"], EID.player.ControllerIndex) then
|
if Input.IsActionPressed(EID.Config["BagOfCraftingToggleKey"], EID.player.ControllerIndex) then
|
||||||
EID.player:SetShootingCooldown(2)
|
EID.player:SetShootingCooldown(2)
|
||||||
if Input.IsActionTriggered(ButtonAction.ACTION_SHOOTDOWN, EID.player.ControllerIndex) then
|
if Input.IsActionTriggered(ButtonAction.ACTION_SHOOTDOWN, EID.player.ControllerIndex) then
|
||||||
EID.bagOfCraftingOffset = math.min(#results-(#results%EID.Config["BagOfCraftingResults"]), EID.bagOfCraftingOffset + EID.Config["BagOfCraftingResults"])
|
EID.bagOfCraftingOffset = math.min(numResults-(numResults%EID.Config["BagOfCraftingResults"]), EID.bagOfCraftingOffset + EID.Config["BagOfCraftingResults"])
|
||||||
EID.downHeld = Isaac.GetTime()
|
EID.downHeld = Isaac.GetTime()
|
||||||
elseif Input.IsActionTriggered(ButtonAction.ACTION_SHOOTUP, EID.player.ControllerIndex) then
|
elseif Input.IsActionTriggered(ButtonAction.ACTION_SHOOTUP, EID.player.ControllerIndex) then
|
||||||
EID.bagOfCraftingOffset = math.max(0, EID.bagOfCraftingOffset - EID.Config["BagOfCraftingResults"])
|
EID.bagOfCraftingOffset = math.max(0, EID.bagOfCraftingOffset - EID.Config["BagOfCraftingResults"])
|
||||||
@@ -739,12 +766,11 @@ function EID:handleBagOfCraftingRendering()
|
|||||||
elseif Input.IsActionTriggered(ButtonAction.ACTION_SHOOTRIGHT, EID.player.ControllerIndex) then
|
elseif Input.IsActionTriggered(ButtonAction.ACTION_SHOOTRIGHT, EID.player.ControllerIndex) then
|
||||||
if (EID.lockedResults == nil) then
|
if (EID.lockedResults == nil) then
|
||||||
EID.refreshNextTick = true
|
EID.refreshNextTick = true
|
||||||
if (results[EID.bagOfCraftingOffset+1]) then EID.refreshPosition = results[EID.bagOfCraftingOffset+1][2] end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
--scroll pages quickly if the button is held
|
--scroll pages quickly if the button is held
|
||||||
if Input.IsActionPressed(ButtonAction.ACTION_SHOOTDOWN, EID.player.ControllerIndex) and Isaac.GetTime() - EID.downHeld > 750 then
|
if Input.IsActionPressed(ButtonAction.ACTION_SHOOTDOWN, EID.player.ControllerIndex) and Isaac.GetTime() - EID.downHeld > 750 then
|
||||||
EID.bagOfCraftingOffset = math.min(#results-(#results%EID.Config["BagOfCraftingResults"]), EID.bagOfCraftingOffset + EID.Config["BagOfCraftingResults"])
|
EID.bagOfCraftingOffset = math.min(numResults-(numResults%EID.Config["BagOfCraftingResults"]), EID.bagOfCraftingOffset + EID.Config["BagOfCraftingResults"])
|
||||||
EID.downHeld = Isaac.GetTime() - 700
|
EID.downHeld = Isaac.GetTime() - 700
|
||||||
elseif Input.IsActionPressed(ButtonAction.ACTION_SHOOTUP, EID.player.ControllerIndex) and Isaac.GetTime() - EID.upHeld > 750 then
|
elseif Input.IsActionPressed(ButtonAction.ACTION_SHOOTUP, EID.player.ControllerIndex) and Isaac.GetTime() - EID.upHeld > 750 then
|
||||||
EID.bagOfCraftingOffset = math.max(0, EID.bagOfCraftingOffset - EID.Config["BagOfCraftingResults"])
|
EID.bagOfCraftingOffset = math.max(0, EID.bagOfCraftingOffset - EID.Config["BagOfCraftingResults"])
|
||||||
@@ -752,7 +778,7 @@ function EID:handleBagOfCraftingRendering()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
--fix bug with being allowed to go to an empty page if recipe count = multiple of page size (or if we refresh on last page)
|
--fix bug with being allowed to go to an empty page if recipe count = multiple of page size (or if we refresh on last page)
|
||||||
if (EID.bagOfCraftingOffset >= #results) then EID.bagOfCraftingOffset = EID.bagOfCraftingOffset - EID.Config["BagOfCraftingResults"] end
|
if (EID.bagOfCraftingOffset >= numResults) then EID.bagOfCraftingOffset = EID.bagOfCraftingOffset - EID.Config["BagOfCraftingResults"] end
|
||||||
|
|
||||||
local prevItem = 0
|
local prevItem = 0
|
||||||
|
|
||||||
@@ -762,14 +788,21 @@ function EID:handleBagOfCraftingRendering()
|
|||||||
prefix = "#{{Trinket159}} "
|
prefix = "#{{Trinket159}} "
|
||||||
end
|
end
|
||||||
|
|
||||||
--results is now sorted by quality and item name, and doesn't iterate over the entire table, instead starting at the page offset
|
--results is now a table of tables for each item, so we have to iterate over the table using sortedIDs
|
||||||
if (EID.bagOfCraftingOffset > 0) then
|
if (EID.bagOfCraftingOffset > 0) then
|
||||||
customDescObj.Description = customDescObj.Description.. prefix .. "...+"..EID.bagOfCraftingOffset.." more"
|
customDescObj.Description = customDescObj.Description.. prefix .. "...+"..EID.bagOfCraftingOffset.." more"
|
||||||
end
|
end
|
||||||
for i=EID.bagOfCraftingOffset+1,EID.bagOfCraftingOffset+EID.Config["BagOfCraftingResults"] do
|
local curOffset = 0
|
||||||
local v = results[i]
|
EID.refreshPosition = -1
|
||||||
|
for k,id in ipairs(sortedIDs) do
|
||||||
|
if (curOffset + #results[id] <= EID.bagOfCraftingOffset) then curOffset = curOffset + #results[id]
|
||||||
|
else
|
||||||
|
if (EID.refreshPosition == -1) then EID.refreshPosition = id end
|
||||||
|
for k2, v in ipairs(results[id]) do
|
||||||
|
curOffset = curOffset + 1
|
||||||
|
if (curOffset > EID.bagOfCraftingOffset+EID.Config["BagOfCraftingResults"]) then break end
|
||||||
if not v then break end
|
if not v then break end
|
||||||
|
if (curOffset > EID.bagOfCraftingOffset) then
|
||||||
if not EID.Config["BagOfCraftingDisplayNames"] then
|
if not EID.Config["BagOfCraftingDisplayNames"] then
|
||||||
customDescObj.Description = customDescObj.Description.."# {{Collectible"..v[2].."}} "
|
customDescObj.Description = customDescObj.Description.."# {{Collectible"..v[2].."}} "
|
||||||
--tack on the secondary recipe image to achievement-locked recipes
|
--tack on the secondary recipe image to achievement-locked recipes
|
||||||
@@ -792,8 +825,11 @@ function EID:handleBagOfCraftingRendering()
|
|||||||
customDescObj.Description = customDescObj.Description..EID:tableToCraftingIconsMerged(v[1])
|
customDescObj.Description = customDescObj.Description..EID:tableToCraftingIconsMerged(v[1])
|
||||||
prevItem = v[2]
|
prevItem = v[2]
|
||||||
end
|
end
|
||||||
if (EID.bagOfCraftingOffset + EID.Config["BagOfCraftingResults"] < #results) then
|
end
|
||||||
customDescObj.Description = customDescObj.Description.. prefix .. "...+"..(#results-EID.Config["BagOfCraftingResults"]-EID.bagOfCraftingOffset).." more"
|
end
|
||||||
|
end
|
||||||
|
if (EID.bagOfCraftingOffset + EID.Config["BagOfCraftingResults"] < numResults) then
|
||||||
|
customDescObj.Description = customDescObj.Description.. prefix .. "...+"..(numResults-EID.Config["BagOfCraftingResults"]-EID.bagOfCraftingOffset).." more"
|
||||||
end
|
end
|
||||||
|
|
||||||
EID:printDescription(customDescObj)
|
EID:printDescription(customDescObj)
|
||||||
|
|||||||
Reference in new issue
Block a user