Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Due to spam on this forum, all posts now need moderator approval.
Entire forum
➜ MUSHclient
➜ General
➜ Having trouble printing a table
Having trouble printing a table
|
It is now over 60 days since the last post. This thread is closed.
Refresh page
Pages: 1 2
Posted by
| Shinth
(10 posts) Bio
|
Date
| Fri 10 Aug 2007 06:57 AM (UTC) Amended on Fri 10 Aug 2007 06:58 AM (UTC) by Shinth
|
Message
| Could someone tell me what is wrong with this function?
function change_priority(name,line,wildcards)
if (wildcards [1] == "health") then
healpriority = {}
healpriority = {health = "drink health", mana = "drink mana", ego = "drink bromide"}
end
if (wildcards [1] == "mana") then
healpriority = {}
Note ("mana")
healpriority = {mana = "drink mana", health = "drink health", ego = "drink bromide"}
for k, v in ipairs (healpriority) do
Tell (tostring(k),"=")
Note (v)
end -- for
end
if (wildcards [1] == "ego") then
healpriority = {}
healpriority = {ego = "drink bromide", health = "drink health", mana = "drink mana"}
end
ColourTell ("aqua","","Healing priority: ") ColourNote ("lime","", string.upper(wildcards [1]))
tprint (healpriority)
end
If I call the function with the wildcard "mana" (from an alias) and don't have tprint, the "for k,v in ipairs (healpriority)" loop doesn't do a thing, but it enters the if statement (that's why I put "Note" there, to check).
If I use tprint, no matter what wildcard I use, either health, mana or ego, it prints the same table
ego=drink bromide
mana=drink mana
health=drink health
I've been trying to see what is wrong with it for a couple of hours now, any suggestions? | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #1 on Fri 10 Aug 2007 07:04 AM (UTC) |
Message
| ipairs is designed to only iterate over numeric keys. You want pairs, not ipairs.
Your keys are the strings "mana", "health" and "ego", which are not numbers. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #2 on Fri 10 Aug 2007 07:07 AM (UTC) |
Message
|
Quote:
healpriority = {}
healpriority = {health = "drink health", mana = "drink mana", ego = "drink bromide"}
The first line there is redundant. You are recreating the table in the second line, and thus you create an empty table that has to be garbage-collected eventually. It is like writing this:
Not much point in the first line. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Shaun Biggs
USA (644 posts) Bio
|
Date
| Reply #3 on Fri 10 Aug 2007 07:17 AM (UTC) Amended on Fri 10 Aug 2007 07:20 AM (UTC) by Shaun Biggs
|
Message
| I'm not really entirely sure what the end result of this script would be, but here's how I would do what you have so far:
healqueues = { health = { "drink health", "drink mana", "drink bromide" },
mana = { "drink mana", "drink bromide", "drink health" },
ego = { "drink bromide", "drink health", "drink mana" } }
function change_priority(name,line,wildcards)
healpriority = healqueues[ wildcards[1] ]
ColourNote ("aqua","","Healing priority: ",
"lime","", string.upper(wildcards [1]) )
for k,v in ipairs( healpriority ) do
Note( k.."="..v )
end
end
This will let you access the highest priority with healpriority[1], just like a normal list. Some sanity checking will need to be done for making sure that healqueues[wildcards[1]] exists and isn't nil unless you're absolutely positive that sane values will be sent into the script.
oh, and here's the output of a quick test:
Healing priority: MANA
1=drink mana
2=drink bromide
3=drink health
Healing priority: HEALTH
1=drink health
2=drink mana
3=drink bromide
|
It is much easier to fight for one's ideals than to live up to them. | Top |
|
Posted by
| Shaun Biggs
USA (644 posts) Bio
|
Date
| Reply #4 on Fri 10 Aug 2007 08:18 AM (UTC) |
Message
| Odd thought on sanity checking... no change to the healpriorty variable if there isn't a bad value is passed. This is assuming that you declared healpriority somewhere globally...
healqueues = { health = { "drink health", "drink mana", "drink bromide" },
mana = { "drink mana", "drink bromide", "drink health" },
ego = { "drink bromide", "drink health", "drink mana" } }
healpriority = healqueues.health --make health the default
function change_priority(name,line,wildcards)
healpriority = healqueues[ wildcards[1] ] or healpriority
ColourNote ("aqua","","Healing priority: ",
"lime","", string.upper(wildcards [1]) )
for k,v in ipairs( healpriority ) do
Note( k.."="..v )
end
end
and the test data:
Healing priority: MANA
1=drink mana
2=drink bromide
3=drink health
Healing priority: WAFFLES
1=drink mana
2=drink bromide
3=drink health
|
It is much easier to fight for one's ideals than to live up to them. | Top |
|
Posted by
| Shinth
(10 posts) Bio
|
Date
| Reply #5 on Fri 10 Aug 2007 10:20 AM (UTC) Amended on Fri 10 Aug 2007 09:18 PM (UTC) by Nick Gammon
|
Message
| Thank you all for the help, I have decided to use an array instead of a table because I need it compared to the key of another table, but in a specific order. Another question, I've declared a table like this:
drinkqueue = {health=0;mana=0;ego=0}
So when I check the conditions to drink health:
drinkqueue.health="drink health"
I want to check if a key is 0, but for some reason v != 0 gives me the error:
Compile error
World: Lusternia
Immediate execution
[string "Script file"]:86: ')' expected near '!'
Error context in script:
82 : tprint(drinkqueue)
83 : if (todrink == 1) then
84 : for i=1,3 do
85 : for k,v in pairs (drinkqueue) do
86*: if (healpriority[i] == k) and (v != 0) then
Any ideas what is wrong with it? And also, a break in the second for loop will stop the first loop too? | Top |
|
Posted by
| Shaun Biggs
USA (644 posts) Bio
|
Date
| Reply #6 on Fri 10 Aug 2007 10:43 AM (UTC) Amended on Fri 10 Aug 2007 10:44 AM (UTC) by Shaun Biggs
|
Message
|
Quote: I have decided to use an array instead of a table because I need it compared to the key of another table, but in a specific order. In Lua, there is no difference between an array and a table. An "array" is merely a table with a sequential set of keys. Being a table, there is no practical difference at all between {health = "drink health", mana = "drink mana", ego = "drink bromide"} and {mana = "drink mana", health = "drink health", ego = "drink bromide"}. They both have the same keys and the same values, and order does not matter terribly much, since there isn't a numerical set dictating any order.
Quote: I want to check if a key is 0, but for some reason v != 0 gives me the error:
!= doesn't mean anything to a Lua interpreter. A nonequivalency is declared as ~= for this language.
If you would like to get a bit more familiar with Lua, this site is where I learned from: http://lua-users.org/wiki/TutorialDirectory I still use it quite frequently for reference. |
It is much easier to fight for one's ideals than to live up to them. | Top |
|
Posted by
| Shaun Biggs
USA (644 posts) Bio
|
Date
| Reply #7 on Fri 10 Aug 2007 11:05 AM (UTC) |
Message
| Would you mind posting the whole function? I'm getting confused with how the line drinkqueue.health="drink health" relates to drinkqueue = {health=0;mana=0;ego=0}
Break will just break the most recent block of code, so it won't exit all of your loops, just the last one. Keep in mind that the counter in a for loop is destroyed once the for loop is finished, so if you plan on keeping the value, use a while loop instead. |
It is much easier to fight for one's ideals than to live up to them. | Top |
|
Posted by
| Shinth
(10 posts) Bio
|
Date
| Reply #8 on Fri 10 Aug 2007 11:37 AM (UTC) Amended on Fri 10 Aug 2007 09:18 PM (UTC) by Nick Gammon
|
Message
| Thank you for the link, I will try the tutorials there as soon as I have time, they seem interesting.
And here is the function:
function system_drink ()
todrink=0
if (tonumber(GetVariable("health"))<math.floor(tonumber(GetVariable("MaxHealth"))*2/3)) then
drinkqueue.health="drink health"
todrink=1
end -- if
if (tonumber(GetVariable("mana"))<math.floor(tonumber(GetVariable("MaxMana"))*1/4)) then
drinkqueue.mana="drink mana"
todrink=1
end -- if
if (tonumber(GetVariable("ego"))<math.floor(tonumber(GetVariable("MaxEgo"))*1/3)) then
drinkqueue.ego="drink bromide"
todrink=1
end -- if
i = 1
while (todrink == 1) and (i <= 3) do
for k,v in pairs (drinkqueue) do
if (healpriority[i] == k) and (v ~= 0) then
Send (drinkqueue.v)
SetVariable("elixbal","0.5")
drinkqueue = {health = 0, mana = 0, ego = 0}
todrink=0
break
end -- if
end -- for
i = i+1
end -- while
end -- function
What I am trying to do is a priority based autosipper, when both my mana and health are low, for example, what will drink first will be set by my healpriority table. Basically it checks if the first item, then the next, and so on, in the healpriority table is below a certain level by checking if there is a value, not equal to 0, assigned to that attribute in the drink queue. If so, it drinks, sets my balance flag to 0.5, that means that I am waiting to actually drink from a vial and exits. It also resets the drinkqueue, just to be sure it will always cure based on my priorities. There might be some flaws here, I haven't test it yet.
Edit: it keeps spelling italic, I don't know why. | Top |
|
Posted by
| Shaun Biggs
USA (644 posts) Bio
|
Date
| Reply #9 on Fri 10 Aug 2007 12:41 PM (UTC) Amended on Fri 10 Aug 2007 09:26 PM (UTC) by Nick Gammon
|
Message
|
i = 1
while (todrink == 1) and (i <= 3) do
for k,v in pairs (drinkqueue) do
if (healpriority == k) and (v ~= 0) then
Send (drinkqueue.v)
SetVariable("elixbal","0.5")
drinkqueue = {health = 0, mana = 0, ego = 0}
todrink=0
break
end -- if
end -- for
i = i+1
end -- while
II'm not quite sure I understand the outer loop in this part. i is never used within the loop, so it will either do the loop once if you send a drink, or it will repeat three times if you don't send a drink (which is impossible due to you needing a drink in the first place.
I'm also still not clear on some of those variables. If the heal priority is the same as the function I posted above, then you should go through that array using ipairs to ensure the proper order, and match drinkqueue up with that.
The following block of code is how I would do the whole thing (both functions and supporting tables). Obviously, it's not the only way to do it, but this way you just have one loop to deal with testing and sending data. This will require changing the max health/mana/ego variables to lowercase, but if that would complicate things too much for other scripts, just change the keys/values for the various tables here. I tested this out with some dummy data, and it seemed to work. I've also taken advantage of quite a few scripting tricks to make the loop easier to deal with, such as concatenating the "max"..healpriority[i] have only one loop take care of all the data comparisons.
healstart = { health = 2/3, mana = 0.25, ego = 1/3 }
healaction = { health = "drink health", mana = "drink mana", ego = "drink bromide" }
healqueues = { health = { "health", "mana", "ego" },
mana = { "mana", "ego", "health" },
ego = { "ego", "health", "mana" } }
healpriority = healqueues.health --make health the default
function change_priority(name,line,wildcards)
healpriority = healqueues[ wildcards[1] ] or healpriority
ColourNote ("aqua","","Healing priority: ",
"lime","", string.upper(wildcards [1]) )
for k,v in ipairs( healpriority ) do
Note( k.."="..v.." action = "..healaction[v] )
end
end
function system_drink()
i = 1
repeat
if tonumber( GetVariable( healpriority[i] ) ) <
tonumber( GetVariable( "max"..healpriority[i] ) ) * healstart[healpriority[i]] then
Send( healaction[healpriority[i]] )
SetVariable( "elixbal", "0.5")
i = 3
end
i = i + 1
until i > 3
end
edit: Once again foiled by the forum eating my table brackets. |
It is much easier to fight for one's ideals than to live up to them. | Top |
|
Posted by
| Shaun Biggs
USA (644 posts) Bio
|
Date
| Reply #10 on Fri 10 Aug 2007 12:55 PM (UTC) Amended on Fri 10 Aug 2007 01:00 PM (UTC) by Shaun Biggs
|
Message
| if (tonumber(GetVariable("health"))<math.floor(tonumber(GetVariable("MaxHealth"))*2/3)) then
Two quick notes about these lines. First, you don't need to put the tonumber(GetVariable...) in parenthesis. Lua will recognize that fine as it is. Second, and the actual important one, is that there isn't really a point to using math.floor here unless you can somehow get 12.7 health or something like that. The test for 25 <= 25 is just the same as 25 < 25.12 and 26 <= 25 is just the same as 26 < 25.12. |
It is much easier to fight for one's ideals than to live up to them. | Top |
|
Posted by
| Shinth
(10 posts) Bio
|
Date
| Reply #11 on Fri 10 Aug 2007 02:19 PM (UTC) Amended on Fri 10 Aug 2007 03:25 PM (UTC) by Shinth
|
Message
| Very nice scripting, it's faster and you can also configure when to drink (like at 3/4*health, instead of 2/3). One thing though, this will run every prompt line, and could slow me down. The todrink variable was to do into the loop only if you needed to drink. But the again, when you needed to heal, you execute more lines, so I guess I will use yours, it looks better. And thanks for the advice about math.floor too!
Edit: It works great. Thank you! | Top |
|
Posted by
| Shaun Biggs
USA (644 posts) Bio
|
Date
| Reply #12 on Fri 10 Aug 2007 04:01 PM (UTC) |
Message
|
Quote: One thing though, this will run every prompt line, and could slow me down. The todrink variable was to do into the loop only if you needed to drink.
The way you originally had it set up worked the same way as mine. You had todrink set with 3 if statements, where I have it set with a loop of one if statement up to three times. I figured you would have the "elixbal" variable checked to see if you drank a potion already, surrounding the whole thing with an if GetVariable( "elixbal" ) ~= "0.5" bit. Or you could turn off the trigger with EnableTrigger( "triggername", false ) and turn it back on with the trigger that catches you drinking the potion. The latter option is what I tend to do, but I go crazy and solve things by turning triggers on and off like strobe lights. For simple things that's fine, but it can get complicated very quickly. |
It is much easier to fight for one's ideals than to live up to them. | Top |
|
Posted by
| Shinth
(10 posts) Bio
|
Date
| Reply #13 on Fri 10 Aug 2007 04:59 PM (UTC) |
Message
| I check to see if I have balance in the prompt trigger. And at the drink message I check to see if I had actually sent the drink command by seeing if the elixbal is 0.5. If it is, then I enable a failsafe timer in case I cannot sip because of an affliction. Then when the actual effect message of the potion is sent I check to see if I drank, then make my balance 0. When the message that I can drink another potion is sent, I check to see if I was off balance and assign elixbal=1. Complicated, but it is a good protection against illusion.
Quote:
Or you could turn off the trigger with EnableTrigger( "triggername", false ) and turn it back on with the trigger that catches you drinking the potion. The latter option is what I tend to do, but I go crazy and solve things by turning triggers on and off like strobe lights.
I don't like having too much triggers active too, it slows you down and makes you vulnerable to illusions. Disabling the prompt trigger where I have set this function is a bad idea, because when my system will be finished I will have to check for about 10 types of balances and other afflictions, and turning it off and on isn't going to work. | Top |
|
Posted by
| Nick Gammon
Australia (23,133 posts) Bio
Forum Administrator |
Date
| Reply #14 on Fri 10 Aug 2007 09:21 PM (UTC) Amended on Fri 10 Aug 2007 11:04 PM (UTC) by Nick Gammon
|
Message
|
Quote:
Edit: it keeps spelling italic, I don't know why.
You are using [i] which means "make the text italic" to the forum. If you are posting text with square brackets, or backslashes in it, you should "escape" them by putting a backslash in front of them, like this: \[i\]
There is a function in MUSHclient to do that for you, which I always use when posting code here. This is what I do:
- Copy the code I want to paste (Ctrl+C)
- Select Edit menu -> Convert Clipboard Forum Codes (Shift+Ctrl+Alt+Q) - a small dialog box pops up showing how many were converted
- Switch to the forum and paste (Ctrl+V)
This reliably fixes this problem with only a small amount of effort.
I am fixing up your current posts for you. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | 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.
43,466 views.
This is page 1, subject is 2 pages long: 1 2
It is now over 60 days since the last post. This thread is closed.
Refresh page
top