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

menu page

Started by elminister, 26 September 2012 - 06:45 AM
elminister #1
Posted 26 September 2012 - 08:45 AM
Hello,

i have setup a system to get items from computer via rednet and redpower. However it works. But there is an issue i would like to find a better solution.

I use tables to print a options menu. But if i use more options then the terminal can hold the menu mess up and the program don't work anymore. I want a "NEXT PAGE" Button to print more options. I can do it with shell.run page2 but i asking if there is a better way to putt all my options in one code.

I'm new to lua and i use and change the code from another forum user here. Thank for that!

Regards

Here is my code for the host:


rednet.open ("left")
local client1_id = 83
local options = {
"Marble",
"Cobblestone",
"Basalt Cobblestone",
"Sand",
"Sandstone",
"Glass",
"Wheat",
"Dirt",
"Iron Ore",
"Copper Ore",
"Tin Ore",
"Gold Ore",
"Diamonds",
"Coal",
"NEXT PAGE",
--you can add more in here
}
local function opt(m,mY)
n=1
l=#m
while true do
for i=1, l, 1 do
if i==n then
local x, y = term.getSize()
local b = string.len(">"..m[i].."<")/2
local x = (x/2)-b
term.setCursorPos(x,i+mY)
term.clearLine()
print(">"..m[i].."<")
else
local x, y = term.getSize()
b = string.len(m[i])/2
x = (x/2)-b
term.setCursorPos(x,i+mY)
term.clearLine()
print(m[i]) end
end
a, b= os.pullEventRaw()
if a == "key" then
if b==200 and n>1 then n=n-1 end
if b==208 and n<l then n=n+1 end
if b==28 then break end
end
end
term.clear() term.setCursorPos(1,1)
return n
end
while true do
term.clear()
term.setCursorPos(1,1)
print("What item do you want?")
local item = opt(options,2) --the second parameter is the y position start point
if item == 1 then
term.clear()
term.setCursorPos(1,1)
print("How many Marble do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "white") -- MARBLE
sleep(.1)
rednet.send(client1_id, "white")
sleep(.6)
end
elseif item == 2 then
term.clear()
term.setCursorPos(1,1)
print("How many Cobblestone do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "black") -- COBBLESTONE
sleep(.1)
rednet.send(client1_id, "black")
sleep(.6)
end
elseif item == 3 then
term.clear()
term.setCursorPos(1,1)
print("How many Basalt Cobblestone do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "orange") -- BASALT COBBLESTONE
sleep(.1)
rednet.send(client1_id, "orange")
sleep(.6)
end
elseif item == 4 then
term.clear()
term.setCursorPos(1,1)
print("How many Sand do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "magenta") -- SAND
sleep(.1)
rednet.send(client1_id, "magenta")
sleep(.6)
end
elseif item == 5 then
term.clear()
term.setCursorPos(1,1)
print("How many Sandstone do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "lightBlue") -- SANDSTONE
sleep(.1)
rednet.send(client1_id, "lightBlue")
sleep(.6)
end
elseif item == 6 then
term.clear()
term.setCursorPos(1,1)
print("How many Glass do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "yellow") -- GLASS
sleep(.1)
rednet.send(client1_id, "yellow")
sleep(.6)
end
elseif item == 7 then
term.clear()
term.setCursorPos(1,1)
print("How many Wheat do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "lime") -- WHEAT
sleep(.1)
rednet.send(client1_id, "lime")
sleep(.6)
end
elseif item == 8 then
term.clear()
term.setCursorPos(1,1)
print("How many Dirt do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "gray") -- DIRT
sleep(.1)
rednet.send(client1_id, "gray")
sleep(.6)
end
elseif item == 9 then
term.clear()
term.setCursorPos(1,1)
print("How many Iron Ore do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "lightGray") -- IRON ORE
sleep(.1)
rednet.send(client1_id, "lightGray")
sleep(.6)
end
elseif item == 10 then
term.clear()
term.setCursorPos(1,1)
print("How many Copper Ore do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "cyan") -- COPPER ORE
sleep(.1)
rednet.send(client1_id, "cyan")
sleep(.6)
end
elseif item == 11 then
term.clear()
term.setCursorPos(1,1)
print("How many Tin Ore do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "purple") -- TIN ORE
sleep(.1)
rednet.send(client1_id, "purple")
sleep(.6)
end
elseif item == 12 then
term.clear()
term.setCursorPos(1,1)
print("How many Gold Ore do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "blue") -- GOLD ORE
sleep(.1)
rednet.send(client1_id, "blue")
sleep(.6)
end
elseif item == 13 then
term.clear()
term.setCursorPos(1,1)
print("How many Diamonds do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "brown") -- DIAMONDS
sleep(.1)
rednet.send(client1_id, "brown")
sleep(.6)
end
elseif item == 14 then
term.clear()
term.setCursorPos(1,1)
print("How many Coal do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
rednet.send(client1_id, "green") -- COAL
sleep(.1)
rednet.send(client1_id, "green")
sleep(.6)
end

---
elseif item == 99 then
term.clear()
term.setCursorPos(1,1)
sleep(.2)
shell.run("item2") -- Next Page
close()
end
end
Doyle3694 #2
Posted 26 September 2012 - 09:04 AM
just a tip, for simplicity, don't do a, b = os.pullEventRaw()

put 'os.pullEvent = os.pullEventRaw' at the top of your program, and then use a, b = os.pullEvent("key"). Makes simplicity…
jag #3
Posted 26 September 2012 - 04:01 PM
You could definitely make the code shorter with some function!
Instead of doing:
term.clear()
term.setCursorPos(1,1)
print("How many Dirt do you want?")
write("Number: ")
local number = tonumber(read())
for i = 1,number do
  rednet.send(client1_id, "gray") -- DIRT
  sleep(.1)
  rednet.send(client1_id, "gray")
  sleep(.6)
end
… you could easily do it with:
-- This goes to the top!
function requestItem(itemName, itemColor)
  term.clear()
  term.setCursorPos(1,1)
  print("How many ".. itemName .." do you want?")
  write("Number: ")
  local number = tonumber(read())
  for i = 1,number do
	rednet.send(client1_id, itemColor) -- DIRT
	sleep(.1)
	rednet.send(client1_id, itemColor)
	sleep(.6)
  end
end
And then switch out the long script to:
if item == 1 then
  -- Marble example
  requestItem("Marble", "white")
  elseif item == 2 then
  -- Cobblestone example
  requestItem("Cobblestone", "black")
end
Really simple, much cleaner!

So this is how the new code should look like:
Spoiler
function requestItem(itemName, itemColor)
  term.clear()
  term.setCursorPos(1,1)
  print("How many ".. itemName .." do you want?")
  write("Number: ")
  local number = tonumber(read())
  for i = 1,number do
        rednet.send(client1_id, itemColor) -- DIRT
        sleep(.1)
        rednet.send(client1_id, itemColor)
        sleep(.6)
  end
end

rednet.open ("left")
local client1_id = 83
local options = {
  "Marble",
  "Cobblestone",
  "Basalt Cobblestone",
  "Sand",
  "Sandstone",
  "Glass",
  "Wheat",
  "Dirt",
  "Iron Ore",
  "Copper Ore",
  "Tin Ore",
  "Gold Ore",
  "Diamonds",
  "Coal",
  "NEXT PAGE",
  --you can add more in here
}

local function opt(m,mY)
  n=1
  l=#m
  while true do
    for i=1, l, 1 do
      if i==n then
        local x, y = term.getSize()
        local b = string.len(">"..m[i].."<")/2
        local x = (x/2)-b
        term.setCursorPos(x,i+mY)
        term.clearLine()
        print(">"..m[i].."<")
      else
        local x, y = term.getSize()
        b = string.len(m[i])/2
        x = (x/2)-b
        term.setCursorPos(x,i+mY)
        term.clearLine()
        print(m[i])
      end
    end
  a, b= os.pullEventRaw()
  if a == "key" then
    if b==200 and n>1 then n=n-1 end
      if b==208 and n<l then n=n+1 end
        if b==28 then break 
        end
      end
    end
  term.clear() term.setCursorPos(1,1)
  return n
end
while true do
  term.clear()
  term.setCursorPos(1,1)
  print("What item do you want?")
  local item = opt(options,2) --the second parameter is the y position start point
  if item == 1 then
    requestItem("Marble", "white")
  elseif item == 2 then
    requestItem("Cobblestone", "black")
  elseif item == 3 then
    requestItem("Basalt Cobblestone", "orange")
  elseif item == 4 then
    requestItem("Sand", "magenta")
  elseif item == 5 then
    requestItem("Sandstone", "lightBlue")
  elseif item == 6 then
    requestItem("Glass", "yellow")
  elseif item == 7 then
    requestItem("Wheat", "lime")
  elseif item == 8 then
    requestItem("Dirt", "gray")
  elseif item == 9 then
    requestItem("Iron Ore", "lightGray")
  elseif item == 10 then
    requestItem("Copper Ore", "cyan")
  elseif item == 11 then
    requestItem("Tin Ore", "purple")
  elseif item == 12 then
    requestItem("Gold Ore", "blue")
  elseif item == 13 then
    requestItem("Diamonds", "brown")
  elseif item == 14 then
    requestItem("Coal", "green")
  elseif item == 99 then
    term.clear()
    term.setCursorPos(1,1)
    sleep(.2)
    shell.run("item2") -- Next Page
    close()
  end
end
Cranium #4
Posted 26 September 2012 - 04:27 PM
Lemme ask, how many items are you looking to request?
elminister #5
Posted 26 September 2012 - 04:46 PM
@jag_e_nummer_ett i'm speakless.. thank you!

@Cranium thats why i use the rednet method. I'ts more than 64 different items. I know i think the solution with "Next Page" it's not the best to choose between the items..
Cranium #6
Posted 26 September 2012 - 04:58 PM
Wow, that many items? I don't think you could fit that on a screen…
What you may need to do is set up an initial option menu, saying to select items sorted a-z, alphabetically, or by item id, which might be neat. You could also do a search function. All a little annoying, but very doable. For searching, just ask for an input, like this:

write("Please enter your search term: ")
local input = string.lower(read())
for i = 1,#options do --make sure options is FULL of all available items
if input == options[i] then select = i end
end
--just use your existing if/elseif commands to determine which item to bring to you. make sure to use if select == "this option" then
elminister #7
Posted 26 September 2012 - 08:34 PM
Mhh Cranium,

wow i feel the new code feels a lot faster :P/>/>

I try it with the item search.. it works but only sends "white" i try it with cobblestone and basalt but it always send the white signal.

Here is the code:

http://pastebin.com/NFSWuC9Z
Cranium #8
Posted 26 September 2012 - 08:53 PM
Sorry, I should have clarified, I was really tired when I suggested this. Lemme give you a break:

function requestItem(itemName, itemColor)
  term.clear()
  term.setCursorPos(1,1)
  print("How many ".. itemName .." do you want?")
  write("Number: ")
  local number = tonumber(read())
  for i = 1,number do
	    rednet.send(client1_id, itemColor) -- DIRT
	    sleep(.1)
	    rednet.send(client1_id, itemColor)
	    sleep(.6)
  end
end
rednet.open ("left")
local client1_id = 83
local options = {
  "Marble",
  "Cobblestone",
  "Basalt",
  "Sand",
  "Sandstone",
  "Glass",
  "Wheat",
  "Dirt",
  "Iron Ore",
  "Copper Ore",
  "Tin Ore",
  "Gold Ore",
  "Diamonds",
  "Coal",
  "NEXT PAGE",
  --you can add more in here
}
local colorList = {
"white",
"black",
"orange",
"magenta",
"lightBlue",
"yellow",
"lime",
"gray",
"lightGray",
"cyan",
"purple",
"blue",
"brown",
"green"
--add more colors dependent only on the number of options.
--for example, options 3 MUST correlate to colorList[3]. NO EXCEPTIONS.
}
local function opt(m,mY)
  n=1
  l=#m
  while true do
    for i=1, l, 1 do
	  if i==n then
	    local x, y = term.getSize()
	    local b = string.len(">"..m[i].."<")/2
	    local x = (x/2)-b
	    term.setCursorPos(x,i+mY)
	    term.clearLine()
	    print(">"..m[i].."<")
	  else
	    local x, y = term.getSize()
	    b = string.len(m[i])/2
	    x = (x/2)-b
	    term.setCursorPos(x,i+mY)
	    term.clearLine()
	    print(m[i])
	  end
    end
  a, b= os.pullEventRaw()
  if a == "key" then
    if b==200 and n>1 then n=n-1 end
	  if b==208 and n<l then n=n+1 end
	    if b==28 then break
	    end
	  end
    end
  term.clear() term.setCursorPos(1,1)
  return n
end
local function search()
term.clear()
term.setCursorPos(1,1)
write("Please enter your search term: ")
local input = read()
for i = 1,#options do --make sure options is FULL of all available items
if input == options[i] then
requestItem(options[i],colorList[i]
end
end
end
If you use the search function, it should allow you to search with the phrases as they appear in the options menu. This only works if the colorList items correlate to the same colors you are using for the lines in options.
For example, I used options[3], which is Basalt, MUST have the color you want in colorList in the same position. In this instance that would be orange, in position [3] in colorList.
elminister #9
Posted 26 September 2012 - 09:25 PM
hey nvm :P/>/> you helped me a lot so for to build my mega item network! thank you

Your code looks really nice and i want to use them but:

bios:206: [string "item3]:92: ')' ecpected (to close 'C' at line 91)

there is something wrong in your code. can you please take a look over them ? :D/>/>
sjele #10
Posted 26 September 2012 - 09:31 PM

function requestItem(itemName, itemColor)
  term.clear()
  term.setCursorPos(1,1)
  print("How many ".. itemName .." do you want?")
  write("Number: ")
  local number = tonumber(read())
  for i = 1,number do
		    rednet.send(client1_id, itemColor) -- DIRT
		    sleep(.1)
		    rednet.send(client1_id, itemColor)
		    sleep(.6)
  end
end
rednet.open ("left")
local client1_id = 83
local options = {
  "Marble",
  "Cobblestone",
  "Basalt",
  "Sand",
  "Sandstone",
  "Glass",
  "Wheat",
  "Dirt",
  "Iron Ore",
  "Copper Ore",
  "Tin Ore",
  "Gold Ore",
  "Diamonds",
  "Coal",
  "NEXT PAGE",
  --you can add more in here
}
local colorList = {
"white",
"black",
"orange",
"magenta",
"lightBlue",
"yellow",
"lime",
"gray",
"lightGray",
"cyan",
"purple",
"blue",
"brown",
"green"
--add more colors dependent only on the number of options.
--for example, options 3 MUST correlate to colorList[3]. NO EXCEPTIONS.
}
local function opt(m,mY)
  n=1
  l=#m
  while true do
    for i=1, l, 1 do
		  if i==n then
		    local x, y = term.getSize()
		    local b = string.len(">"..m[i].."<")/2
		    local x = (x/2)-b
		    term.setCursorPos(x,i+mY)
		    term.clearLine()
		    print(">"..m[i].."<")
		  else
		    local x, y = term.getSize()
		    b = string.len(m[i])/2
		    x = (x/2)-b
		    term.setCursorPos(x,i+mY)
		    term.clearLine()
		    print(m[i])
		  end
    end
  a, b= os.pullEventRaw()
  if a == "key" then
    if b==200 and n>1 then n=n-1 end
		  if b==208 and n<l then n=n+1 end
		    if b==28 then break
		    end
		  end
    end
  term.clear() term.setCursorPos(1,1)
  return n
end
local function search()
term.clear()
term.setCursorPos(1,1)
write("Please enter your search term: ")
local input = read()
for i = 1,#options do --make sure options is FULL of all available items
if input == options[i] then
requestItem(options[i],colorList[i]) --You missed an ) here
end
end
end
Cranium #11
Posted 26 September 2012 - 09:38 PM
*snip*
You missed an ) here
Whoopsie! Silly mistake :P/>/>
elminister #12
Posted 26 September 2012 - 10:10 PM
ok thanks for the fix.

but now i'm starting the program with item3 and nothing happens. mhh :P/>/>

edit: i see the modem turns red. so the port to the modem is open.
Cranium #13
Posted 26 September 2012 - 10:19 PM
Wait…so you open the program by typing item3 to get item # 3? That's not how it works….
So what you would do is add search() at the end of the program, and it will run. as it is now, it's just a few tables and functions, no actual running code.
elminister #14
Posted 26 September 2012 - 10:36 PM
no thats the name of the program nothing more.. i put all the code in item3

now i put search() at the end of the code.. now it works. fantastic.. i must go to the understand that stuff. it really makes me happy lol :P/>/>
elminister #15
Posted 26 September 2012 - 10:46 PM
how i can do to not exit the program with still open rednet port. I just want to go back to write("Please enter your search term: ")
sjele #16
Posted 26 September 2012 - 10:47 PM
Use a loop.
Cranium #17
Posted 26 September 2012 - 10:49 PM
Just put this part in instead of the search() function:

local function search()
while true do --created an infinite loop
term.clear()
term.setCursorPos(1,1)
write("Please enter your search term: ")
local input = read()
for i = 1,#options do --make sure options is FULL of all available items
if input == options[i] then
requestItem(options[i],colorList[i])
elseif input == "exit" then break --adding an exit call here.
end
end
end
end
elminister #18
Posted 26 September 2012 - 11:00 PM

local function search()
while true do --created an infinite loop
term.clear()
term.setCursorPos(1,1)
write("Please enter your search term: ")
local input = read()
for i = 1,#options do --make sure options is FULL of all available items
if input == options[i] then
requestItem(options[i],colorList[i])
elseif input == "exit" then break --adding an exit call here.
end
end
end
end
search()

now it rocks :P/>/> really thanks again for your help Cranium and Sjele!
elminister #19
Posted 26 September 2012 - 11:34 PM
mhh i think we have a little design change..

i use

local client1_id = 83

to send the message to client 83. I want now add

local client2_id = 84

in my old variant there was no problem to send them messages. But in current code design i don't know how it works O_o
Cranium #20
Posted 26 September 2012 - 11:56 PM
Just send the message normally, but this time, you will have to ask which client to send to, and send using that variable. You would have to specify that client 1 handles items from 1 to 16, then client 2 handles from 17 to 32, and so on. Basically, if you modify the requestItem() function to sort that out, it can do it automatically.

function requestItem(itemName, itemColor,clientID) --added clientID parameter
  term.clear()
  term.setCursorPos(1,1)
  print("How many ".. itemName .." do you want?")
  write("Number: ")
  local number = tonumber(read())
  for i = 1,number do
				    rednet.send(clientID, itemColor) -- to be called here
				    sleep(.1)
				    rednet.send(clientID, itemColor)
				    sleep(.6)
  end
end

local function search()
while true do --created an infinite loop
term.clear()
term.setCursorPos(1,1)
write("Please enter your search term: ")
local input = read()
for i = 1,#options do --make sure options is FULL of all available items
if input == options[i] then
  if input <= 16 then  --sorting out which options get sent to which computer.
    requestItem(options[i],colorList[i],client_id1)
  elseif input >16 and input <=32 then
    requestItem(options[i],colorList[i],client_id1)
  end
elseif input == "exit" then break --adding an exit call here.
end
end
end
end
I have not tested any of this code, but it should work, I hope I helped a little.
elminister #21
Posted 27 September 2012 - 12:45 AM
i think

function requestItem(itemName, itemColor,clientID) --added clientID parameter

cannot recognize the parameter send from


if input == options[i] then
  if input <= 16 then  --sorting out which options get sent to which computer.
    requestItem(options[i],colorList[i],client_id1)
  elseif input >16 and input <=32 then
    requestItem(options[i],colorList[i],client_id2)

the error is item3:94 attempt to compare number with string expected, got number
Cranium #22
Posted 27 September 2012 - 12:49 AM
Oh, whoops…my mistake. It's trying to compare input, which is a string, to a number. It can't do that.Try replacing input with the variable i. That should work.
ChaddJackson12 #23
Posted 27 September 2012 - 01:11 AM
Don't make another code file. Just make a table or something called "options2" and reference to it using the more options button.
elminister #24
Posted 27 September 2012 - 01:38 AM
It works now, i forget a comma.
elminister #25
Posted 27 September 2012 - 01:43 AM
Here is the complete code so far:

http://pastebin.com/Ab1B7SmC