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

Check Inventory For More Blocks

Started by andrewhopps, 02 November 2013 - 09:50 AM
andrewhopps #1
Posted 02 November 2013 - 10:50 AM
As with most who post questions on here, I am piecing things together one issue at a time and my floor program is fully functioning except for the inventory. Upon running out of blocks, it cycles through the inventory infinitely. I want the turtle to scan for more blocks of the same type in all slots available (2-15) one time, if there is nothing useable, wait for user to input useable material and hit a key. It will then scan the inventory completely one time to find the placed in item and continue running, if not found, pester the user some more. I have had a good many variations of attempts at figuring this out, but am beyond confused at what needs to be done. A little guidance would be very helpful!


local function checkInv()
	turtle.getItemCount( inventory )
	while turtle.getItemCount( inventory ) == 1 do
		for slot = 2, 15 do
			turtle.select ( slot )
			if turtle.getItemCount( slot ) > 0 and turtle.compareTo( inventory ) == true then
				turtle.transferTo( inventory )
				turtle.select( inventory )
				break
			end
		end
	end	
end

I removed any indication of waiting for user input, that is not my issue, mainly just the inventory cycling crazily.
Edited on 02 November 2013 - 10:09 AM
sens #2
Posted 02 November 2013 - 11:24 AM
Seems like you're on the right track already. I'd suggest some variations to reduce the number of slot selections, and using an event to listen for changes to the inventory:


local function checkInv()
  turtle.select ( inventory )
  while turtle.getItemCount( inventory ) == 1 do
	for slot = 2, 15 do
	  if turtle.getItemCount( slot ) > 0 and turtle.compareTo( slot ) == true then
		turtle.select( slot )
		turtle.transferTo( inventory )
		turtle.select( inventory )
		--# Great, we're done
		return
	  end
	end
	--# Pester
	print("Out of materials, add more of the same type as slot "..inventory)
	--# Wait for user to do something
	local event, p1 = os.pullEvent("turtle_inventory")
  end	
  if(turtle.getItemCount( inventory ) == 0)
    --# Nothing in the inventory slot, oh dear.
    error("Please refill slot "..inventory)
  end
end

Now the function will only return once the user adds compatible items. (100% untested)
andrewhopps #3
Posted 02 November 2013 - 11:48 AM
Seems like you're on the right track already. I'd suggest some variations to reduce the number of slot selections, and using an event to listen for changes to the inventory:


local function checkInv()
  turtle.select ( inventory )
  while turtle.getItemCount( inventory ) == 1 do
	for slot = 2, 15 do
	  if turtle.getItemCount( slot ) > 0 and turtle.compareTo( slot ) == true then
		turtle.select( slot )
		turtle.transferTo( inventory )
		turtle.select( inventory )
		--# Great, we're done
		return
	  end
	end
	--# Pester
	print("Out of materials, add more of the same type as slot "..inventory)
	--# Wait for user to do something
	local event, p1 = os.pullEvent("turtle_inventory")
  end	
  if(turtle.getItemCount( inventory ) == 0)
	--# Nothing in the inventory slot, oh dear.
	error("Please refill slot "..inventory)
  end
end

Now the function will only return once the user adds compatible items. (100% untested)

Turtle inventory is as such for testing purposes: [1] Dirt [2] Stone [3] Dirt
When the turtle runs out of blocks in Slot 1, I see it go to Slot 2, stops on Slot 2, and then ask for more blocks. Although there is more dirt in it's inventory in another slot.
sens #4
Posted 02 November 2013 - 11:57 AM
Well, then the same principle applies:


local function checkInv(inventory)
  turtle.select ( inventory )
  while turtle.getItemCount( inventory ) == 1 do
	for slot = 1, 15 do
	  if slot ~= inventory and turtle.getItemCount( slot ) > 0 and turtle.compareTo( slot ) == true then
		turtle.select( slot )
		turtle.transferTo( inventory )
		--# Done checking this material
		return
	  end
	end
	--# Pester
	print("Out of materials, add more of the same type as slot "..inventory)
	--# Wait for user to do something
	local event, p1 = os.pullEvent("turtle_inventory")
  end	
  if(turtle.getItemCount( inventory ) == 0)
	--# Nothing in the inventory slot, oh dear.
	error("Please refill slot "..inventory)
  end
