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

Detecting and dumping items...

Started by SyberSmoke, 04 May 2013 - 10:45 PM
SyberSmoke #1
Posted 05 May 2013 - 12:45 AM
I have been messing around with turtle programs some and the basic of basic commands. But I have been hung up a little on how to make my very dumb looping kill turtle dump items it collects.

Setup:
I have built a setup where chickens are bred, eggs are tossed to make more, then are sluiced into a kill chamber where a turtle whacks them to death. The turtle then collects the goodies…but does not dump them.

I manually added into the loop a item slot change and dump down, but without doing the same thing 16 times, items are always stuck somewhere. So I was wondering about how to make it so the turtle will detect an item and dump those items every so often…say after the turtle has chopped up all the chickens or other mob really.

I have looked and did not see anything simple like this so…asking is the next step.
grand_mind1 #2
Posted 05 May 2013 - 12:52 AM
Could you please post your current code? It would make it easier to help you.
SyberSmoke #3
Posted 05 May 2013 - 01:09 AM
That is hard as I did it entirely in the turtle I was messing with.

The gist is:

while true do
turtle.attack()
turtle.select(1)
turtle.dropDown()
turtle.select(2)
turtle.dropDown()
turtle.select(3)
turtle.dropDown()
end

I have never done anything like this before and graphic art has been my thing. So I have been dabbling but this is all very outside my knowledge base.
Smiley43210 #4
Posted 05 May 2013 - 01:22 AM
Use a for loop to drop the whole inventory.
for i=1,16 do
  turtle.dropDown(i)
end
And to do it every so often, just dump it all after x attacks. Count the number of attacks, and after x amount, dump it all, and start attacking again.
grand_mind1 #5
Posted 05 May 2013 - 01:22 AM
So you want to dumb everything a turtle has in it's inventory into a chest? Well you could use a for loop like so:

for i = 1,16 do --run the loop for every 16 slots in the turtle
  turtle.select(i) --select the current i
  turtle.dropDown() --drop it
end

EDIT:Ninja!!
SyberSmoke #6
Posted 05 May 2013 - 02:11 AM
Use a for loop to drop the whole inventory.
for i=1,16 do
  turtle.dropDown(i)
end
And to do it every so often, just dump it all after x attacks. Count the number of attacks, and after x amount, dump it all, and start attacking again.

Ok, I think that makes sense. At least the variables look like they make sense. Same for the post after, thanks for the notes by the way. So it was mentioned to count the attacks the turtle makes, mind demonstrating that?

It is interesting, I can read what is being demonstrated and understand it. But the link between understanding it and writing it is still elusive. But hey, time and patience leads to learning.
grand_mind1 #7
Posted 05 May 2013 - 02:29 AM
To count the number of attacks you could simply add 1 to a variable every time a turtle attacks like so:

totalAttacks = 0 --defines the variable
for i = 1,10 do --run the loop 10 times
  turtle.attack() --attack
  totalAttacks = totalAttacks+1 --add one to totalAttacks
end
This is, of course, just a sample program and is probably not exactly how you will have it in your code. If you want to drop all of the items after the turtles has attacked a number of times there are multiple things you could do. The easiest(in my opinion) would be to use the modulo operator. The modulo operator(represented as %) can be used to get the remainder of a certain division calculation. For example:

10%2=0 because 10 divided by 2 has a remainder of 0.
5%3=2 because 5 divided by 3 has a remainder of 2.

Using this, we can detect when the number of attacks is divisible by, let's say 10.

totalAttacks = 0 --defines the variable
for i = 1,10 do --run the loop 10 times
  turtle.attack() --attack
  totalAttacks = totalAttacks+1 --add one to totalAttacks
  if totalAttacks%10 == 0 then --check if it is divisible by 10
	--drop off all of it's inventory
  end
end
If you have any more questions feel free to ask! :D/>
SyberSmoke #8
Posted 05 May 2013 - 03:00 AM
So if I am reading this properly. The above represents the attack portion of the script. Every time the turtle reaches the designated number of attacks, it will then run the next loop? Or does the dump code require variables to recognize that the attack code has reached the threshold and activates at that point?

It does make sense though…

Oh now I see it…the if totalAttacks activates the dump lines mentioned in previous posts but should be inserted into that space.
grand_mind1 #9
Posted 05 May 2013 - 03:04 AM
I also forgot to mention that you could also just detect when the inventory of the turtle is full like so:

if turtle.getItemCount(16) == 64 then
  --drop off stuff
