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

[Lua][Error] "flight:130: attempt to call nil"

Started by KeithGB, 07 July 2012 - 10:49 AM
KeithGB #1
Posted 07 July 2012 - 12:49 PM
Another snag in my first attempt at coding (not doing well so far), finished draft 1 of my code by I'm getting "flight:130: attempt to call nil" somewhere during either the flytoX or facdir functions.


function CalLoc()
x, y, z = gps.locate(5)
if x == nil or y == nil or z == nil then
error("Failed to get coordinates for initial location, check GPS Hosts")
else
print ("Current coordinates:")
print ("x: "..x)
print ("y: "..y)
print ("z: "..z)
end

end
function CalFac()
turtle.forward()
curx, cury, curz = gps.locate(5)
if curx == nil or cury == nil or curz == nil then
error("Failed to get coordinates for orientation, check GPS Hosts")
else

if x == curx and y == cury then
error("Failed to move, please check obstacles")
else

if curx > x then
fac = 1
print ("East "..fac)
else

if curx < x then
fac = 3
print ("West "..fac)
else

if cury > y then
fac = 2
print ("South "..fac)
else

if cury < y then
fac = 4
print ("North "..fac)
else

error("Failed to get facing")

x = curx
y = cury
z = curz


end
end
end
end
end
end
end

function TarIn()
print("Enter target coordinates")
write("X: ")
tempx = read()
tarx = tonumber(tempx)
write("Y: ")
tempy = read()
tary = tonumber(tempy)
write("Z: ")
tempz = read()
tarz = tonumber(tempz)
print("Coordinates confirmed as "..tarx..", "..tary..", "..tarz)
end

function flytoZ()
if curz < tarz then
  repeat
   turtle.up()
   curz=curz+1
  until curz >= tarz
else
if curz > tarz then
  repeat
   turtle.down()
   curz=curz-1
  until curz <= tarz
else
end
end
end

function facnumcor()
if fac > 4 then
fac=fac-4
else
if fac < 1 then
fac=fac+4
end
end

function facdir()
repeat
if tfac == fac+2 or tfac == fac-2 then
turtle.turnRight()
turtle.turnRight()
fac=fac+2
facnumcor()
else
if tfac == fac+1 or tfac == fac-3 then
turtle.turnRight()
fac=fac+1
facnumcor()
else
if tfac == fac-1 or tfac == fac+3 then
turtle.turnLeft()
fac=fac-1
facnumcor()
else
end
end
end
until tfac == fac
end
end

function flytoX()
if curx < tarx then --East
tfac = 1
facdir()
  repeat
   turtle.forward()
   curx=curx+1
  until curx >= tarx
else
if curx > tarx then --West
tfac = 3
facdir()
  repeat
   turtle.forward()
   curx=curx-1
  until curx <= tarx
else
end
end
end

function flytoY()
if cury < tary then --South
tfac = 2
facdir()
  repeat
   turtle.forward()
   cury=cury+1
  until cury >= tary
else
if cury > tary then --North
tfac = 4
facdir()
  repeat
   turtle.forward()
   cury=cury-1
  until cury <= tary
else
end
end
end

function selectpayload()
print ("Select payload:")
print ("1. None")
print ("2. Dummy")
print ("3. Conventional")
print ("4. Nuclear")
pay = read()

if pay~="1" and pay~="2" and pay~="3" and pay~="4" and pay~="none" and pay~="None" and pay~="dummy" and pay~="Dummy" and pay~="conventional" and pay~="Conventional" and pay~="tnt" and pay~="TNT" and pay~="nuclear" and pay~="Nuclear" and pay~="nuke" then
error("Payload not recognised")
else

if pay=="1" or pay=="none" or pay=="None" then

else
if pay=="2" or pay=="dummy" or pay=="Dummy" then
turtle.select(1)
else
if pay=="3" or pay=="conventional" or pay=="Conventional" or pay=="tnt" or pay=="TNT" then
turtle.select(2)
else
if pay=="4" or pay=="nuclear" or pay=="Nuclear" or pay=="nuke" then
turtle.select(3)
end
end
end
end
end
end
function droppayload()
if pay~="1" and pay~="none" and pay~="None" then
redstone.setOutput("front", true)
turtle.place()
end
end

function returnplot()
x=tarx
y=tary
z=tarz
end

rednet.open("right")
CalLoc()
CalFac()
TarIn()
selectpayload()
flytoZ()
flytoX()
flytoY()
droppayload()
returnplot()
flytoY()
flytoX()
flytoZ()
turtle.forward()
turtle.turnRight()
turtle.turnRight()
print ("Mission success")

Suspect it's trying to call tfac before defining it… however I'm sure I set it before calling it.

Edit: It's throwing the error at where I call facdir() in flytoX() and presumably flytoY() if it got that far. Still no idea why.
Edited on 07 July 2012 - 03:32 PM
Lyqyd #2
Posted 07 July 2012 - 07:09 PM
Well, you really should be passing local variables between functions rather than operating on global variables inside each function, but here is the slightly improved code, with comments. It should work better at this point.

