[Home] [Downloads] [Search] [Help/forum]


Register forum user name Search FAQ

Gammon Forum

[Folder]  Entire forum
-> [Folder]  MUSHclient
. -> [Folder]  Lua
. . -> [Subject]  Using nested tables with Ultis.listbox

Using nested tables with Ultis.listbox

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page


Posted by Notaskixa   (5 posts)  [Biography] bio
Date Sun 22 Jul 2012 04:07 PM (UTC)
Message
I'm new to using Lua, I'm used to Vbscript. The change seems to be a pretty big jump and I'm having a couple issues mainly with using the tables values and keys correctly. I'm trying to use nested tables and call only certain values to make a listbox. This is a simple version of my tables.

potsamnts = { healpots = 4, spellpots = 5}
pots = {
 healpots = { jade = { name = "jade", quantity = 1}, ballad = { name = "ballad" ,quantity = 3}},
 spellpots = { tea = { name = "tea", quantity = 3}, tears = { name = "tears", quantity = 2}},
}


What I want the listbox to do is display the options as the keys from the the sub-tables pots.healpots and pots.spellpots with the value of their quantity keys added to the end. The only way I can figure out how to get it to display the keys I want is to combine the sub-tables but that jumbles an already cluttered plugin and would prefer not to, and I cannot figure out how to get it to add the values without receiving errors. That I'm pretty sure just come from my ineptitude with Lua. This is just a small part of a complex plugin and seems to be the main problem I'm having.
[Go to top] top

Posted by Nick Gammon   Australia  (22,982 posts)  [Biography] bio   Forum Administrator
Date Reply #1 on Sun 22 Jul 2012 09:55 PM (UTC)
Message
You seem to have duplication there. Each word appears twice (eg. jade, jade)

For the listbox you need to get the required things into a temporary table keyed by a number. Here is an example:


potsamnts = { healpots = 4, spellpots = 5}
pots = {
 healpots = { jade = 1, ballad = 3 },
 spellpots = { tea = 3, tears = 2 },
}

pots = pots.spellpots   -- or whatever

local choices = {}

for k, v in pairs (pots) do
  table.insert (choices, k)
end -- for

result = utils.listbox ("Choose a pot", "Pots ...", choices)

if result then
  print ("You chose", choices [result])
  print ("Quantity =", pots [ choices [result] ] )
else
  print "Nothing chosen"
end -- if


The table.insert inserts into choices each item from the required table. Then we can index back into the original to find the quantity.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Notaskixa   (5 posts)  [Biography] bio
Date Reply #2 on Mon 23 Jul 2012 08:35 AM (UTC)

Amended on Mon 23 Jul 2012 08:58 AM (UTC) by Notaskixa

Message
Nick thanks for the input what you posted is close to what I have but still doesn't solve what I'm trying to do. I did go ahead and simplify the pots table like you suggested. I wanted to display the value for each key beside it in the listbox with the key not after selection. here's my actual function

 potsamnts = { healpots = 4, spellpots = 5}
 pots = { tea = {3}, ballad = {3}, jade = {1}, tears = {2} }
 jade = pots.jade
 ballad = pots.ballad
 tea = pots.tea
 tears = pots.tears
 
function makepotionstable()
list = {}

for k, v in pairs (pots) do
  table.insert (list, k)
end -- for

result = utils.listbox ("Choose a potion to drink","Selecting a potion", list, "jade")
if result ~= nil then
choice = (list[result])
Note (list [result])
Execute ("sip " .. list[result])
Note("Searching for " .. list[result] .. " in storage")
table.insert (choice, 1, pots [ list [result] ] -1)
end -- if
SaveState()
end


When I call the function I get this error

[string "Script file"]:21: attempt to perform arithmetic on field '?' (a table value)
stack traceback:
        [string "Script file"]:21: in function <[string "Script file"]:8>
Error context in script:
  17 : choice = (list[result])
  18 : Note (list [result])
  19 : Execute ("sip " .. list[result])
  20 : Note("Searching for " .. list[result] .. " in storage")
  21*: table.insert (choice, 1, pots [ list [result] ] -1)


I am using the nested tables to make editing the values easier since i can't figure out how to make it edit the value instead of the table itself without them. My first tries caused a new key and value to be added to pots instead of changing them. And cannot use strings for the pos in table.insert (t, pos, v) also the default doesn't seem to work in __listbox (..., ..., t, "default")
[Go to top] top

Posted by Notaskixa   (5 posts)  [Biography] bio
Date Reply #3 on Tue 24 Jul 2012 03:26 AM (UTC)
Message
I also tried using tonumber to convert the table value


function makepotionstable()
list = {}

for k, v in pairs (pots) do
  table.insert (list, k)
end -- for