end
(You would use this if you didn't want to drop off at exact intervals. Instead it would just drop off whenever it needed to)
Also, if you wanted it to run forever instead of just 10 times like it was above you could replace to for loop with a while loop. If you are going to make it run infinitely you probably want to add some sleep.
SyberSmoke #10
Posted 05 May 2013 - 03:19 AM
I also forgot to mention that you could also just detect when the inventory of the turtle is full like so:

if turtle.getItemCount(16) == 64 then
  --drop off stuff
end
(You would use this if you didn't want to drop off at exact intervals. Instead it would just drop off whenever it needed to)
Also, if you wanted it to run forever instead of just 10 times like it was above you could replace to for loop with a while loop. If you are going to make it run infinitely you probably want to add some sleep.

With this, I am guessing the value for the getItemCount would be the slot number? If that is correct could the variable be (i) instead so that the system checks the slots and finds the full ones. Needless to say…I do not think a turtle full of chicken, sixteen stacks, would need to be run all that often. But…I could see it when killing skellies from a spawner.
grand_mind1 #11
Posted 05 May 2013 - 03:30 AM
Yes, I agree that the system would have to be running fairly fast for a turtle emptying 16 stacks to be very efficient. I don't really understand what you are asking. Do you mean the 16 in turtle.getItemCount(16). If that is what you mean then yes, what is put in the parenthesis is the slot number it checks.
SyberSmoke #12
Posted 05 May 2013 - 04:00 AM
Yes, that is what I meant. So in previous examples used:


for i=1,16 do
  turtle.dropDown(i)
end

Was used to scan all of the inventory positions and then to dump then individually, this strikes me as inefficient of coarse. But I was curious if the above:


if turtle.getItemCount(16) == 64 then
Could instead be

if turtle.getItemCount(i) == 64 then

That way it scans the inventory and only slots with 64 are dumped…or would that just cause a mess.
grand_mind1 #13
Posted 05 May 2013 - 04:09 AM
Yes, I believe that would work although I haven't tested it. Also, I don't believe

turtle.dropDown(i)
will work. This is because what you put in parenthesis when using turtle.dropDown() is how many you want to drop. So using

for i = 1,16 do
  turtle.dropDown(i)
end
would stay on the first slot and drop 1 then 2 then 3 then 4 etc items from that same slot. Instead, I would use

for i = 1,16 do
  turtle.select(i)
  turtle.dropDown()
end
So, in the end, I think using

for i = 1,16 do
  if turtle.getItemCount(i) == 64 then
    turtle.select(i)
    turtle.dropDown()
  end
end
should work.
SyberSmoke #14
Posted 05 May 2013 - 04:27 AM
Well what I placed with the bad i was a post from another from higher. But yes I understand. I will have to play with this now that I have a working skeleton spawner to test with. Chickens can be so unreliable…but a spawner is always ready to spit out death.
SyberSmoke #15
Posted 05 May 2013 - 02:34 PM
OK, I have been messing around with things and it is interesting. I was wondering though is there a way to reset the total attack count once the dump process has been run? So say totalAttacks gets to 100 then goes past, I would like to reset the count back to zero.
grand_mind1 #16
Posted 05 May 2013 - 04:15 PM
If you would like to reset the totalAttacks variable to 0 once it has reached 100 you could use an if statement like so:

if totalAttacks == 100 then --checks if it is equal to 100
  totalAttacks = 0 --if it is then reset it to 0
end --close the if statement
Daqx #17
Posted 05 May 2013 - 08:24 PM
Simple as this.
Hope it was helpful.


while true do 
 turtle.attack()
 if turtle.getItemCount(16) > 0 then
  for i = 1,16 do
   turtle.select(i)
   turtle.drop()
  end
  turtle.select(1)
 end
end
SyberSmoke #18
Posted 05 May 2013 - 09:54 PM
Thank you again grand mind, This entire thread has been helpful in not just basic functions but syntax…Love the comments!


Daqx: Correct, I could do it that way and in fact you answered a syntax question I had in the back of my mind also. But having the turtle repeatedly attack once and then dump is rather inefficient while at the same time relying on a stack of 64 as the queue to dump is also not optimal as skeletons drop single items (Bows and Armor).

So I was looking at ways to allow the turtle to attack for a period of time and then dump so that it attacks more frequently with out the long seek times between attacks. That was in fact the line of questioning I got help with. Thank you though for the input.
PixelToast #19
Posted 06 May 2013 - 02:22 PM

turtle.select(1)
while true do
    if turtle.attack() and turtle.getItemCount(16)>0 then
        for i=1,16 do
	    turtle.dropDown() -- will drop the first availible item, no need to select
	end
    end
end
a better method, will attack constantly and dump items quickly