Panakotta00 / FicsIt-Networks

Control, Monitor, Manage and Automate your Satisfactory.
https://ficsit.app/mod/FicsItNetworks
GNU General Public License v3.0
156 stars 51 forks source link

inventory bug? #178

Closed kfpopeye closed 2 years ago

kfpopeye commented 2 years ago

I'm trying to use the code below to list the contents of a storage container but I'm not getting the expected output.

When I first run the program it works fine but when I remove a couple items from the container and run the program a second time there is no change in the list from the first run. Also if I save the game and then run the lua program the list is updated properly.

Am I missing a way to refresh the container contents?

-- total all the items in the countainer
function inventoryTheContainer()
 print(computer.time(), "Inventory the container.")
 local invTable = {}
 local invs = nil
 invs = container:getInventories(invs)
 invs[1]:sort()
 i = 0
 while (i < invs[1].Size) do
  t = invs[1]:getStack(i).item.type
  if(t ~= nil) then
   n = t.internalName
   c = invs[1]:getStack(i).count
   print(i, n, c)
   if (invTable[n] == nil) then
    invTable[n] = c
   else
    invTable[n] = invTable[n] + c
   end
  else
   print(i, "blank")
  end
  i = i + 1
 end
 return invTable
end

function printTablePairs(t)
 print("Table pairs")
 i = 0
 for a, b in pairs(t) do
  print(i, a, b)
  i = i + 1
 end
end

--main chuck
container = component.proxy("08BC875F4652A329EBC31793BFECB856")
inventoryCurrent = {}
inventoryCurrent = inventoryTheContainer()
--printTablePairs(inventoryCurrent)

I also noticed the internal name of some of the items are incorrect. See below:

  1. Desc_ModularFrameLightweight_C was actually Radio Control Unit
  2. Desc_CircuitBoardHighSpeed_C 100 was actually AI Limiter
  3. Desc_AluminumPlateReinforced_C 39 was actually Heat Sink
VoiD2008 commented 2 years ago

I have almost the same issue My network is: 1 - computer 5 - containers 1 - screen

when I'm trying to get containers items only one container updating its count

my code is: ( this is one of variants in this iteration i tryed reinstanciate component.proxy each loop iteration )

local gpu = computer.getPCIDevices(findClass("GPUT1"))[1]

-- below code is for screen output --
local tableBuffer = {}
local tableBufferPos = {}
local tableBufferColor = {}
local w, h
local tick = 0

local gpuClear = function()
    gpu:fill(0, 0, w, h, " ")
end

function gpuInit(s)
    hh = 10
    ww = 30
    sw, sh = s: getSize()
    hh = sh*2
    ww = sw*4
    gpu:bindScreen(s)
    gpu:setSize(ww, hh)
    w, h = gpu:getSize()
    gpuClear()
end

function sleep(n)
    event.pull(n)
end

function printToScreen(text, x, y,color)
    local nx, ny, cl
    if x == nil then
        nx = 0
    else 
        nx = x 
    end
    if y == nil then 
        ny = 0
    else 
        ny = y 
    end
    if color == nil then color = {1,1,1,1} end
    gpu:setForeground(color[1],color[2],color[3],color[4])
    gpu:setText(nx, ny, text)
    gpu:flush()
end

function printBuffer()
    gpuClear()
    for i = 1, #tableBuffer do
        printToScreen(tableBuffer[i], tableBufferPos[i], i - 1, tableBufferColor[i])
    end
end

function clearScreen()
    tableBuffer = {}
    tableBufferPos = {}
    tableBufferColor = {}
end