result = utils.listbox ("Choose a potion to drink","Selecting a potion", list, "jade")
if result ~= nil then
choice = (list[result])
Note (list [result])
Execute ("sip " .. list[result])
Note("Searching for " .. list[result] .. " in storage")
table.insert (choice, 1,tonumber( pots [ list [result] ]) -1)
end -- if
SaveState()
end


But it returns this error when called


[string "Script file"]:21: attempt to perform arithmetic on a nil value
stack traceback:
        [string "Script file"]:21: in function <[string "Script file"]:8>
Error context in script:
  17 : choice = (list[result])
  18 : Note (list [result])
  19 : Execute ("sip " .. list[result])
  20 : Note("Searching for " .. list[result] .. " in storage")
  21*: table.insert (choice, 1,tonumber( pots [ list [result] ]) -1)
  22 : end -- if
[Go to top] top

Posted by Nick Gammon   Australia  (22,982 posts)  [Biography] bio   Forum Administrator
Date Reply #4 on Wed 25 Jul 2012 03:06 AM (UTC)
Message
I'm not sure what is going through your head here:


pots = { tea = {3}, ballad = {3}, jade = {1}, tears = {2} }


That makes tea have a value of a table which has a single item in it, where the item has a key of 1 and a value of 3. Why not:


pots = { tea = 3, ballad = 3, jade = 1, tears = 2 }


The code below shows the quantity in the listbox, and uses a different method to extract that out if the player selects one:


potsamnts = { healpots = 4, spellpots = 5}
pots = {
 healpots = { jade = 1, ballad = 3 },
 spellpots = { tea = 3, tears = 2 },
}

pots = pots.spellpots   -- or whatever

local choices = {}

for k, v in pairs (pots) do
  table.insert (choices, string.format ("%s (%d)", k, v))
end -- for

result = utils.listbox ("Choose a pot", "Pots ...", choices)

if result then
  print ("You chose", choices [result])
  qty = tonumber (string.match (choices [result], "%((%d+)%)"))
  print ("Quantity =", qty )
else
  print "Nothing chosen"
end -- if

- Nick Gammon

www.gammon.com.au, www.mushclient.com
[Go to top] top

Posted by Notaskixa   (5 posts)  [Biography] bio
Date Reply #5 on Wed 25 Jul 2012 07:21 AM (UTC)

Amended on Wed 25 Jul 2012 07:27 AM (UTC) by Notaskixa

Message
Quote:
I'm not sure what is going through your head here:

pots = { tea = {3}, ballad = {3}, jade = {1}, tears = {2} }



I tried to explain that in one of my posts but i will try to clarify what i meant. I am trying to use table.insert to track how many potions are available and display the number available in the listbox

Quote:

I am using the nested tables to make editing the values easier since i can't figure out how to make it edit the value instead of the table itself without them. My first tries caused a new key and value to be added to pots instead of changing them.


using modified version of your code


if result then
  print ("You chose", choices [result])
  qty = tonumber (string.match (choices [result], "%((%d+)%)"))
  print ("Quantity =", qty )
  table.insert (pots,  tonumber (string.match (choices [result], "%((%d+)%)")) -1)  
else
  print "Nothing chosen"
end -- if
end


now if we call the script 2 times and choose ballad which had a value of 3 at the start, the value hasn't changed and displays the same in the listbox as 'ballad (3)' instead of 'ballad (1)' using '/tprint (pots)' shows that two new keys have been added 1=2 and 2=2

Quote:

And cannot use strings for the pos in table.insert (t, pos, v)


if result then
  print ("You chose", choices [result])
  qty = tonumber (string.match (choices [result], "%((%d+)%)"))
  print ("Quantity =", qty )
  table.insert (pots, (choices[result]), tonumber (string.match (choices [result], "%((%d+)%)")) -1)  
else
  print "Nothing chosen"
end -- if

returns this error when you run the script

[string "Script file"]:26: bad argument #2 to 'insert' (number expected, got string)
stack traceback:
        [C]: in function 'insert'
        [string "Script file"]:26: in function <[string "Script file"]:9>


I was using the nested tables with the numbered key to allow me to use 1 as the 'pos' value in table.insert
I just cannot figure out how to make it edit the value of the key being selected instead of the table itself by adding keys using your method,or to edit the correct sub-table without making a long conditional using the one I was trying.
[Go to top] top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


14,088 views.

It is now over 60 days since the last post. This thread is closed.     [Refresh] Refresh page

Go to topic:           Search the forum


[Go to top] top

Quick links: MUSHclient. MUSHclient help. Forum shortcuts. Posting templates. Lua modules. Lua documentation.

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.

[Home]


Written by Nick Gammon - 5K   profile for Nick Gammon on Stack Exchange, a network of free, community-driven Q&A sites   Marriage equality

Comments to: Gammon Software support
[RH click to get RSS URL] Forum RSS feed ( https://gammon.com.au/rss/forum.xml )

[Best viewed with any browser - 2K]    [Hosted at HostDash]