Implement stack group transfers

This commit is contained in:
Gabriel Tofvesson 2024-10-12 07:34:57 +02:00
parent 43bfca07c6
commit 9ac62319fd
5 changed files with 75 additions and 4 deletions

View File

@ -1,6 +1,7 @@
local ItemStack = require("storage.itemstack") local ItemStack = require("storage.itemstack")
local Sentinel = require("storage.sentinel")
local Chest = {} local Chest = Sentinel.tag({}, Sentinel.CHEST)
Chest.__index = Chest Chest.__index = Chest
-- Homogeneity allows chest scan to clone empty itemDetail slot to all empty slots in chest -- Homogeneity allows chest scan to clone empty itemDetail slot to all empty slots in chest

View File

@ -1,5 +1,7 @@
local Chest = require("storage.chest") local Chest = require("storage.chest")
local Storage = {} local Sentinel = require("storage.sentinel")
local Storage = Sentinel.tag({}, Sentinel.STORAGE)
Storage.__index = Storage Storage.__index = Storage
function Storage.assumeHomogeneous(names) function Storage.assumeHomogeneous(names)

View File

@ -1,4 +1,6 @@
local ItemGroup = {} local Sentinel = require("storage.sentinel")
local ItemGroup = Sentinel.tag({}, Sentinel.ITEMGROUP)
ItemGroup.__index = ItemGroup ItemGroup.__index = ItemGroup
--- Create a group of managed itemstacks --- Create a group of managed itemstacks
@ -107,6 +109,52 @@ function ItemGroup:addStack(stack)
return false return false
end end
function ItemGroup:transferTo(target, itemCount)
local targetGroup = nil
if Sentinel:is(target, Sentinel.CHEST) or Sentinel:is(target, Sentinel.STORAGE) then
local identity = self:_getIdentityStack()
local find = target:find(function(stack) return identity:canTransfer(stack) end)
if #find == 0 then
return itemCount == nil or itemCount == 0, 0
end
targetGroup = ItemGroup:from(find[1])
for i=2,#find do
targetGroup:_addStack(find[i])
end
elseif Sentinel:is(target, Sentinel.ITEMSTACK) then
targetGroup = ItemGroup:from(target)
elseif Sentinel:is(target, Sentinel.ITEMGROUP) then
targetGroup = target
end
if targetGroup == nil then
error("Unexpected transfer target for ItemGroup:transferTo")
end
local targetCap = 0
for _,stack in targetGroup:_iterateStacks() do
targetCap = targetCap + (stack:getMaxCount() - stack:getCount())
end
-- TODO: Not efficient
local transferMax = math.min(itemCount or targetCap, targetCap, self:getItemCount())
local transfer = 0
for _,stack in targetGroup:_iterateStacks() do
local targetCount = math.min(target:getCount() + transferMax - transfer, stack:getMaxCount())
for _,from in self:_iterateStacks() do
if stack:getCount() == targetCount then
goto continue
end
local _, xfer = from:transferTo(stack)
transfer = transfer + xfer
end
::continue::
end
return itemCount == nil or (itemCount == transfer), transfer
end
function ItemGroup:getItemCount() function ItemGroup:getItemCount()
if self:_getIdentityStack():isEmpty() then if self:_getIdentityStack():isEmpty() then
return 0 return 0

View File

@ -1,6 +1,7 @@
local Inventory = require("storage.inventory") local Inventory = require("storage.inventory")
local Sentinel = require("storage.sentinel")
local ItemStack = {} local ItemStack = Sentinel.tag({}, Sentinel.ITEMSTACK)
ItemStack.__index = ItemStack ItemStack.__index = ItemStack
function ItemStack:fromDetail(inv, detail, slot) function ItemStack:fromDetail(inv, detail, slot)

19
storage/sentinel.lua Normal file
View File

@ -0,0 +1,19 @@
local TABLE_KEY = "!__SENTINEL"
local Sentinel = {
CHEST = "CHEST",
ITEMSTACK = "ITEMSTACK",
ITEMGROUP = "ITEMGROUP",
STORAGE = "STORAGE"
}
function Sentinel:tag(table, sentinel)
table[TABLE_KEY] = sentinel
return table
end
function Sentinel:is(table, sentinel)
return table[TABLE_KEY] == sentinel
end
return Sentinel