end

--# Call it for each material (dirt, stone...)
for slotIdx = 1, 3 do
  checkInv(slotIdx)
end
andrewhopps #5
Posted 02 November 2013 - 12:22 PM
Well, then the same principle applies:

I am terribly confused where what should be now and turtle skips placing blocks while rummaging through inventory.


print( "How long would you like the first side to be? This will be the first length" )
local a = io.read()
local length = tonumber( a )
term.clear()
term.setCursorPos(1, 1)
print( "How long would you like the width to be?" )
local b = io.read()
local width = tonumber( b )
term.clear()
term.setCursorPos(1, 1)
local area = tonumber(a) * tonumber(B)/>/>/>/>
local counterLength = 1
local counterWidth = 1
local inventory = 1
local direction = 0
print( "This will require " .. area .. " blocks. Please insert as many as you can in Slots 1-15. Then press any key." )
os.pullEvent ( "key" )
local fuelRequired = a * b * 3 / 80
local function floor()
turtle.digDown()
  turtle.placeDown()
   counterLength = counterLength + 1
	turtle.forward()
end
local function checkInv(inventory)
  turtle.select ( inventory )
  while turtle.getItemCount( inventory ) == 1 do
		for slot = 1, 15 do
		  if slot ~= inventory and turtle.getItemCount( slot ) > 0 and turtle.compareTo( slot ) == true then
				turtle.select( slot )
				turtle.transferTo( inventory )
				--# Done checking this material
				return
		  end
		end
		--# Pester
		print("Out of materials, add more of the same type as slot "..inventory)
		--# Wait for user to do something
		local event, p1 = os.pullEvent("turtle_inventory")
  end  
  if(turtle.getItemCount( inventory ) == 0)
		--# Nothing in the inventory slot, oh dear.
		error("Please refill slot "..inventory)
  end
end
--# Call it for each material (dirt, stone...)
for slotIdx = 1, 3 do
  checkInv(slotIdx)
end
while true do
if turtle.getFuelLevel() < fuelRequired then
  print( "A total of " .. math.ceil(fuelRequired) .. "pieces of coal are required to finish." )
  print( "Please insert " .. math.ceil(fuelRequired) .. " into Slot 16 and press any key to begin." )
  os.pullEvent ("key")
  turtle.select( 16 )
  turtle.refuel(  math.ceil(fuelRequired) )
  turtle.select( 1 )
end

checkInv()
print( "Building..." )

floor()


if counterLength == length then
  if direction == 0 then
   turtle.digDown()
	turtle.placeDown()
	 turtle.turnRight()
	  turtle.forward()
	   turtle.turnRight()
		 direction = 1
	   counterLength = 1
		counterWidth = counterWidth +1
end
	
end

  if counterLength == length then
  if direction == 1 then
	  turtle.digDown()
		  turtle.placeDown()
		turtle.turnLeft()
			turtle.forward()
			 turtle.turnLeft()
		direction = 0
		counterLength = 1
			 counterWidth = counterWidth +1
   end

	
end

   if counterWidth == width + 1 then
	term.clear()
term.setCursorPos(1,1)
print( "Platform is complete!" )
	 os.pullEvent( "key" )
	  startup()
   end
  

   end
sens #6
Posted 02 November 2013 - 01:09 PM
Three final suggestions:
-Clean up the indentation to make it more clear
-Remove the line "local inventory = 1"
-"checkInv()" takes a slot number as an argument now, so for example, you would call checkInv(1) to check the first slot.

You're welcome.
andrewhopps #7
Posted 03 November 2013 - 04:01 AM
I feel like I am getting further away from where I was. This is not working anywhere close to what I was heading for, and has more issues. If there are enough blocks in slot 1, it runs ok. If not, it goes to slot 2 and tells me to put more of slot 2 supplies in, which in example was stone and not what i want being placed. The event also does not trigger if I add or remove items to any slot, forcing me to Ctrl + T to stop the program. Then subsequent runs, slot 2 stays selected and checks slot one for material that matches itself, which again, is stone. So I don't understand what is going on here.

