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

Need help with button code and api.

Started by 7_Seven, 03 April 2018 - 09:49 PM
7_Seven #1
Posted 03 April 2018 - 11:49 PM
Hi guys.

Im trying to make Draconic Evotution portal (one portal for 16 destination without using turtles) that is controlled with Advanced computer.
I figured out how to transport Charms of dislocation in and out of receptacal, that was the easy part it took like five minutes.

Now im not a programmer or any way related to coding. That is why i was trying to get someone's code to serve my purpose.
Was not lucky.
Only option remained to find someones code and modify to fit my needs.

So i did.
Here is the original:
Who made this thanks. I have lost the authors name.
The program:
Spoiler

disk="/disk/"
todisk=0
local programs = {
   cc10remote="mbEHZZnh",
   cc10host="CR92ZjdE ",
   WiReServer="hqpRw4Jy",
   WiReClient="jtFa7V1n",
   Foo="3fnFhwvd",
   Foo2="2Zf5an8H",
   LightCon="yqJdet4j ",
   DeadGlass="2uY6KeNa ",
   QuarryPC="6smzHGJY",
   QuarryTurtle="rpXRAZs4",
   QuarryRepeater="Te359WA2",
   Ladder="u8ubAuT4",
   TreeFarm="bbpeedQ7",
   VertShaft="XyyFJ4xk",
   BundledControl="GxDwxLBi",
   MFSUmon="Tr8rWtUV",
   gpsdeploy="QEqtfgRR",
   ccreStartup="NGXLKpfA",
}
local wired = {
   cc10host="CR92ZjdE ",
   WiReClient="jtFa7V1n",
   startup="NGXLKpfA",
}
local termX, termY = term.getSize()
local function centerPrint(text, y)
  term.setCursorPos(termX/2-#text/2, y)
  term.write(text)
end
local menu_options = {
[1] = "Turtle Programs";
[2] = "PC Programs";
[3] = "Handheld Programs";
[4] = "Other Programs";
[5] = "Exit";
}
local turtle_options = {
[1] = "GPS-Build";
[2] = "Ladder Program";
[3] = "Replicator Program";
[4] = "Auto Tree Farm";
[5] = "Back";
}
local pc_options = {
[1] = "Setup Remote Host";
[2] = "WiRe Server";
[3] = "Lighting Control v1.3";
[4] = "Bundled Cable Control";
[5] = "Rednet Message Display";
[6] = "DeadGlass";
[7] = "Back";
}
local pocket_options = {
[1] = "cc10 Remote Control";
[2] = "Back";
}
local other_options = {
[1] = "Download all programs to Disk";
[2] = "Back";
}
function welcomeBack()
term.clear()
term.setTextColour(colors.red)
print("Welcome Back Commander....")
sleep(1)
end
function Close()
shell.run("clear")
print("Goodbye....")
sleep(1)
shell.run("clear")
error()
end

function mainMenu()
shell.run("clear")
term.setTextColour(colors.white)
local startY = termY/2-#menu_options/2
for i=1, #menu_options do
  centerPrint("["..i.."] "..menu_options[i], startY)
  startY = startY + 1
end
term.setCursorPos(1, termY)
term.write("Press a number to select the menu option...")
local selected = false
while true do
  local e = {os.pullEvent()}
  if e[1] == "char" then
	if menu_options[tonumber(e[2])] then
		  selected = tonumber(e[2])
		  break
	end
  end
end
print("You've selected: ".. menu_options[selected])
if selected == 1 then turtleMenu()
elseif selected == 2 then PCMenu()
elseif selected == 3 then PocketMenu()
elseif selected == 4 then OtherMenu()
elseif selected == 5 then Close()
else
return
end
end -- func mainMenu
function PCMenu()
shell.run("clear")
term.setTextColour(colors.white)
local startY = termY/2-#pc_options/2
for i=1, #pc_options do
  centerPrint("["..i.."] "..pc_options[i], startY)
  startY = startY + 1
end
term.setCursorPos(1, termY)
term.write("Press a number to select the menu option...")
local selected = false
while true do
  local e = {os.pullEvent()}
  if e[1] == "char" then
	if pc_options[tonumber(e[2])] then
		  selected = tonumber(e[2])
		  break
	end
  end
end
print("You've selected: ".. pc_options[selected])
if selected == 1 then
   shell.run("rm", "startup")
  for name,code in pairs(wired) do
   shell.run("pastebin", "get",code,name)
  end
   shell.run("clear")
   print("Restarting...")
   sleep(1)
   shell.run("clear")
   print("Please make sure a wireless modem is attached....")
   write("Press any key to continue")
   os.pullEvent("key")
   shell.run("startup")
elseif selected ==2 then
  print("Downloading WiReClient....")
  shell.run("rm", "startup")
  shell.run("pastebin", "get", "hqpRw4Jy", "startup")
  print("WiReClient Download Complete....")
  shell.run("startup")
elseif selected ==3 then
  shell.run("rm", "startup")
  print("Downloading Lighting Control v1.3....")
  shell.run("pastebin", "get", "ScRu9crS", "button")
  print("LightControl Api Download Complete....")
  shell.run("pastebin", "get", "0f455rvM", "startup")
  print("LightControl Program Download Complete....")
  print("Monitor required is x4 wide by x3 high ....")
  shell.run("startup")
elseif selected ==4 then
  shell.run("rm", "startup")
  print("Downloading Bundled Cable Control PC....")
  shell.run("pastebin", "get", "GxDwxLBi", "startup")
  print("Bundled Cable Control Download Complete....")
  print("Recommend a x2 Wide by x3 High Monitor Block....")
  write("Press any key to continue")
  os.pullEvent("key")
  print("Starting Program....")
  shell.run("startup")
elseif selected ==5 then
  shell.run("rm", "startup")
  print("Downloading Rednet Message Display....")
  shell.run("pastebin", "get", "65esSnuB", "startup")
  print("Rednet Message Display Download Complete....")
  print("Starting Program....")
  shell.run("startup")
elseif selected ==6 then
  shell.run("rm", "startup")
  print("Downloading DeadGlass....")
  shell.run("pastebin", "get", "bbpeedQ7", "startup")
  print("DeadGlass Download Complete....")
  print("Recommend a x2 Wide by x3 High Monitor Block....")
  print("Starting Program....")
  shell.run("startup")
elseif selected ==7 then
mainMenu()
else
return
end
end -- func PCMenu
function turtleMenu()
shell.run("clear")
term.setTextColour(colors.white)
local startY = termY/2-#turtle_options/2
for i=1, #turtle_options do
  centerPrint("["..i.."] "..turtle_options[i], startY)
  startY = startY + 1
end
term.setCursorPos(1, termY)
term.write("Press a number to select the menu option...")
local selected = false
while true do
  local e = {os.pullEvent()}
  if e[1] == "char" then
	if turtle_options[tonumber(e[2])] then
		  selected = tonumber(e[2])
		  break
	end
  end
end
print("You've selected: ".. turtle_options[selected])
if selected == 1 then
  print("Downloading GPS-Builder....")
  shell.run("pastebin", "get", "QEqtfgRR", "gpsbuilder")
  print("GPS-Builder Download Complete....")
elseif selected ==2 then
  print("Downloading Ladder Builder....")
  shell.run("pastebin", "get", "u8ubAuT4", "ladder")
  print("Ladder Builder Download Complete....")
  shell.run("ladder")
elseif selected ==3 then
  write "Version 1 or 2? "
  write "1, 2? "
  input = read()
  if input == "1" then
  print("Downloading Replicator Program v1....")
   shell.run("rm", "startup")
   shell.run("pastebin", "get", "3fnFhwvd", "startup")
   print("Replicator Program Download Complete....")
   shell.run("startup")
  elseif input == "2" then
  print("Downloading Replicator Program v2....")
   shell.run("rm", "startup")
   shell.run("pastebin", "get", "2Zf5an8H", "startup")
   print("Replicator Program Download Complete....")
   shell.run("startup")
  end
elseif selected ==4 then
  shell.run("rm", "startup")
  print("Downloading Auto Tree Farm....")
  shell.run("pastebin", "get", "bbpeedQ7", "startup")
  print("Auto Tree Farm Download Complete....")
  print("Starting Program....")
  shell.run("startup")
elseif selected ==5 then
mainMenu()
else
return
end
end -- func TurtleMenu
function PocketMenu()
shell.run("clear")
term.setTextColour(colors.white)
local startY = termY/2-#pocket_options/2
for i=1, #pocket_options do
  centerPrint("["..i.."] "..pocket_options[i], startY)
  startY = startY + 1
end
term.setCursorPos(1, termY)
term.write("Press a number to select the menu option...")
local selected = false
while true do
  local e = {os.pullEvent()}
  if e[1] == "char" then
	if pocket_options[tonumber(e[2])] then
		  selected = tonumber(e[2])
		  break
	end
  end
end
print("You've selected: ".. pocket_options[selected])
if selected == 1 then
  print("Downloading cc10 Remote....")
  shell.run("pastebin", "get", "mbEHZZnh", "cc10")
  print("cc10host Complete....")
  shell.run("cc10")
  end
if selected == 2 then
  mainMenu()
else
return
end
end -- func pocketMenu
function OtherMenu()
shell.run("clear")
term.setTextColour(colors.white)
local startY = termY/2-#other_options/2
for i=1, #other_options do
  centerPrint("["..i.."] "..other_options[i], startY)
  startY = startY + 1
end
term.setCursorPos(1, termY)
term.write("Press a number to select the menu option...")
local selected = false
while true do
  local e = {os.pullEvent()}
  if e[1] == "char" then
	if other_options[tonumber(e[2])] then
		  selected = tonumber(e[2])
		  break
	end
  end
end
print("You've selected: ".. other_options[selected])
if selected == 1 then
  print("Downloading All Scripts to Disk....")
  for name,code in pairs(programs) do
  shell.run("pastebin", "get",code, "/disk/",name)
  print("Mass Download Complete....")
  end
elseif selected ==2 then
mainMenu()
else
return
end
end
term.clear()
term.setTextColour(colors.red)
local password = "ada"
print ("Enter Password")
local input = read("*")
if input == password then
term.setTextColour(colors.green)
print("Password is correct. Access granted.")
sleep(1)
welcomeBack()
mainMenu()
function findMonitor()
		local face
		if (peripheral.find("monitor"))and(peripheral.isPresent("left")) then
				face="left"
	print("Monitor Found on " .. face)
				return true, face
		elseif (peripheral.find("monitor"))and(peripheral.isPresent("right")) then
				face="right"
	print("Monitor Found on " .. face)
				return true, face
		elseif (peripheral.find("monitor"))and(peripheral.isPresent("bottom")) then
				face="bottom"
	print("Monitor Found on " .. face)
				return true, face
		elseif (peripheral.find("monitor"))and(peripheral.isPresent("top")) then
				face="top"
	print("Monitor Found on " .. face)
				return true, face
		elseif (peripheral.find("monitor"))and(peripheral.isPresent("back")) then
				face="back"
	print("Monitor Found on " .. face)
				return true,face
		else
				face=""
	print("No Monitor Found")
				return false,face
		end
end
function findModem()
  if peripheral.find("modem") then
	print("Modem Found")
	fMo()
  else
	print("Modem NOT Found")
  end

end
function fMo()
local function openRednet()
for _,side in ipairs({"top", "bottom", "front", "left", "right", "back"}) do
   if peripheral.isPresent(side) and peripheral.getType(side) == "modem" then
   rednet.open(side)
   return side
   end
  end
  print("no wifi present")
end
modemSide = openRednet()
if modemSide == nil then
  print("No modem connected")
else
  print("Opened modem on "..modemSide)
end
end
--findMonitor()
--findModem()
end


From spoiler, that i added, iv took out two codes, one was button (api), secound was startup.
Startup - https://pastebin.com/0f455rvM
Button (API) - https://pastebin.com/ScRu9crS

So i started modifying it to serve my needs.
I havnt started with adding bunduled output's for fun1() till fun16(). But i belive that i will manage that.

My problem is.
when ever i load the program - i press button('s) "1-8" or "9-16" , computer stops the program and writes:
button: 74: attempt to index ? (a nill value).
I did read forum's topic "Read This Post Before Asking Questions"
but it didnt made any sense for me. i tried to fix it but my trying made it worse.
so im baisicly stuck.

modified codes:
Button(api) - https://pastebin.com/Z6zq3TW3
Startup - https://pastebin.com/xF6LiU5G

Here are some of in game screens-shoots.
SpoilerFirst image is when program is running and nothing is pressed.
Spoiler
When button "1-8" was pressed it stop't the program. (same goes with button "9-16"
Spoiler
This is the error.
Spoiler


Thanks for reading this. Hope someone can help with this.
Edited on 05 April 2018 - 08:02 AM
Lupus590 #2
Posted 04 April 2018 - 12:42 PM
The error explained: button: 74: attempt to index ? (a nill value)

button:
This is the name of the file that the error occured in.

74:
This is the line number that the error was noticed on.
(Sometimes lua notices the error long after the cause of the error, in which case you will need to keep in mind scope to track the error. - Luckily, the error you have at the moment is simple and doesn't 'move')

attempt to index ? (a nill value)
There is a variable on the line referenced which is being used as a table but is not a table (and is actually nil, or an unset variable), this can be indication of a spelling mistake in the variable name, missing initialisation of the variable, or a leftover reference after deleting the variable.


Edit: actually looking at your code, your modified button code doesn't have anything on the erroring line. The original has one variables being indexed twice: bData check that bData is a table before the for loop. (Also I suspect that you have the pastebin links the wrong way round.)
Edited on 04 April 2018 - 10:46 AM
7_Seven #3
Posted 04 April 2018 - 10:18 PM
Yeah sorry about that, when i uploaded a code, i did add –Startup and –Button text.
And did'nt think of that the code moves down and it does not show the actual line, that the screen was provided in spoiler.
I will re-upload code without any added text.
Button(api) - https://pastebin.com/Z6zq3TW3
Startup - https://pastebin.com/xF6LiU5G


actual line for error 74(screen):
Spoiler


About bData - it has yspot and xspot if you are talking about the same lines as i am.
When i'm reading them they are making sort of sense.
Is it function fillButton(text, color, bData) line number 48 in re-uploaded code?


I will edit the main topic with a new uploaded link's so that people does not get confused.


About the error, when i did read about it in the first time (in pinned topic) it made sense, then i checked the code again and was the same way confused as before.
Same thing happened this time i read your'e explanation, it made sense, but after compared to the code, and my brain was confused again.
Lupus590 #4
Posted 05 April 2018 - 06:58 PM
Based on the screenshot of the code, either button is nil or button[name] is nil.

Try adding a new line above that (but still part of the function) with the following code.


if not button then error("Could not find button table",2) end
if not button[name] then error("No button called "..tostring(name), 2) end
7_Seven #5
Posted 05 April 2018 - 08:34 PM
Yeah, now it says that their is no such button, thanks to added code.
How do i make it so that it reads (find's) a button's "1-8" and button "9-16"?
Cause when i click on "Select" button it flashes and does not stop the program.
So baisicly im understanding that i have to specify those two buttons that they are indeed a clickable buttons.
but it does not make senses again.

Because:
Spoiler

function fT1()
  button.clearAll()
--1.		2.
  button.addButton("1-8",	fT2,	 1,  9, 1, 1)
  button.addButton("SELECT", fT1, 10, 20, 1, 1)
  button.addButton("9-16",   fT3,	21, 29, 1, 1)
  button.screenButton()
end

1.

function toggleButton(name)
  button[name]["active"] = not button[name]["active"]		  -- <---
  screenButton()
end

2.

function addButton(name, func, xmin, xmax, ymin, ymax, color, activeColor)	   -- <---
  color = color or colors.red
  activeColor = activeColor or colors.lime
  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
  button[name]["color"] = color
  button[name]["activeColor"] = activeColor
end

Or this is wrong?
Maybe problem is in "function fT1()", "function fT2()" and "function fT3()"?
If so how do i specify it so that it is a button?


Screen shoot:
Spoiler
Lupus590 #6
Posted 06 April 2018 - 10:53 AM
replace line 81 with this:


local ok, err = pcall(toggleButton, name)
if not ok then error(err, 2) end
Edited on 06 April 2018 - 09:15 AM
7_Seven #7
Posted 06 April 2018 - 08:09 PM
I did replace the code.
But error is looping back to it self "function flash(name)".
As far as i understanding that it does loop back to itself.

Screenshoots:


SpoilerErrors line screenshoot:



The code screenshoot:
Lupus590 #8
Posted 06 April 2018 - 11:44 PM
Try renaming the table in the button API to something other than button (bottons or b should be fine). Do not rename anything in your startup file.
Edited on 07 April 2018 - 08:14 PM
7_Seven #9
Posted 07 April 2018 - 08:17 PM
I replaced whole Button API - where was "button" or "textButton" to "butt" or "textButt" with a save and computers restart -
it dropped this error for startup program.

That makes sense cause there is nothing in startup program that specify's "butt".
Spoiler

function fT1() is at line 6. This is ftom "Satartup" program.

function fT1()
  button.clearAll()
  button.addButton("1-8",    fT2,	 1,  9, 1, 1)
  button.addButton("SELECT", fT1, 10, 20, 1, 1)
  button.addButton("9-16",   fT3,    21, 29, 1, 1)
  button.screenButton()
end
Lupus590 #10
Posted 07 April 2018 - 10:13 PM
Can you post your code again?

Edit: Explaining the error, it means that it has found a table called button but could not find a function in that table called addButton (assuming that I have found the right line). Does the error still happen if you don't call button.clearAll?
Edited on 07 April 2018 - 08:54 PM
7_Seven #11
Posted 08 April 2018 - 08:46 PM
I removed that line in startup "button.clearAll()".
Now it sort a works without error's.

But there is another problem.
When ever I press button "1-8" and after that i press "9-16", the buttons overlap.
Spoiler

function fun1()
--colors.white
print(1)
end
function fun2()
--colors.orange
print(2)
end
I did add thees lines for all button (1-16) function's. (Ignore –color.color)
So i could see if they are working even.
They are pressable but doesn't work as they should.

Screens:
SpoilerOverlap:


I was pressin buttons in order: 9, 2, 3, 4, 5, 14, 15, 8.


Sure Here is the re-uploaded files:
SpoilerButton (API): https://pastebin.com/4fTVK9z7

Startup : https://pastebin.com/YmhS9DJC
Lupus590 #12
Posted 09 April 2018 - 10:08 PM
Try changing line 10 of your button API to local button = {} and uncommenting calls to button.clearAll in your program.
7_Seven #13
Posted 14 April 2018 - 09:43 PM
Thank you Lupus590!
Now the code is working, as i wanted.
Tank you one more time!