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

mystcraft and computercraft, attempt to call nil

Started by BurnedSpaghetti, 01 February 2014 - 06:47 PM
BurnedSpaghetti #1
Posted 01 February 2014 - 07:47 PM
i got the code from direwolf20 season 5 1.4.7, i rewrote it on most of the parts to work with 1.6.4 and the only thing that keeps messing up is line 7
that says "attempt to call nil"


os.loadAPI("button")
m = peripheral.wrap("left")
rednet.open("bottom")

function mainTable()
   button.clearTable()
   button.heading("Choose a Dimension")
   button.setTable("Rayvash", Rayvash3r, 5,15,5,9)
   button.setTable("_jream_",_jream_,25,35,5,9)
   button.setTable("Burned",BurnedSpaghetti,5,15,11,15)
   button.setTable("twilight", Twilight, 25,35,11,15)
   button.screen()
end

function mystBook(slot,name)
   button.toggleButton(name)
   rednet.send(131,tostring(slot))
   sleep(5)
   button.toggleButton(name)
end

function Burned()
   mystBook(3, "BurnedSpaghetti")
end

function Rayvash()
   mystBook(2,"Rayvash3r")
end

function _jream_()
   mystBook(0,"_jream_")
end

function twilight()
   mystBook(1,"Twilight Forest")
end

function mystportal()
   mystTable()
   getClick()
   mainTable()
end

function getClick()
   event,side,x,y = os.pullEvent("monitor_touch")
   button.checkxy(x,y)
end

while true do
   mainTable()
   getClick()
end
Edited by
Bomb Bloke #2
Posted 01 February 2014 - 08:51 PM
Line 7 is attempting to call a function in the "button" API. The question is thus: Does a "heading" function exist in that API?
BurnedSpaghetti #3
Posted 02 February 2014 - 11:27 AM
Line 7 is attempting to call a function in the "button" API. The question is thus: Does a "heading" function exist in that API?
yes the function "heading" does exist in the "button" API
here is the button code:

local mon = peripheral.wrap("left")
  mon.setTextScale(1)
  mon.setTextColor(colors.white)
local button={}
  mon.setBackgroundColor(colors.black)
function clearTable()
   button = {}
   mon.clear()
end
			  
function setTable(name, func, xmin, xmax, ymin, ymax)
   button[name] = {}
   button[name]["func"] = func
   button[name]["active"] = false
   button[name]["xmin"] = xmin
   button[name]["ymin"] = ymin
   button[name]["xmax"] = xmax
   button[name]["ymax"] = ymax
end
function funcName()
   print("You clicked buttonText")
end
	   
function fillTable()
   setTable("ButtonText", funcName, 5, 25, 4, 8)
end	
function fill(text, color, bData)
   mon.setBackgroundColor(color)
   local yspot = math.floor((bData["ymin"] + bData["ymax"]) /2)
   local xspot = math.floor((bData["xmax"] - bData["xmin"] - string.len(text)) /2) +1
   for j = bData["ymin"], bData["ymax"] do
	  mon.setCursorPos(bData["xmin"], j)
	  if j == yspot then
		 for k = 0, bData["xmax"] - bData["xmin"] - string.len(text) +1 do
		    if k == xspot then
			   mon.write(text)
		    else
			   mon.write(" ")
		    end
		 end
	  else
		 for i = bData["xmin"], bData["xmax"] do
		    mon.write(" ")
		 end
	  end
   end
   mon.setBackgroundColor(colors.black)
end
	
function screen()
   local currColor
   for name,data in pairs(button) do
	  local on = data["active"]
	  if on == true then currColor = colors.lime else currColor = colors.red end
	  fill(name, currColor, data)
   end
end
function toggleButton(name)
   button[name]["active"] = not button[name]["active"]
   screen()
end	
function flash(name)
   toggleButton(name)
   screen()
   sleep(0.15)
   toggleButton(name)
   screen()
end
											
function checkxy(x, y)
   for name, data in pairs(button) do
	  if y>=data["ymin"] and  y <= data["ymax"] then
		 if x>=data["xmin"] and x<= data["xmax"] then
		    if data["func"]() then
		    return true
		    --data["active"] = not data["active"]
		    --print(name)
		 end
	  end
   end
   return false
end
	
function heading(text)
   w, h = mon.getSize()
   mon.setCursorPos((w-string.len(text))/2+1, 1)
   mon.write(text)
end
	
function label(w, h, text)
   mon.setCursorPos(w, h)
   mon.write(text)
end
   end
