17 posts
Posted 16 March 2013 - 12:59 PM
I'm trying to make myself a 9x6x9 mob trap and as part of it I'd like to avoid the need to use pressure plates or trip wires to tell the turtle when to attack a mob. I'd rather it just blindly keep attacking every few seconds as long as it keeps recieving a redstone signal from my on/off lever.
However no matter how hard I try, when I try to make a loop to keep attacking I eventually get the error 'too long without yielding' is there a way to resolve this?
My code is below
local totalloot
totalloot = 0
local function updateterm()
term.clear()
print("----Dav's Mob Grinder Turtle----")
write("Total Items Looted: ")
write(totalloot)
print("--------------------------------")
print("")
print("")
print("Status:")
end
updateterm()
print("Mob grinder ready")
while true do
while redstone.getInput("left") == false do
turtle.attack()
for i=1,16,1 do
if turtle.getItemCount(i) > 0 then
totalloot = totalloot + turtle.getItemCount(i)
turtle.select(i)
turtle.dropDown()
updateterm()
print("Waiting for mob to spawn..")
end
end
sleep(2)
end
end
*EDIT* I see where my problem is now. It's not the turtle running that's the problem, it's when it's not running. If I have a redstone signal on (which tells the turtle to do nothing at the "while redstone.getInput("left") == false do" line) the turtle cycles on the false line over and over again rapidly and that's what makes it throw that error.
I can't work out in my head how to make it wait for a os pull event for the lever to be turned off, but while it's off continue it's loop on it's marry way until the redstone signal starts again. Any suggestions?
1522 posts
Location
The Netherlands
Posted 16 March 2013 - 01:40 PM
do a sleep(0) in your second while loop.
Also try something like this:
while true do
if not redstone.getInput("left") then
-- Your code
end
sleep(0) --or longer, I suggest 0.4 if you use turtle.attack()
end
This does the same but uses you just one while loop. Now you can also detect other things, like if its true.
You do not have to do:
local totalloot
totalloot = 0
Instead you can do
local totalloot = 0
997 posts
Location
Wellington, New Zealand
Posted 16 March 2013 - 02:32 PM
When you do this, or something like it:
while rs.getInput("side") == true do
sleep(0)
end
your code is the kids in the backseat shouting "Are we there yet?" every 2 seconds, and possibly causing lag for no good reason.
This waits for a redstone signal to change:
os.pullEvent("redstone")
If you want to wait for a specific redstone state:
while rs.getInput("side") == true do
os.pullEvent("redstone")
end
17 posts
Posted 16 March 2013 - 02:36 PM
do a sleep(0) in your second while loop.
Also try something like this:
while true do
if not redstone.getInput("left") then
-- Your code
end
sleep(0) --or longer, I suggest 0.4 if you use turtle.attack()
end
Thanks, I'll test it now. This is the code I'll try out right now:
local totalloot = 0
local function updateterm()
term.clear()
print("----Dav's Mob Grinder Turtle----")
write("Total Items Looted: ")
write(totalloot)
print("--------------------------------")
print("")
print("")
print("Status:")
end
updateterm()
print("Mob grinder ready")
while true do
if not redstone.getInput("left") == then
turtle.attack()
for i=1,16,1 do
if turtle.getItemCount(i) > 0 then
totalloot = totalloot + turtle.getItemCount(i)
turtle.select(i)
turtle.dropDown()
updateterm()
print("Waiting for mob to spawn..")
end
end
sleep(0.5)
end
end
1522 posts
Location
The Netherlands
Posted 16 March 2013 - 02:39 PM
do a sleep(0) in your second while loop.
Also try something like this:
while true do
if not redstone.getInput("left") then
-- Your code
end
sleep(0) --or longer, I suggest 0.4 if you use turtle.attack()
end
Thanks, I'll test it now. This is the code I'll try out right now:
local totalloot = 0
local function updateterm()
term.clear()
print("----Dav's Mob Grinder Turtle----")
write("Total Items Looted: ")
write(totalloot)
print("--------------------------------")
print("")
print("")
print("Status:")
end
updateterm()
print("Mob grinder ready")
while true do
if not redstone.getInput("left") == then
turtle.attack()
for i=1,16,1 do
if turtle.getItemCount(i) > 0 then
totalloot = totalloot + turtle.getItemCount(i)
turtle.select(i)
turtle.dropDown()
updateterm()
print("Waiting for mob to spawn..")
end
end
sleep(0.5)
end
end
you should replace this line
if not redstone.getInput("left") == then
with this:
if not redstone.getInput("left") then
You can also do what immibis said, as it reduces lagg.
17 posts
Posted 16 March 2013 - 02:39 PM
When you do this, or something like it:
while rs.getInput("side") == true do
sleep(0)
end
your code is the kids in the backseat shouting "Are we there yet?" every 2 seconds, and possibly causing lag for no good reason.
This waits for a redstone signal to change:
os.pullEvent("redstone")
If you want to wait for a specific redstone state:
while rs.getInput("side") == true do
os.pullEvent("redstone")
end
I understand the purpose of the OS pull event, but I can't figure out where to put it to work in the right case. The spot I kept putting it made it so that the turtle wouldn't repeatedly attack. It would wait for a redstone signal each time before attacking.
I can't figure out where I'd put that OS pull event so that it repeatedly attacks, keeping it's loop going, but once it sees a redstone signal, it then switches to an OS pull event to wait until the redstone signal is turned off. If it turns off, then it can go back to looping again until the next time it sees a redstone signal.
17 posts
Posted 16 March 2013 - 02:41 PM
you should replace this line
if not redstone.getInput("left") == then
with this:
if not redstone.getInput("left") then
You can also do what immibis said, as it reduces lagg.
Thanks Engineer. I missed leaving in that == as for the OS pull event, I can't work out where to put it. I posted about that the same time you posted.
17 posts
Posted 16 March 2013 - 02:43 PM
I think I figured it out. I put the OS pull event in the else statement at the bottom.
local totalloot = 0
local function updateterm()
term.clear()
print("----Dav's Mob Grinder Turtle----")
write("Total Items Looted: ")
write(totalloot)
print("--------------------------------")
print("")
print("")
print("Status:")
end
updateterm()
print("Mob grinder ready")
while true do
if not redstone.getInput("left") then
turtle.attack()
for i=1,16,1 do
if turtle.getItemCount(i) > 0 then
totalloot = totalloot + turtle.getItemCount(i)
turtle.select(i)
turtle.dropDown()
updateterm()
print("Waiting for mob to spawn..")
end
end
sleep(0.5)
elseif redstone.getInput("left") then
print("Grinder disabled. Waiting..")
event = os.pullEvent("redstone")
end
end
Edited on 16 March 2013 - 01:47 PM
17 posts
Posted 16 March 2013 - 03:13 PM
Success, my new code is working properly now.
Thanks immibis and Engineer for your help.
Here's the final version of my code (I hope)
http://pastebin.com/TwTkMmnz
local totalloot = 0
local function updateterm()
term.clear()
print("----Dav's Mob Grinder Turtle----")
write("Total Items Looted: ")
write(totalloot)
print("--------------------------------")
print("")
print("")
print("Status:")
end
updateterm()
print("Mob grinder ready")
while true do
if not redstone.getInput("left") then
turtle.attack()
for i=1,16,1 do
if turtle.getItemCount(i) > 0 then
totalloot = totalloot + turtle.getItemCount(i)
turtle.select(i)
turtle.dropDown()
updateterm()
print("Waiting for mob to spawn..")
end
end
sleep(0.5)
elseif redstone.getInput("left") then
print("Grinder disabled: Waiting..")
event = os.pullEvent("redstone")
print("Grinder enabled:")
print("Waiting for mob to spawn..")
end
end