print( "Hello! I can make a platform, say you need a floor or a roof or just a flat surface I can do it" )
print( "Push any key to continue" )
os.pullEvent( "key" )
term.clear()
term.setCursorPos(1, 1)

print( "Place me in the bottom left corner that you would like to be your platform." )
print( "Push any key to continue" )
os.pullEvent( "key" )
term.clear()
term.setCursorPos(1, 1)

print( "How long would you like the first side to be? This will be the first length" )
local a = io.read()
local length = tonumber( a )
term.clear()
term.setCursorPos(1, 1)

print( "How long would you like the width to be?" )
local b = io.read()
local width = tonumber( b )
term.clear()
term.setCursorPos(1, 1)

local area = tonumber(a) * tonumber(B)/>/>
local counterLength = 1
local counterWidth = 1
local direction = 0

print( "This will require " .. area .. " blocks. Please insert as many as you can in Slots 1-15. Then press any key." )
os.pullEvent ( "key" )

local fuelRequired = a * b * 3 / 80

local function floor()
	turtle.digDown()
	turtle.placeDown()
	counterLength = counterLength + 1
	turtle.forward()
end

local function checkInv(inventory)
	turtle.select ( inventory )
	while turtle.getItemCount( inventory ) == 1 do
		for slot = 1, 15 do
			if slot ~= inventory and turtle.getItemCount( slot ) > 0 and turtle.compareTo( slot ) == true then
				turtle.select( slot )
				turtle.transferTo( inventory )
				--# Done checking this material
			return
			end
		end
		
		--# Pester
		print("Out of materials, add more of the same type as slot "..inventory)
		
		--# Wait for user to do something
		local event, p1 = os.pullEvent("turtle_inventory")
	end  
	
	if(turtle.getItemCount( inventory ) == 0) then
		--# Nothing in the inventory slot, oh dear.
		error("Please refill slot "..inventory)
	end
end

--# Call it for each material (dirt, stone...)
for slotIdx = 1, 3 do
	checkInv(slotIdx)
end


while true do
	if turtle.getFuelLevel() < fuelRequired then
		print( "A total of " .. math.ceil(fuelRequired) .. "pieces of coal are required to finish." )
		print( "Please insert " .. math.ceil(fuelRequired) .. " into Slot 16 and press any key to begin." )
		os.pullEvent ("key")
		turtle.select( 16 )
		turtle.refuel(  math.ceil(fuelRequired) )
		turtle.select( 1 )
	end

	checkInv(1)
	print( "Building..." )

	floor()


	if counterLength == length then
		if direction == 0 then
			turtle.digDown()
			turtle.placeDown()
			turtle.turnRight()
			turtle.forward()
			turtle.turnRight()
			direction = 1
			counterLength = 1
			counterWidth = counterWidth +1
		end
	end	

	if counterLength == length then
		if direction == 1 then
			turtle.digDown()
			turtle.placeDown()
			turtle.turnLeft()
			turtle.forward()
			turtle.turnLeft()
			direction = 0
			counterLength = 1
			counterWidth = counterWidth +1
		end
	end	

	if counterWidth == width + 1 then
		term.clear()
		term.setCursorPos(1,1)
		print( "Platform is complete!" )
		os.pullEvent( "key" )
		startup()
	end
end
Bomb Bloke #8
Posted 03 November 2013 - 05:00 AM
This:

local a = io.read()
local length = tonumber( a )

… could just be written as:

local length = tonumber( read() )

The variable "B" referenced lower down is not the same thing as the variable "b" referenced earlier, though I suspect that's just these forums trying to be "helpful" and not an error you've made (still, why not stick with "length" and "width" for easier reading?):

local area = tonumber(a) * tonumber(B)/>/>

"turtle.compareTo( slot ) == true" can simply be written as "turtle.compareTo( slot )". That function already returns true or false, you don't need to check on that. Were you wanting to use "turtle.compareTo( slot ) == false", it'd instead be better to use just "not turtle.compareTo( slot )".