Edited on 02 February 2014 - 02:05 PM
surferpup #4
Posted 02 February 2014 - 04:53 PM
Please post the full error message.
H4X0RZ #5
Posted 02 February 2014 - 05:51 PM
The Rayvash3r part is the problem…
t is a undefined variable. I THINK you want it as a string but I'm not sure…
BurnedSpaghetti #6
Posted 02 February 2014 - 05:58 PM
Please post the full error message.
here is the error msg
Bomb Bloke #7
Posted 02 February 2014 - 07:09 PM
This code here:

button.setTable("Rayvash", Rayvash3r, 5,15,5,9) 

… is apparently supposed to pass the name of the button, the function to call when it's pressed, and the co-ordinates of that button, to the button API. The "function" you're passing is "Rayvash3r", which is an undefined variable. You later define a function called "Rayvash", but never one called "Rayvash3r", so attempting to click that button will result in an attempt to call nil.

Most of the other buttons have the exact same issue.

If there's any more to it then that, then yes, the full error message - along with any steps that lead up to it - would indeed be helpful.
BurnedSpaghetti #8
Posted 02 February 2014 - 11:51 PM
aah i see
BurnedSpaghetti #9
Posted 03 February 2014 - 12:25 AM
alright i fix the function and i had to remove button.heading("Choose a Dimension") because it still gave the error, after that it did not give me anymore error the only problem now is that the monitor isn't responding to the touch and its not telling the turtle what to do
EDIT: only the button Rayvash is working but the turtle is not doing anything
Edited on 02 February 2014 - 11:36 PM
Bomb Bloke #10
Posted 03 February 2014 - 03:04 AM
How do you know the turtle isn't getting any rednet messages? Is the turtle's ID equal to the number you're sending to (131)?

What does the current version of your script look like? What's the turtle running?

I notice that the button API's "toggleButton" code requires that it be passed the name of the button you wish to press. For example, if you have this:

button.setTable("twilight", Twilight, 25,35,11,15)  -- Button name, function name, xmin/max, ymin/max

Then lower down you must have this:

function Twilight()	   -- Function name as above, case and all
   mystBook(1,"twilight")  -- Button name as above, case and all
end

Though it strikes me that pushing the other buttons wouldn't "do nothing" so much as they'd "error out with an attempt to index nil" if you'd left such a mistake there…

Anyway, you could also just skip the separate function declaration and do this:

button.setTable("twilight", function () mystBook(1,"twilight") end, 25,35,11,15)  -- Instead of using a pointer to a function we'll define later, let's just define the function now.
BurnedSpaghetti #11
Posted 03 February 2014 - 09:19 AM
How do you know the turtle isn't getting any rednet messages? Is the turtle's ID equal to the number you're sending to (131)?

What does the current version of your script look like? What's the turtle running?

I notice that the button API's "toggleButton" code requires that it be passed the name of the button you wish to press. For example, if you have this:

button.setTable("twilight", Twilight, 25,35,11,15)  -- Button name, function name, xmin/max, ymin/max

Then lower down you must have this:

function Twilight()	   -- Function name as above, case and all
   mystBook(1,"twilight")  -- Button name as above, case and all
end

Though it strikes me that pushing the other buttons wouldn't "do nothing" so much as they'd "error out with an attempt to index nil" if you'd left such a mistake there…

Anyway, you could also just skip the separate function declaration and do this:

button.setTable("twilight", function () mystBook(1,"twilight") end, 25,35,11,15)  -- Instead of using a pointer to a function we'll define later, let's just define the function now.

wow i forgot to change the turtle id, someone took my first turtle that had that id. and for the script i cant give it to right now the server i have it on is down for reasons i do not know, but thank you all for the help and ill post the turtles scrip once the server is up
BurnedSpaghetti #12
Posted 03 February 2014 - 11:55 AM
this are the codes on the turtle, these are from 1.4.7 direwolf20 modpack.
i couldnt find any latest code that would work and i just used this one

local tArgs = {...}
m = peripheral.wrap("left")

book = tonumber(tArgs[1])

m.suckDown(book,1)
turtle.dropUp()
sleep(5)
turtle.suckUp()
m.dropDown(book,1)
BurnedSpaghetti #13
Posted 03 February 2014 - 12:33 PM
ok i did what you said and made it like this
but now im getting an error from the "button" api on line 63

os.loadAPI("button")
m = peripheral.wrap("left")
rednet.open("bottom")