Oh, and since I refactored the problem function out, the issue was that in the facnumcor (you really should use more descriptive titles for things) function, you were missing an end.


function CalLoc()
	x, y, z = gps.locate(5)
	if x == nil or y == nil or z == nil then
		error("Failed to get coordinates for initial location, check GPS Hosts")
	else
		print ("Current coordinates:")
		print ("x: "..x)
		print ("y: "..y)
		print ("z: "..z)
	end
end

function CalFac()
	turtle.forward()
	curx, cury, curz = gps.locate(5)
	if curx == nil or cury == nil or curz == nil then
		error("Failed to get coordinates for orientation, check GPS Hosts")
	elseif x == curx and y == cury then
		--elseif is your friend.
		error("Failed to move, please check obstacles")
	elseif curx > x then
		fac = 1
		print ("East "..fac)
	elseif curx < x then
		fac = 3
		print ("West "..fac)
	elseif cury > y then
		fac = 2
		print ("South "..fac)
	elseif cury < y then
		fac = 4
		print ("North "..fac)
	else
		x = curx
		y = cury
		z = curz
		error("Failed to get facing")
	end
end

function TarIn()
	print("Enter target coordinates")
	write("X: ")
	tempx = read()
	tarx = tonumber(tempx)
	write("Y: ")
	tempy = read()
	tary = tonumber(tempy)
	write("Z: ")
	tempz = read()
	tarz = tonumber(tempz)
	print("Coordinates confirmed as "..tarx..", "..tary..", "..tarz)
end

function flytoZ()
	if curz < tarz then
		repeat
			turtle.up()
			curz=curz+1
		until curz >= tarz
	elseif curz > tarz then
		repeat
			turtle.down()
			curz=curz-1
		until curz <= tarz
	end
end

--facnumcor can be replaced by one-line if statements in each relevant case in facdir.

function facdir()
	--repeat is unnecessary, since this if covers all valid cases.
	if tfac == fac+2 or tfac == fac-2 then
		turtle.turnRight()
		turtle.turnRight()
		fac=fac+2
		if fac > 4 then fac = fac - 4 end
	elseif tfac == fac+1 or tfac == fac-3 then
		turtle.turnRight()
		fac=fac+1
		if fac > 4 then fac = fac - 4 end
	elseif tfac == fac-1 or tfac == fac+3 then
		turtle.turnLeft()
		fac=fac-1
		if fac < 1 then fac = fac + 4 end
	end
end

function flytoX()
	if curx < tarx then --East
		tfac = 1
		facdir()
		repeat
			--you have no collision detection, so even if we think we have arrived, we may not have.
			turtle.forward()
			curx=curx+1
		until curx >= tarx
	elseif curx > tarx then --West
		tfac = 3
		facdir()
		repeat
			turtle.forward()
			curx=curx-1
		until curx <= tarx
	end
end

function flytoY()
	if cury < tary then --South
		tfac = 2
		facdir()
		repeat
			turtle.forward()
			cury=cury+1
		until cury >= tary
	elseif cury > tary then --North
		tfac = 4
		facdir()
		repeat
			turtle.forward()
			cury=cury-1
		until cury <= tary
	end
end

function selectpayload()
	print ("Select payload:")
	print ("1. None")
	print ("2. Dummy")
	print ("3. Conventional")
	print ("4. Nuclear")
	pay = read()
	if pay~="1" and pay~="2" and pay~="3" and pay~="4" and tolower(pay)~="none" and tolower(pay)~="dummy" and tolower(pay)~="conventional" and tolower(pay)~="tnt" and tolower(pay)~="nuclear" and tolower(pay)~="nuke" then
		error("Payload not recognised")
	--elseif is again our friend.
	elseif pay=="1" or pay=="none" or pay=="None" then
	elseif pay=="2" or pay=="dummy" or pay=="Dummy" then
		turtle.select(1)
	elseif pay=="3" or pay=="conventional" or pay=="Conventional" or pay=="tnt" or pay=="TNT" then
		turtle.select(2)
	elseif pay=="4" or pay=="nuclear" or pay=="Nuclear" or pay=="nuke" then
		turtle.select(3)
	end
end

function droppayload()
	if pay~="1" and tolower(pay)~="none" then
		redstone.setOutput("front", true)
		turtle.place()
	end
end

function returnplot()
	x=tarx
	y=tary
	z=tarz
end

rednet.open("right")
CalLoc()
CalFac()
TarIn()
selectpayload()
flytoZ()
flytoX()
flytoY()
droppayload()
returnplot()
flytoY()
flytoX()
flytoZ()
turtle.forward()
turtle.turnRight()
turtle.turnRight()
print ("Mission success")
KeithGB #3
Posted 07 July 2012 - 08:04 PM
Thanks very much! I will have to learn proper use of locals soon. This is just a alpha script so no collision detection or repeat bombing runs are included yet.

I'm now having a problem, when I used 'None' as a payload in gave me an attempt to call nil error and when I used an other payload it attempts to call nil when using droppayload().
Lyqyd #4
Posted 08 July 2012 - 11:59 AM
Do a find and replace and change "tolower(" to "string.lower(". I forgot to look up the actual function for that one after I wrote it in.