This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
tbot's profile picture

turtle.suckUp() taking 2 stacks

Started by tbot, 31 December 2013 - 11:33 AM
tbot #1
Posted 31 December 2013 - 12:33 PM
Hi all,

sorry to ask that, but i cant find my mistake in this simple turtle program i wrote. Somehow the suckUp() method takes 2 stacks instead just one and i cant find the mistake.
So i wanted to ask a Pro :)/>

I post the whole code so you can run it and see if it produces the same strange thing:




local function CheckSlots()
if (turtle.getItemCount(2) == 0) or (turtle.getItemCount(5) == 0) or (turtle.getItemCount(6) == 0) or (turtle.getItemCount(9) == 0) then

return false

else
--write ("true\n")
return true

end

end

local function ClearSlots()
write("ClearSlots - Running\n")
turtle.select(2)
turtle.dropUp()
turtle.select(5)
turtle.dropUp()
turtle.select(6)
turtle.dropUp()
turtle.select(9)
turtle.dropUp()
end

local function FillSlots()
write("FillSlots - Running\n")
turtle.select(2)
turtle.suckUp()
turtle.select(5)
turtle.suckUp()
turtle.select(6)
turtle.suckUp()
turtle.select(9)
turtle.suckUp()
end

local function FillStack()

write ("FillStack - Running\n")

if turtle.getItemCount(2) == 0 then
write ("Select Slot2\n")
turtle.select(2)
write ("Suck Slot2\n")
sleep(5)
turtle.suckUp()


end


if turtle.getItemCount(5) == 0 then
write ("Select Slot5\n")
turtle.select(5)
write ("Suck Slot5\n")
sleep(5)
turtle.suckUp()


end

if turtle.getItemCount(6) == 0 then
write ("Select Slot6\n")
turtle.select(6)
write ("Suck Slot6\n")
sleep(5)
turtle.suckUp()


end

if turtle.getItemCount(9) == 0 then
write ("Select Slot9\n")
turtle.select(9)
write ("Suck Slot9\n")
sleep(5)
turtle.suckUp()


end

write("FillStack - Finished\n")
end

local function DropResult()
turtle.select(16)
turtle.dropDown()
end


local function SpreadSlots()
write("SpreadSlots - Running\n")
sum = (turtle.getItemCount(9) + turtle.getItemCount(6) + turtle.getItemCount(5) + turtle.getItemCount(2))
result = math.floor((sum/4) + 0.5)
space = ' '
-- write (sum..space..result.."\n")

ClearSlots()

turtle.select(2)
turtle.suckUp()
turtle.dropUp((turtle.getItemCount(2)-result))

turtle.select(5)
turtle.suckUp()
turtle.dropUp((turtle.getItemCount(5)-result))

turtle.select(6)
turtle.suckUp()
turtle.dropUp((turtle.getItemCount(6)-result))

turtle.select(9)
turtle.suckUp()


end

local function CleanInventory()
write("CleanInventory - Running\n")
turtle.select(3)
turtle.dropUp()
turtle.select(7)
turtle.dropUp()
turtle.select(10)
turtle.dropUp()
end


local function Production()

while true do

write("Production Check\n")
sleep(5)

if CheckSlots() == false then
write("CheckSlots - false\n")
FillStack()
if turtle.suckUp() == false then
write("SuckUp - false\n")
SpreadSlots()
end

end

if CheckSlots() == true then
turtle.select(16)
turtle.craft()
DropResult()
end
end
end


-- Hauptprogramm:

ClearSlots()
CleanInventory()
FillSlots()
Production()
Bomb Bloke #2
Posted 31 December 2013 - 07:16 PM
At a glance, I'm guessing you might have your problem at this line near the end:

if turtle.suckUp() == false then

In order to see what the result of calling turtle.suckUp() is, the turtle will indeed attempt to suck - same as any time you call that function. If you want to know the result of calling the FillStack() function, have that return something.
tbot #3
Posted 31 December 2013 - 08:32 PM
At a glance, I'm guessing you might have your problem at this line near the end:

if turtle.suckUp() == false then

In order to see what the result of calling turtle.suckUp() is, the turtle will indeed attempt to suck - same as any time you call that function. If you want to know the result of calling the FillStack() function, have that return something.

Ill try that!

Funny thing, i wrote the code 2 days ago and everything just worked like a charm, today i wanted to show it to a friend and it started to draw 2 stacks every time it ran threw the FillStack() function.
So i put all the write and sleep parts to see exactly in which part of the api the 2nd stack appears.

So what i found out is that it leaves the FillStack() function and hops back into the Production() Function. But the second stack is already there so the production() function can not work properly anymore as the recipe is not correct anymore. And actually if the turtle.suckUp() check in the Production() function is called it would write in the console "SuckUp - false" which it does not.

So my guess is that the mistake happens somewhere in the FillStack() function.
The only thing that happens there is that it runs into 1 if statement and runs turtle.suckUp() once.
Thats why im here now :(/>

Ok you were right, it was exactly this problem.
When it checked if turtle.suckUp() was possible it sucked a second stack.

So how do i check if there are still stacks in the upper box without sucking a second stack? :)/>
Bomb Bloke #4
Posted 31 December 2013 - 10:16 PM
I'm afraid a vanilla turtle has no way of knowing whether there's an item in a container, short of by trying to pull that item out…

Assuming you have access to MiscPeripherals or OpenPeripheral, you can likely find access to a type of turtle that can do what you want.

Alternatively, depending on the type of container, you may just be able to shove the item stack right back where it came from.
Farrk #5
Posted 01 January 2014 - 12:09 PM
With OpenPeripherals it would go like

local function isBoxEmpty()
local box=peripheral.wrap("top")
for i=1,box.getInventorySize() do -- or box.getInvSize() , cant recall without launching game
if m.getStackInSlot(i)~= nil then
  return false
end
sleep(0)
end
return true
end

Then you just need to call this function instead of turtle.suckUp() in that place where you check if it is empty.
Edited on 01 January 2014 - 11:11 AM
tbot #6
Posted 01 January 2014 - 09:00 PM
I'm afraid a vanilla turtle has no way of knowing whether there's an item in a container, short of by trying to pull that item out…

Assuming you have access to MiscPeripherals or OpenPeripheral, you can likely find access to a type of turtle that can do what you want.

Alternatively, depending on the type of container, you may just be able to shove the item stack right back where it came from.

I changed now the code to this:


local function FillStack()

if turtle.getItemCount(2) == 0 then
   turtle.select(2)
      if turtle.suckUp() == false then
         SpreadSlots()
      end
end
if turtle.getItemCount(5) == 0 then
   turtle.select(5)
      if turtle.suckUp() == false then
         SpreadSlots()
      end
end
if turtle.getItemCount(6) == 0 then
   turtle.select(6)
      if turtle.suckUp() == false then
         SpreadSlots()
      end
end

if turtle.getItemCount(9) == 0 then
   turtle.select(9)
      if turtle.suckUp() == false then
         SpreadSlots()
      end
end
end


And its working now. Thanks for the hints to the other OpenPeripherals ill give it try and see what i can do with it.

BTW is there any future plans to change turtle.suck() so you can define how many units you want to suck? Cause im having a problem with a other part of my code and had to fix it in a very mangy way :)/>