Add safer way to get inventory lists, replace in current code

This commit is contained in:
Zenon Seth 2024-04-09 12:44:42 +01:00
parent c7b1b13411
commit 45017fb451
13 changed files with 39 additions and 32 deletions

View File

@ -23,7 +23,7 @@ local function update_upgrade_count(pos, optMeta)
local meta = optMeta or minetest.get_meta(pos)
local inv = meta:get_inventory()
local upgCount = 0
for _, st in ipairs(inv:get_list(INV_UPG) or {}) do
for _, st in ipairs(logistica.get_list(inv, INV_UPG)) do
if not st:is_empty() then upgCount = upgCount + 1 end
end
meta:set_int(META_UPGRADE_COUNT, upgCount)

View File

@ -13,7 +13,7 @@ local TIMER_LONG = 3.0
local function update_craft_output(inv)
local inputList = inv:get_list(INV_CRAFT)
local inputList = logistica.get_list(inv, INV_CRAFT)
local out, _ = minetest.get_craft_result({
method = "normal",
width = 3,

View File

@ -10,7 +10,7 @@ local INV_HOUT = "hout"
local forms = {}
local function update_craft_output(inv)
local inputList = inv:get_list(INV_CRAFT)
local inputList = logistica.get_list(inv, INV_CRAFT)
local out, _ = minetest.get_craft_result({
method = "normal",
width = 3,
@ -122,7 +122,8 @@ local function on_craftsup_inventory_take(pos, listname, index, stack, player)
end
local function can_dig_craftsup(pos, player)
local main = minetest.get_meta(pos):get_inventory():get_list(INV_MAIN) or {}
local inv = minetest.get_meta(pos):get_inventory()
local main = logistica.get_list(inv, INV_MAIN)
for i = 2, #main do
if not main[i]:is_empty() then return false end
end

View File

@ -39,7 +39,7 @@ end
-- returns true if something was crafted, false if nothing was crafted
-- optSourceListName is optional: if nil, no checks will be made if enough materials exist
function logistica.autocrafting_produce_single_item(inv, recipeList3x3Name, optSourceListName, outputListName)
local recipeList = inv:get_list(recipeList3x3Name) or {}
local recipeList = logistica.get_list(inv, recipeList3x3Name)
local craftRes = get_combined_crafting_ouputs(recipeList)
if craftRes.item:is_empty() then return false end
@ -53,7 +53,7 @@ function logistica.autocrafting_produce_single_item(inv, recipeList3x3Name, optS
if optSourceListName ~= nil then
-- check if source has enough materials
local recCounts = count_items(recipeList)
local srcCounts = count_items(inv:get_list(optSourceListName) or {})
local srcCounts = count_items(logistica.get_list(inv, optSourceListName))
for name, count in pairs(recCounts) do
if srcCounts[name] == nil or srcCounts[name] < count then return false end
end

View File

@ -108,7 +108,7 @@ end
function logistica.crafting_supplier_get_main_list(pos)
local isOn = logistica.is_machine_on(pos)
local inv = minetest.get_meta(pos):get_inventory()
local mainList = inv:get_list(INV_MAIN)
local mainList = logistica.get_list(inv, INV_MAIN)
if isOn then return mainList
else
local sublist = {}
@ -154,9 +154,9 @@ function logistica.take_item_from_crafting_supplier(pos, _takeStack, network, co
repeat
craftItemMult = craftItemMult + 1
--
local recipeItems = count_items_to_stack(inv:get_list(INV_CRAFT))
local recipeItems = count_items_to_stack(logistica.get_list(inv, INV_CRAFT))
-- use the output of any previous loop iterations to make it available to take from - except for the item we have to send to requester
local extrasListsMinusTarget = list_without_stack(inv:get_list(INV_HOUT), takeStack)
local extrasListsMinusTarget = list_without_stack(logistica.get_list(inv, INV_HOUT), takeStack)
local extrasMadeByCrafting = extrasListsMinusTarget.newList -- extra items output by the previous craft loops (aka substitutes)
-- consume items required to craft the item from the extras and network if needed
@ -188,7 +188,7 @@ function logistica.take_item_from_crafting_supplier(pos, _takeStack, network, co
if not dryRun then
local extraNotTaken = 0
local toInsert = {}
for _, st in ipairs(inv:get_list(INV_HOUT)) do
for _, st in ipairs(logistica.get_list(inv, INV_HOUT)) do
if st:get_name() == takeStackName then
extraNotTaken = extraNotTaken + st:get_count()
else
@ -198,7 +198,7 @@ function logistica.take_item_from_crafting_supplier(pos, _takeStack, network, co
taken:set_count(leftover + extraNotTaken)
if not taken:is_empty() then
local main = inv:get_list(INV_MAIN) or {}
local main = logistica.get_list(inv, INV_MAIN) or {}
for i = 2, #main do
taken = main[i]:add_item(taken)
end

View File

@ -33,7 +33,7 @@ function logistica.sort_item_storage_list(meta)
local sortFunc = sortFunctions[logistica.get_item_storage_selected_sort_index(meta)]
if not sortFunc then return end
local inv = meta:get_inventory()
local list = inv:get_list(ITEM_STORAGE_LIST)
local list = logistica.get_list(inv, ITEM_STORAGE_LIST)
local sortedList = sortFunc(list)
if not sortedList then return end
inv:set_list(ITEM_STORAGE_LIST, sortedList)

View File

@ -8,8 +8,8 @@ local BASE_TRANSFER_RATE = 10
local function mass_storage_room_for_item(pos, meta, stack)
local stackName = stack:get_name()
local maxNum = logistica.get_mass_storage_max_size(pos)
local filterList = meta:get_inventory():get_list("filter")
local storageList = meta:get_inventory():get_list("storage")
local filterList = logistica.get_list(meta:get_inventory(), "filter")
local storageList = logistica.get_list(meta:get_inventory(), "storage")
local roomForItems = 0
for i, storageStack in ipairs(filterList) do
if storageStack:get_name() == stackName then
@ -59,7 +59,7 @@ end
-- Returns a stack of how many items remain
function logistica.insert_item_into_mass_storage(pos, inv, inputStack, dryRun)
local maxItems = logistica.get_mass_storage_max_size(pos)
local numSlots = #(inv:get_list("filter"))
local numSlots = #(logistica.get_list(inv, "filter"))
local inputStackName = inputStack:get_name()
local indices = {}
for i = 1, numSlots do
@ -146,7 +146,7 @@ function logistica.try_to_add_player_wield_item_to_mass_storage(pos, player)
local pInv = player:get_inventory()
local pListName = player:get_wield_list()
local pList = pInv:get_list(pListName)
local pList = logistica.get_list(pInv, pListName)
for i, pInvStack in ipairs(pList) do
if pInvStack:get_name() == wieldStack:get_name() then
newStack = logistica.insert_item_into_mass_storage(pos, inv, pInvStack)
@ -215,7 +215,8 @@ function logistica.update_mass_storage_front_image(origPos, newParam2)
local meta = minetest.get_meta(pos)
local slot = logistica.get_mass_storage_image_slot(meta)
if slot > 0 then
local item = meta:get_inventory():get_list("filter")[slot] or ItemStack("")
local inv = meta:get_inventory()
local item = logistica.get_list(inv, "filter")[slot] or ItemStack("")
logistica.display_item_on_block_front(pos, item:get_name(), newParam2)
end
end
@ -226,7 +227,7 @@ function logistica.get_mass_storage_imgname_or_first_item(meta)
local index = meta:get_int(META_IMG_PIC)
local itemStack = inv:get_stack("filter", index)
if not itemStack:is_empty() then return "\n(Has: "..itemStack:get_description()..")" end
for _, v in ipairs(inv:get_list("filter")) do
for _, v in ipairs(logistica.get_list(inv, "filter")) do
if not v:is_empty() then return "\n(Has: "..v:get_description()..")" end
end
return "\n(Empty)"
@ -239,7 +240,7 @@ end
function logistica.update_mass_storage_cap(pos, optMeta)
local meta = optMeta or minetest.get_meta(pos)
local storageUpgrade = 0
local list = meta:get_inventory():get_list("upgrade") or {}
local list = logistica.get_list(meta:get_inventory(), "upgrade")
for _, item in ipairs(list) do
local upgradeDef = logistica.craftitem.storage_upgrade[item:get_name()]
if upgradeDef and upgradeDef.storage_upgrade then
@ -264,7 +265,7 @@ function logistica.can_remove_mass_storage_upgrade(pos, upgradeName)
if not upgradeDef or not upgradeDef.storage_upgrade then return true end
local inv = minetest.get_meta(pos):get_inventory()
local maxStored = 0
for _, st in ipairs(inv:get_list("storage") or {}) do
for _, st in ipairs(logistica.get_list(inv, "storage")) do
if st:get_count() > maxStored then maxStored = st:get_count() end
end
local currMax = logistica.get_mass_storage_max_size(pos)

View File

@ -175,6 +175,6 @@ function logistica.get_cache_list_for(position, meta, listName)
if nodeDef and nodeDef.logistica and nodeDef.logistica.get_cache_list then
return nodeDef.logistica.get_cache_list(position) or {}
else
return meta:get_inventory():get_list(listName) or {}
return logistica.get_list(meta:get_inventory(), listName)
end
end

View File

@ -193,7 +193,7 @@ function logistica.take_stack_from_item_storage(stack, network, collectorFunc, i
for storageHash, _ in pairs(network.item_storage) do
local storagePos = h2p(storageHash)
local storageInv = get_meta(storagePos):get_inventory()
local storageList = storageInv:get_list(ITEM_STORAGE_LIST_NAME) or {}
local storageList = logistica.get_list(storageInv, ITEM_STORAGE_LIST_NAME)
for i, storedStack in ipairs(storageList) do
if (not storedStack:is_empty()) and eq(storedStack, stack) then
local leftover = collectorFunc(storedStack)
@ -227,7 +227,7 @@ function logistica.take_stack_from_mass_storage(stackToTake, network, collectorF
local storagePos = h2p(storageHash)
local meta = get_meta(storagePos)
local storageInv = meta:get_inventory()
local storageList = storageInv:get_list(MASS_STORAGE_LIST_NAME) or {}
local storageList = logistica.get_list(storageInv, MASS_STORAGE_LIST_NAME)
-- we can't use the usual take/put methods because mass storage exceeds max stack
for i = #storageList, 1, -1 do -- traverse backwards for taking items
local storageStack = storageList[i]

View File

@ -66,7 +66,7 @@ local function get_valid_requester_and_target_inventory(requesterPos)
end
local function get_target_missing_item_stack(requestStack, invs)
local storageList = invs.targetInventory:get_list(invs.targetList)
local storageList = logistica.get_list(invs.targetInventory, invs.targetList)
local remaining = requestStack:get_count()
for i,_ in ipairs(storageList) do
local stored = storageList[i]
@ -91,7 +91,7 @@ local function get_next_requested_stack(pos, inventories)
if not inventories then return nil end
local nextSlot = logistica.get_next_filled_item_slot(get_meta(pos), "actual")
if nextSlot <= 0 then return nil end
return inventories.requesterInventory:get_list("actual")[nextSlot]
return logistica.get_list(inventories.requesterInventory, "actual")[nextSlot]
end
-- updates the inv list called 'actual' with the latest checked request
@ -105,7 +105,7 @@ local function update_requester_actual_request(pos)
local startingSlot = nextSlot
repeat
if nextSlot <= 0 then return nil end
local filterStack = requesterInv:get_list("filter")[nextSlot]
local filterStack = logistica.get_list(requesterInv, "filter")[nextSlot]
requestStack = get_target_missing_item_stack(filterStack, inventories)
local demStackCount = requestStack:get_count()
if demStackCount > 0 then
@ -136,7 +136,7 @@ end
-- returns 0 if no request, or the count of requested items
local function get_filter_request_for(requesterInventory, itemStackName)
local actualRequestList = requesterInventory:get_list("actual")
local actualRequestList = logistica.get_list(requesterInventory, "actual")
if not actualRequestList then return 0 end
for _, v in ipairs(actualRequestList) do
if v:get_name() == itemStackName then
@ -199,10 +199,9 @@ end
-- returns a list of ItemStacks tha represent the current requests of this requester
function logistica.get_requester_request(pos)
local inv = get_meta(pos):get_inventory()
local list = inv:get_list("filter")
if not list then return {} end
local list = logistica.get_list(inv, "filter")
local ret = {}
for k, v in list do
for k, v in ipairs(list) do
ret[k] = ItemStack(v)
end
return ret

View File

@ -55,7 +55,7 @@ function logistica.take_item_from_supplier(supplierPos, stackToTake, network, co
local remaining = stackToTake:get_count()
local supplierInv = minetest.get_meta(supplierPos):get_inventory()
local supplyList = supplierInv:get_list(META_SUPPLIER_LIST)
local supplyList = logistica.get_list(supplierInv, META_SUPPLIER_LIST)
for i, supplyStack in ipairs(supplyList) do
if i ~= optIgnorePosition and eq(supplyStack, stackToTake) then
local supplyCount = supplyStack:get_count()

View File

@ -7,7 +7,7 @@ function logistica.trashcan_trash_item(pos, inputStack)
local itemStackName = inputStack:get_name()
local inv = minetest.get_meta(pos):get_inventory()
if inv:is_empty(INV_FILT) then return ItemStack("") end
for _, filterStack in ipairs(inv:get_list(INV_FILT) or {}) do
for _, filterStack in ipairs(logistica.get_list(inv, INV_FILT)) do
if filterStack:get_name() == itemStackName then
return ItemStack("")
end

View File

@ -72,3 +72,9 @@ function logistica.add_allowed_pull_list(listName)
if not listName then return end
allowedPull[listName] = true
end
-- a safer way to get inv list, returns an empty table if something goes wrong
function logistica.get_list(inventory, listName)
if not inventory or not listName or type(listName) ~= "string" then return {} end
return inventory:get_list(listName) or {}
end