function mainTable()
   button.clearTable()
   button.setTable("Rayvash3r",function () mystBook(0,"Rayvash3r") end,5,15,5,9)
   button.setTable("_jream_",function () mystBook(1,"_jream_") end,25,35,5,9)
   button.setTable("Burned",function () mystBook(2,"Burned") end,5,15,11,15)
   button.setTable("twilight", function () mystBook(3,"twilight") end,25,35,11,15)
   button.screen()
   button.toggleButton(name)
   rednet.send(140,tostring(slot))
   sleep(5)
   button.toggleButton(name)
end

function mystportal()
   mystTable()
   getClick()
   mainTable()
end

function getClick()
   event,side,x,y = os.pullEvent("monitor_touch")
   button.checkxy(x,y)
end

while true do
   mainTable()
   getClick()
end

Bomb Bloke #14
Posted 03 February 2014 - 07:00 PM
That doesn't sound right. The copy of the buttons API you've provided puts that line in the "flash()" function, which your code doesn't call. Even if it were called, that line doesn't index anything and wouldn't throw that error. Have you altered the button API since posting it…?

Your current revision of the main script does still have some problems, though (that "mystBook" function was still needed!). Here's a quick (untested) re-write which may or may not help you (it at least cuts out the fat):

Spoiler
os.loadAPI("button")
rednet.open("bottom")

function mystBook(slot,name)
   button.toggleButton(name)
   rednet.send(131,tostring(slot))
   sleep(5)
   button.toggleButton(name)
end

button.clearTable()
button.heading("Choose a Dimension")
button.setTable("Rayvash3r",      function () mystBook(2,"Rayvash3r") end,        5,15, 5, 9)
button.setTable("_jream_",        function () mystBook(0,"_jream_") end,         25,35, 5, 9)
button.setTable("BurnedSpaghetti",function () mystBook(3, "BurnedSpaghetti") end, 5,15,11,15)
button.setTable("Twilight Forest",function () mystBook(1,"Twilight Forest") end, 25,35,11,15)
button.screen()

while true do
   local event,side,x,y = os.pullEvent("monitor_touch")
   button.checkxy(x,y)
end

Oh, and I've spotted why you couldn't get that heading function to work. The button API has a misplaced "end":

Spoiler
function checkxy(x, y)
   for name, data in pairs(button) do
          if y>=data["ymin"] and  y <= data["ymax"] then
                 if x>=data["xmin"] and x<= data["xmax"] then
                    if data["func"]() then
                    return true
                    --data["active"] = not data["active"]
                    --print(name)
                 end            -- ******** An extra "end" should be here!
          end
   end
   return false
end

function heading(text)
   w, h = mon.getSize()
   mon.setCursorPos((w-string.len(text))/2+1, 1)
   mon.write(text)
end

function label(w, h, text)
   mon.setCursorPos(w, h)
   mon.write(text)
end
   end                 -- ******** But is instead down here!
BurnedSpaghetti #15
Posted 03 February 2014 - 11:25 PM
That doesn't sound right. The copy of the buttons API you've provided puts that line in the "flash()" function, which your code doesn't call. Even if it were called, that line doesn't index anything and wouldn't throw that error. Have you altered the button API since posting it…?

Your current revision of the main script does still have some problems, though (that "mystBook" function was still needed!). Here's a quick (untested) re-write which may or may not help you (it at least cuts out the fat):

Spoiler
os.loadAPI("button")
rednet.open("bottom")

function mystBook(slot,name)
   button.toggleButton(name)
   rednet.send(131,tostring(slot))
   sleep(5)
   button.toggleButton(name)
end

button.clearTable()
button.heading("Choose a Dimension")
button.setTable("Rayvash3r",	  function () mystBook(2,"Rayvash3r") end,		5,15, 5, 9)
button.setTable("_jream_",		function () mystBook(0,"_jream_") end,		 25,35, 5, 9)
button.setTable("BurnedSpaghetti",function () mystBook(3, "BurnedSpaghetti") end, 5,15,11,15)
button.setTable("Twilight Forest",function () mystBook(1,"Twilight Forest") end, 25,35,11,15)
button.screen()

while true do
   local event,side,x,y = os.pullEvent("monitor_touch")
   button.checkxy(x,y)
end

Oh, and I've spotted why you couldn't get that heading function to work. The button API has a misplaced "end":

Spoiler
function checkxy(x, y)
   for name, data in pairs(button) do
		  if y>=data["ymin"] and  y <= data["ymax"] then
				 if x>=data["xmin"] and x<= data["xmax"] then
					if data["func"]() then
					return true
					--data["active"] = not data["active"]
					--print(name)
				 end			-- ******** An extra "end" should be here!
		  end
   end
   return false
end