function printLnTS(text, start, color)
    fl = start
    if start == nil then
        fl = 1
    end
    if color == nil then
      color = {1,1,1,1}
    end
    table.insert(tableBuffer, #tableBuffer + 1, text)
    table.insert(tableBufferPos, #tableBufferPos + 1, fl)
    table.insert(tableBufferColor, #tableBufferColor + 1, color)
    while #tableBuffer > h do
        table.remove(tableBuffer, 1)
        table.remove(tableBufferPos, 1)
        table.remove(tableBufferColor, 1)
    end
    printBuffer()
end

local f = false
function transliterate(text)
    local textBuffer = ""
    local charCodes = {c384 = "a",c385 = "b",c386 = "v",c387 = "g",c388 = "d",c389 = "e",c354 = "e",c390 = "zh",c391 = "z",c392 = "i",c393 = "yi",c394 = "k",c395 = "l",c396 = "m",c397 = "n",c398 = "o",c399 = "p",c337 = "r",c338 = "s",c339 = "t",c340 = "u",c341 = "f",c342 = "h",c343 = "c",c344 = "ch",c345 = "sh",c346 = "sch",c350 = "e",c351 = "yu",c352 = "ya",c353 = "B",c354 = "V",c355 = "G",c356 = "D",c357 = "E",c358 = "ZH",c359 = "Z",c360 = "I",c361 = "YI",c362 = "K",c363 = "L",c364 = "M",c365 = "N",c366 = "O",c367 = "P",c368 = "R",c369 = "S",c370 = "T",c371 = "U",c372 = "F",c373 = "H",c374 = "C",c375 = "CH",c376 = "SH",c377 = "SCH",c381 = "E",c382 = "YU",c383 = "YA",c348 = "ii",c379 = "II",c349 = "~",c380 = "~",c347 = "~",c378 = "~"}
    for i = 1, #text do
        if f == false then
            local bt = string.byte(text, i)
            if bt == 208 or bt == 209 then
                local char = charCodes["c"..string.byte(text, i) + string.byte(text, i + 1)]
                if not char then
                    textBuffer = textBuffer.."_"
                else
                    textBuffer = textBuffer..char
                end
                f = true
            else
                textBuffer = textBuffer..string.sub(text, i, i)
            end
        else
            f = false
        end
    end
    return textBuffer
end

function trailing(str,cr,length)
  if #str < length then
    return string.rep(cr,length-#str) .. str
  else
    return str
  end
end

function printColorString(v,i)
  color = {1,0,0,1}
  if v.productivity > 0.9 then
    color = {0,1,0,1}
  else
    if v.productivity > 0.5 then
      color = {1,1,0,1}
    end
  end
  printLnTS(trailing(tostring(i)," ",2).." : "..trailing(tostring(math.ceil(v.progress*100))," ",3).."%".." Efficiency: "..trailing(tostring(math.ceil(v.productivity*100))," ",3).."%",nil,color)
end
-- above code is for screen output --

local screens = component.proxy(component.findComponent(findClass("Build_Screen_C")));
if #screens then
    gpuInit(screens[1])
    q = component.findComponent(findClass("Build_StorageContainerMk2_C"))
    containers = {}
    dataTable = {}
    titleTable = {}

while true do
dataTable = {}
    for _,v in pairs(q) do
      t = component.proxy(v)
      local inventories = t: getInventories()
      local size = inventories[1].size
      for i = 0, size-1 do
        local stack = inventories[1]:getStack(i)
        if stack.item.type ~= nil then
-- saving item hash -> count 
          dataTable[stack.item.type.hash] = (dataTable[stack.item.type.hash] and dataTable[stack.item.type.hash] + stack.count or stack.count)
-- saving item hash -> names if not exists
          if not titleTable[stack.item.type.hash] then titleTable[stack.item.type.hash] = transliterate(stack.item.type.name) end
        end

      end
    end
    clearScreen()
    printLnTS(tostring(tick)..string.rep("=", w), 0)
    printLnTS(transliterate("Содержимое "..tostring(#q).." контейнеров:"))
    printLnTS(string.rep("=", w), 0)
    for _,v in pairs(dataTable) do
-- printing to screen line by line each count from data table
      printLnTS(titleTable[_]..":"..tostring(v))
    end
-- reseting table for next iteration
        dataTable = nil
        sleep(1)
        tick = tick + 1
    end
end
lucasmaurice commented 2 years ago

Same issue for me, the values get updated after a few minutes when I change the content of the storage manually:

-- VARIABLES
storages = {"STATOR", "ROTOR", "MOTOR"}
containers = {}
inventories = {}

-- INIT
count=1
for _,storage in pairs(storages) do
  containers[count] = component.proxy(component.findComponent(storage .. "_STORAGE"))[1]
  inventories[count] = containers[count]:getInventories()[1] 
  count = count + 1 
end

panel = component.proxy(component.findComponent("MotorControlPanel"))[1]
display = panel:getModule(2,4)
display.size = 30
LED = panel:getModule(2,8)

-- FUNCTIONS
function getContainerType(inventory)
    first_type = nil
    for stack_number = 0, inventory.size-1, 1 do
      type = inventory:getStack(stack_number).item.type
      if type ~= nil then
        if first_type == nil then
          first_type = type
        else
          if first_type ~= type then
            return false
          end
        end
      end
    end
    return first_type
end

-- MAIN LOOP
while true do
  txt = ""
  for _,inventory in pairs(inventories) do
    type = getContainerType(inventory)
    if type then
      name = type.name
    else
      name = "Multi"
    end
    txt = txt .. name .. " - " .. inventory.itemCount .. " items\n"
  end
  display.text = txt
  event.pull(0.05)
  LED:setColor(255,0,0,0)
  event.pull(1.0)
  LED:setColor(255,0,0,0.01)
end
RozeDoyanawa commented 2 years ago

I have now tested this bug, and I can confirm it. The itemCount and inventories does not update until a change occurs on the factoryConnectors. Using belts, pulling out or inserting new items into the container immediately updates the counts, but without a factory connector trigger, it just sits there showing the inventory from when the computer was first ran,

As such, manually manipulating a containers content is Not reflected in FIN. Very weird.

woodwardkw commented 2 years ago

Any updates on this issue?

scatterlogical commented 2 years ago

Yeah I confirm this too. Can this issue please be prioritized. Inventory management is basically impossible without inventory updating properly, and I would say this is a major use of ficsit-networks.

Panakotta00 commented 2 years ago

We already know and we are investigating, its just not simple...

scatterlogical commented 2 years ago

Thanks, I appreciate your efforts.

scatterlogical commented 2 years ago

As a potential workaround, I have found that using storage:getFactoryConnectors()[1]:getInventory().itemCount will provide a properly updated inventory count

woodwardkw commented 2 years ago

As a potential workaround, I have found that using storage:getFactoryConnectors()[1]:getInventory().itemCount will provide a properly updated inventory count

Awesome news... I'll give that a try. :-)

theVosCache commented 2 years ago

As a potential workaround, I have found that using storage:getFactoryConnectors()[1]:getInventory().itemCount will provide a properly updated inventory count

I have the same problem and this fixed it for me.

scatterlogical commented 2 years ago

Yeah unfortuanately it doesn't work for some things, like the item dispenser mod since that doesn't seem to provide the proper factory connections. So it really is just a workaround

VoltairesPuppet commented 2 years ago

You can also cause it to update if you use the dismantle build tool (F key) and look at the container; presumably because it displays a summary of the contents and associated build resources.

kfpopeye commented 2 years ago

Yup. This works nicely.