"fuelRequired" is set up to track how many bits of coal the turtle needs to complete the operation. Comparing it directly to "turtle.getFuelLevel()" may not be what you want to do (though it'll technically "work", the turtle may stop rather unpredictably while working).

If "checkInv()" has restocked a slot, then the slot the resources came from will remain selected. This will cause problems unless that source slot happened to have a full stack in it beforehand.

Your turning check could be condensed somewhat. For starters, there's no need to check if "counterLength == length" twice!

If the turtle needs to turn, but just used up its second-to-last block before doing so, then it'll go ahead and use the last block before calling "checkInv()" again.

I'm not sure what the "startup()" line is supposed to do - as far as I'm aware, it'll crash unless you actually define a function with that title. If you want the turtle to restart (and hence run its startup script from scratch) use "os.reboot()".

Apparently the "turtle_inventory" event didn't exist until ComputerCraft version 1.55, which requires MineCraft 1.6.2. I'm guessing you don't have it (in which case you should stick with "key" events).
andrewhopps #9
Posted 03 November 2013 - 05:27 AM
This:

Well I fixed most of the above, minus the fuelRequired, currently working in a way I understand at this point. And ComputerCraft is 1.53 (Stupid FTB) And the whole checkInv() is beyond my comprehension now and is at this point code that I hoped would just work. I believe this is functioning properly, still testing having blocks in other slots.

print( "Hello! I can make a platform, say you need a floor or a roof or just a flat surface I can do it" )
print( "Push any key to continue" )
os.pullEvent( "key" )
term.clear()
term.setCursorPos(1, 1)

print( "Place me in the bottom left corner that you would like to be your platform." )
print( "Push any key to continue" )
os.pullEvent( "key" )
term.clear()
term.setCursorPos(1, 1)

print( "How long would you like the first side to be? This will be the first length" )
local length = tonumber( io.read() )
term.clear()
term.setCursorPos(1, 1)

print( "How long would you like the width to be?" )
local width = tonumber( io.read() )

term.clear()
term.setCursorPos(1, 1)

local area = tonumber(length) * tonumber(width)
local counterLength = 1
local counterWidth = 1
local direction = 0
local inventory = 1

print( "This will require " .. area .. " blocks. Please insert as many as you can in Slots 1-15. Then press any key." )
os.pullEvent ( "key" )

local fuelRequired = length * width * 3 / 80

local function floor()
    turtle.digDown()
    turtle.placeDown()
    counterLength = counterLength + 1
    turtle.forward()
end

local function checkInv(inventory)
    turtle.select ( inventory )
    while turtle.getItemCount( inventory ) == 1 do
        for slot = 2, 15 do
            if slot ~= inventory and turtle.getItemCount( slot ) > 0 and turtle.compareTo( slot ) then
                turtle.select( slot )
                turtle.transferTo( inventory )
                turtle.select( inventory )
                --# Done checking this material
            return
            end
        end
        
        --# Pester
        print("Out of materials, add more of the same type as slot "..inventory)
        
        --# Wait for user to do something
        local event, p1 = os.pullEvent("key")
    end  
end

while true do
    if turtle.getFuelLevel() < fuelRequired then
        print( "A total of " .. math.ceil(fuelRequired) .. "pieces of coal are required to finish." )
        print( "Please insert " .. math.ceil(fuelRequired) .. " into Slot 16 and press any key to begin." )
        os.pullEvent ("key")
        turtle.select( 16 )
        turtle.refuel(  math.ceil(fuelRequired) )
        turtle.select( 1 )
    end

    checkInv(1)
    print( "Building..." )

    floor()


    if counterLength == length then
        if direction == 0 then
            turtle.digDown()
            turtle.placeDown()
            turtle.turnRight()
            turtle.forward()
            turtle.turnRight()
            direction = 1
            counterLength = 1
            counterWidth = counterWidth +1
        
        else
            turtle.digDown()
            turtle.placeDown()
            turtle.turnLeft()
            turtle.forward()
            turtle.turnLeft()
            direction = 0
            counterLength = 1
            counterWidth = counterWidth +1
        end
    end    

    if counterWidth == width + 1 then
        term.clear()
        term.setCursorPos(1,1)
        print( "Platform is complete!" )
        sleep(3)
        os.reboot()
    end
end