function heading(text)
   w, h = mon.getSize()
   mon.setCursorPos((w-string.len(text))/2+1, 1)
   mon.write(text)
end

function label(w, h, text)
   mon.setCursorPos(w, h)
   mon.write(text)
end
   end				 -- ******** But is instead down here!
the button ipa is still the same from when i posted, and the code did do anything at all it didnt even show the buttons on the monitor and isnt m = peripheral.wrap("left")
suppost to be on the code or is that how the codes suppost to be without it, and i didnt understand what you meant on the button api should i remove them or leave them there since they are there.
Bomb Bloke #16
Posted 03 February 2014 - 11:33 PM
Perhaps you should check the copy of the button API you have on your computer, and see what the sixty-third line looks like on your end.

In regards to that errant "end" statement, yes, it should be moved upwards. In its current location it puts the "label" and "heading" functions inside the "checkxy" function, meaning they can only be called from in there. It also causes the function to stop checking buttons after the first (another fault you'd previously noticed).

The "m = peripheral.wrap("left")" line made "m" effectively a pointer to the monitor's functions. However, "m" never gets used in the script, making that line redundant.
BurnedSpaghetti #17
Posted 04 February 2014 - 12:37 AM
Perhaps you should check the copy of the button API you have on your computer, and see what the sixty-third line looks like on your end.
i dont know why it shows it like that on the code i posted but on my computer line 6 is empty

local mon = peripheral.wrap("left")
  mon.setTextScale(1)
  mon.setTextColor(colors.white)
local button={}
  mon.setBackgroundColor(colors.black)

function clearTable()
   button = {}
   mon.clear()
end
In regards to that errant "end" statement, yes, it should be moved upwards. In its current location it puts the "label" and "heading" functions inside the "checkxy" function, meaning they can only be called from in there. It also causes the function to stop checking buttons after the first (another fault you'd previously noticed).
if i remove the "end" at the last line it give me this error : bios:339: [string "button"]:100: 'end' expected (to close 'function' at line 75), im not getting what do you mean by moving it upwards or where

The "m = peripheral.wrap("left")" line made "m" effectively a pointer to the monitor's functions. However, "m" never gets used in the script, making that line redundant.
alright understood

EDIT: nvm i think i found where to put it, but the monitor still shows nothing

function checkxy(x, y)
   for name, data in pairs(button) do
		  if y>=data["ymin"] and  y <= data["ymax"] then
				 if x>=data["xmin"] and x<= data["xmax"] then
					if data["func"]() then
					return true
					--data["active"] = not data["active"]
					--print(name)
				 end
                                       end

		  end

   end
   return false
end
		
Edited on 03 February 2014 - 11:47 PM
Bomb Bloke #18
Posted 04 February 2014 - 12:54 AM
What does the computer terminal show? If an error, how does the line that error points to read?
BurnedSpaghetti #19
Posted 04 February 2014 - 01:13 AM
What does the computer terminal show? If an error, how does the line that error points to read?
when i moved the "end" upwards to under line 83 that now it looks like this :

function checkxy(x, y)
   for name, data in pairs(button) do
				  if y>=data["ymin"] and  y <= data["ymax"] then
								 if x>=data["xmin"] and x<= data["xmax"] then
										if data["func"]() then
										return true
										--data["active"] = not data["active"]
										--print(name)
								 end
									   end
it stopped giving the error but the monitor doesnt show anything
Edited on 04 February 2014 - 12:16 AM
surferpup #20
Posted 04 February 2014 - 01:57 AM
Here is that extra end, a little better formatted for you.


function checkxy(x, y)
    for name, data in pairs(button) do
        if y>=data["ymin"] and  y <= data["ymax"] then
            if x>=data["xmin"] and x<= data["xmax"] then
                    if data["func"]() then
                        return true
                        --data["active"] = not data["active"]
                        --print(name)
                     end --<<< this is where the extra end goes.
            end
        end
    end
    return false
end


Finally, your code, reformatted should look just like this:


function checkxy(x, y)
   for name, data in pairs(button) do
          if y>=data["ymin"] and  y <= data["ymax"] then
                 if x>=data["xmin"] and x<= data["xmax"] then
                    if data["func"]() then
                        return true
                        --data["active"] = not data["active"]
                        --print(name)
                    end
                end
          end
   end
   return false
end

function heading(text)
   w, h = mon.getSize()
   mon.setCursorPos((w-string.len(text))/2+1, 1)
   mon.write(text)
end

function label(w, h, text)
   mon.setCursorPos(w, h)
   mon.write(text)
end
BurnedSpaghetti #21
Posted 05 February 2014 - 04:04 PM
the monitor doesnt show anything ist blank
surferpup #22
Posted 05 February 2014 - 04:10 PM
Could you please post your current code? I think seeing it in its current state would be useful
BurnedSpaghetti #23
Posted 07 February 2014 - 01:22 AM
current codes on the pc and turtel
pc:
Spoiler
os.loadAPI("button")
mon = peripheral.wrap("left")
rednet.open("bottom")

function mystBook(slot,name)
   button.toggleButton(name)
   rednet.send(140,tostring(slot))
   sleep(5)
   button.toggleButton(name)
end

function mainTable()
   button.clearTable()
   button.heading("Choose a Dimension")
   button.setTable("Rayvash3r",function () mystBook(2,"Rayvash3r") end,5,15,5,9)
   button.setTable("_jream_",function () mystBook(0,"_jream_") end,25,35,5,9)
   button.setTable("Burned",function () mystBook(3,"Burned") end,5,15,11,15)
   button.setTable("twilight", function () mystBook(1,"twilight") end,25,35,11,15)
   button.screen()
end


while true do
   local event,side,x,y = os.pullEvent("monitor_touch")
   button.checkxy(x,y)
end
Spoiler
local mon = peripheral.wrap("left")
  mon.setTextScale(1)
  mon.setTextColor(colors.white)
local button={}
  mon.setBackgroundColor(colors.black)
function clearTable()
   button = {}
   mon.clear()
end
			  
function setTable(name, func, xmin, xmax, ymin, ymax)
   button[name] = {}
   button[name]["func"] = func
   button[name]["active"] = false
   button[name]["xmin"] = xmin
   button[name]["ymin"] = ymin
   button[name]["xmax"] = xmax
   button[name]["ymax"] = ymax
end
function funcName()
   print("You clicked buttonText")
end
	   
function fillTable()
   setTable("ButtonText", funcName, 5, 25, 4, 8)
end	
function fill(text, color, bData)
   mon.setBackgroundColor(color)
   local yspot = math.floor((bData["ymin"] + bData["ymax"]) /2)
   local xspot = math.floor((bData["xmax"] - bData["xmin"] - string.len(text)) /2) +1
   for j = bData["ymin"], bData["ymax"] do
	  mon.setCursorPos(bData["xmin"], j)
	  if j == yspot then
		 for k = 0, bData["xmax"] - bData["xmin"] - string.len(text) +1 do
		    if k == xspot then
			   mon.write(text)
		    else
			   mon.write(" ")
		    end
		 end
	  else
		 for i = bData["xmin"], bData["xmax"] do
		    mon.write(" ")
		 end
	  end
   end
   mon.setBackgroundColor(colors.black)
end
	
function screen()
   local currColor
   for name,data in pairs(button) do
	  local on = data["active"]
	  if on == true then currColor = colors.lime else currColor = colors.red end
	  fill(name, currColor, data)
   end
end
function toggleButton(name)
   button[name]["active"] = not button[name]["active"]
   screen()
end	
function flash(name)
   toggleButton(name)
   screen()
   sleep(0.15)
   toggleButton(name)
   screen()
end
											
function checkxy(x, y)
   for name, data in pairs(button) do
	  if y>=data["ymin"] and  y <= data["ymax"] then
		 if x>=data["xmin"] and x<= data["xmax"] then
		    if data["func"]() then
		    return true
		    --data["active"] = not data["active"]
		    --print(name)
		 end
		
	   end
		   
	  end
	 
   end
   return false
end
	
function heading(text)
   w, h = mon.getSize()
   mon.setCursorPos((w-string.len(text))/2+1, 1)
   mon.write(text)
end
	
function label(w, h, text)
   mon.setCursorPos(w, h)
   mon.write(text)
end
turtel:
Spoiler
local tArgs = {...}
m = peripheral.wrap("down")

book = tonumber(tArgs[1])

m.suckDown(book,1)
turtle.dropUp()
sleep(5)
turtle.suckUp()
m.dropDown(book,1)
Bomb Bloke #24
Posted 07 February 2014 - 08:06 AM
You've got a "mainTable()" function on the computer that never gets called.

I'm suspecting you tried to implement the code I gave you here, but only partially copied it over.
BurnedSpaghetti #25
Posted 07 February 2014 - 04:57 PM
You've got a "mainTable()" function on the computer that never gets called.

I'm suspecting you tried to implement the code I gave you here, but only partially copied it over.
yea the one i posted is the one from when you posted but i missed read sorry