Register to post in forums, or Log in to your existing account
 

Play RetroMUD
Post new topic  Reply to topic     Home » Forums » CMUD General Discussion
grunthork
Novice


Joined: 22 Jun 2009
Posts: 38

PostPosted: Fri Dec 18, 2009 6:18 am   

Capture 'group' command stats to variables - one for each person and stat
 
I want to capture each stat (hp/mana/mv) as well as class/lvl and char name for each person in my group. Group size can vary, and changes. I want to put this information into a status window, so i'm fairly sure I need stats to be stored into variables. So i'll get to what the mud looks like first:

Code:

< 1392(1392) 1583(1583) 323(323) > group
Your group consists of:
----front-----
[50 Av][1819(2017)h  331( 331)m  212( 300)v]*NAME1 (Leader) 
[50 Dr][1392(1392)h 1583(1583)m  323( 323)v]*NAME2 


The prompt is fairly easy to spot, as well as the stats for group members. I also typed 'group' after the prompt to get the resulting group list. I am one of the group members listed, which isn't ideal, but I can worry about that later. Also, members of the group can be in each of three rows, provided there is at least one person in the row in front of them. The three rows are front/middle/last. There are no blank lines between rows, but each row is declared in the same way as "----front-----" is. This command is always ended with a blank line.
My problem is the logic. Forgetting about the rows, I know I can capture the enire first row into variables using a fairly simple trigger. My question really has to do with looping this trigger to fire until it has run out of members, and storing those member names, classes, and stats into variables. How do I accomplish this? I would like to have a status window that looks fairly similar to this group command, but possibly formatted with percentages instead of hitpoints, or formatted differently, like taking out the data in the first set of brackets, which state the character's level and class. Basically, I'd like to be able to manipulate these variables, and show them wherever I want in my window. My only thoughts were to do a member list using a string variable, but i dont know how i can tie the hp/mana/mv points to the correct name of the member, or how to extract each member in the string variable to a list of people in my 'group status' window. Help is most appreciated. I prefer to learn this if i can, so references to MUD commands and other scripting functions would be more helpful than simply writing the script for me. I certainly will post my script, if i can ever get it to work! P.S. I currently have NO code for this script, as i'm still in the planning process. I honestly haven't tried anything, because I'm not really sure what I can try. I've looked through many of the scripting commands and functions, but none have examples on capturing multiple variables from multiple lines. Thank you in advance, to anyone who takes time to help.

Gman
Reply with quote
MattLofton
GURU


Joined: 23 Dec 2000
Posts: 4834
Location: USA

PostPosted: Fri Dec 18, 2009 7:57 am   
 
How to capture a variable number of lines with a multistate trigger
A somewhat simple trick is to use a 2-state trigger. State 0 will be something that always appears, and state 1 will be something like so:

Code:

#trigger "[b]name[/b]" {[b]pattern for a fixed line goes here[/b]} {[b]necessary prepwork goes here, very likely that you won't have anything to put here[/b]}
#condition {(*)} {
  #if (%1 = "") {
    #state [b]name, see above[/b] 0
  } {
    [b]everything to process the varying number of lines[/b]
  }
} {manual}


As for the logic, you have three possible lines to take care of:

1)----front-----
2)[50 Av][1819(2017)h 331( 331)m 212( 300)v]*NAME1 (Leader)
3)stuff you send to the screen via #SAY, #SHOW, #ECHO, and so forth (this can be triggered on, so you might want to have a #PRINT case that visibly shows you something else matched the line)

#3 you don't really need, but I've found it handier to have my scripts visibly remind me that they came across something unexpected and that I need to fix whatever is causing that to happen. Most times, it's going to either break my script and it'll hang or it won't break but will end up drawing out bad data to work on.

Given the inclusion of #3, I recommend the use of the #SWITCH command, using %match() in the condition to test the line for a match and populate variables to be evaluated. #Local variables make this a very easy and self-contained process, so you won't have to scatter unused variables all over. For help with building your pattern strings (for either a trigger or as part of %match()), check out the Pattern Matching help.

Storing and displaying your data
1)variables

I would probably store the data like so:

Group
.front = "list|of|names"
.middle = "list|of|names"
.back = "list|of|names"

Keep in mind that datarecord variables are stored in a hash table, so even though you can assign a stringlist to any field of one you can't directly access it with commands/functions that act upon stringlists. To do so, you need to assign the field value to a non-datarecord variable (#LOCAL variables make this quite easy.)

groupmember name
.curhp = %1..%99
.maxhp = %1..%99
.leader = 1 or 0

This allows me to easily reference any piece of any person's data without having to do something obnoxiously long and difficult.

2)window

I would use a regular window for this, as you can bring to bear a more powerful array of features. You will have to use an #ALIAS or #RAISE an #EVENT or something that takes care of the window updating, though, because normal windows don't self-update like the statusbar window or a button caption will.

If your head doesn't explode from this, if you're still having trouble I or someone else will do some more specific exampling.
_________________
EDIT: I didn't like my old signature
Reply with quote
grunthork
Novice


Joined: 22 Jun 2009
Posts: 38

PostPosted: Fri Dec 18, 2009 2:53 pm   Wow - 8AM
 
While I do appreciate the ultra quick response, I wish you had responded more towards the end of the day. :)
Now I have to work for 8 hours before going home to work on it. What you're saying makes sense, so i'll give it a try tonight. Hopefully i'll have something to show for my work sometime this weekend. Again, thanks for the reply, and I'll let you know if I have more difficulties.

Gman
Reply with quote
grunthork
Novice


Joined: 22 Jun 2009
Posts: 38

PostPosted: Sat Dec 19, 2009 3:12 am   Focusing on Capturing into Variables
 
I do think the multistate trigger is the way to go. However, I don't understand how to capture all the stats for multiple people. If i capture the first line of the 'group' command into variables, how do i capture the second line of the group command (which is the second person) into a different set of variables. It seems that if i use a loop to capture each line, that those captures will be put into the same variables, and will overwrite the variables for the first group member. This is the part I can't understand in your code. How does the multistate capture each line of stats into different variables? If i capture
Code:

[50 Av][1819(2017)h  331( 331)m  212( 300)v]*NAME1

Into a set of variables, and then capture the next line, how do i get that next line into another set of variables? Once I've figured that out, how do I control the trigger when there are varying numbers of group members?
I feel like i'm closer, but i still don't fully get it. This is the 'logic' that I refer to in my first post, the 'logic' that i just can't wrap my head around.
Reply with quote
MattLofton
GURU


Joined: 23 Dec 2000
Posts: 4834
Location: USA

PostPosted: Sat Dec 19, 2009 6:03 am   
 
You don't have to worry about controlling the trigger. That happens automatically because of the #IF command in the #CONDITION. The #IF says, basically, that if the line is a blank line then we're done; if it's not a blank line, we need to check it out. The checking-out part is where you determine which non-blank line you are dealing with.

As to that, first order of business is the #SWITCH.

Code:

#SWITCH (%pos("front",%1)) {position = "front"}
  (%match(%1,[b]pattern[/b],[b]variables[/b])) {
    //update group list
    $list = %db(@Group,@position)
    #additem $list $name
    #addkey Group @position $list
    #addkey %expand($name) level $level
    ...
    #addkey %expand($name) maxmv $maxmv
  }


pattern (including the double quotes) = "[(%d) (%w)][(*)~((*)~)h%s(%d)~((*)~)m%s(%d)~((*)~)v](*)"
variables (including commas) = $level,$class,$curhp,$maxhp,$curmn,$maxmn,$curmv,$maxmv,$name

The %expand() allows you to refer to the correct person's variable, so there's no overwriting.

In addition to the above, you will want to have triggers or whatever that remove people from your group list. Without such, your list will keep getting bigger.
_________________
EDIT: I didn't like my old signature
Reply with quote
grunthork
Novice


Joined: 22 Jun 2009
Posts: 38

PostPosted: Sat Dec 19, 2009 8:10 am   Just a quick note
 
Thanks. that last explanation really helps tie it together. I have a couple of quick questions. In your first post in the 'code' tag, what is the last line for? it just says 'manual' and I'm not sure what that is. I'm still reading through each function to see what your script is actually doing, so i won't post anything else until tomorrow. Rest assured i'm working on it. Again, thanks for the clarification. It really helped a lot. Hopefully I'll have a post here tomorrow.

Gman
Reply with quote
MattLofton
GURU


Joined: 23 Dec 2000
Posts: 4834
Location: USA

PostPosted: Sat Dec 19, 2009 6:37 pm   
 
That line is part of the #CONDITION syntax. The beginning } closes up the code-to-execute part, and the {manual} contains all the trigger option settings for that trigger state. "manual" specifically defines the type of state and means that the user must change the trigger state themselves (ie, use the #STATE command), but you will see other option keywords as well:

param=# -- # represents a number. Some state types require parameters, such as how long to wait or how many lines to handle.
nocr -- this means that the Trigger on Newline option is unchecked, so this trigger won't fire when a carriage return is received.
prompt -- this means that the Trigger on Prompt option is checked, meaning that the trigger will fire as soon as a match is made.

More details can be found, I believe, in the Trigger Options helpfile (if that doesn't have the state-type descriptions, the correct helpfile is linked to in the syntax of the #CONDITION helpfile).
_________________
EDIT: I didn't like my old signature
Reply with quote
grunthork
Novice


Joined: 22 Jun 2009
Posts: 38

PostPosted: Sat Dec 19, 2009 7:43 pm   Not there yet.
 
Ok this is what I have so far.
Code:

#IF (%1= " ") {
#STATE groupcapture 0} {#SWITCH (%pos("front" ,%1)) {position = "front"} (%match(%1, "[(%d) (%w)][(*)~((*)~)h%s(%d)~((*)~)m%s(%d)~((*)~)v](*)", $level,$class,$curhp,$maxhp,$curmn,$maxmn,$curmv,$maxmv,$name)) { $list= %db(@group,@position)}
#additem $list $name
#addkey Group @position $list
#ADDKEY %expand($name) level $level
#ADDKEY %expand($name) class $class
#ADDKEY %expand($name) curhp $curhp
#ADDKEY %expand($name) maxhp $maxhp
#ADDKEY %expand($name) curmn $curmn
#ADDKEY %expand($name) maxmn $maxmn
#ADDKEY %expand($name) curmv $curmv
#ADDKEY %expand($name) maxmv $maxmv
#} {manual}


I know have a compiler error, stating command expected. I don't understand the #ADDkey %expand statements. Is this supposed to store the real values into a db variable? It seems that is where the compiler error is. I did switch it up a little, got rid of the compiler error, but what it was storing in my group variable were values like $level and $class, instead of the actual values. Please help. I'm obviously in a little over my head here, but I really appreciate the help.
Reply with quote
MattLofton
GURU


Joined: 23 Dec 2000
Posts: 4834
Location: USA

PostPosted: Sat Dec 19, 2009 9:59 pm   
 
Quote:

I know have a compiler error, stating command expected.


If it's not obvious, it's the lonely # at the bottom.

Quote:

I don't understand the #ADDkey %expand statements. Is this supposed to store the real values into a db variable? It seems that is where the compiler error is.


First, a minor tangent, since I didn't include it before. With someone having the (Leader) tag, you will want to test for and extract this before you add data to your variables:

#if (%pos("(Leader)",$name)) {$leader = yes;$name = %remove(" (Leader)",%1)}

Second, this wouldn't generate a command expected error because the command is already present (#ADDKEY). At any rate, the %expand($name) represents the name of the datarecord variable we want to add data to, in other words we want the contents of the $name variable. If we just used $name, the #ADDKEY would simply use "$name" as the variable to add the field to, because $name is a valid variable name.

Quote:

what it was storing in my group variable were values like $level and $class, instead of the actual values.


Maybe it means $level and $class aren't defined? I wasn't entirely sure I could use %match() like that within the confines of a condition block (you can leave off the variables to do a simple check with the pattern), so you may need to take the variables out and do a #CALL %match() on the same pattern so you can populate the variables.
_________________
EDIT: I didn't like my old signature
Reply with quote
grunthork
Novice


Joined: 22 Jun 2009
Posts: 38

PostPosted: Sun Dec 20, 2009 12:04 am   
 
Ok, I didn't see the lonley # at the bottom, but i've removed it, and now the compiler is happy. When i use this and type 'group' a variable @Group is populated with things like $curmv and curmv, and not actual data. Is that supposed to happen? I was thinking that when they were put in the variable Group, they would be expanded, and then i'd be able to see real data.
Reply with quote
MattLofton
GURU


Joined: 23 Dec 2000
Posts: 4834
Location: USA

PostPosted: Sun Dec 20, 2009 5:07 am   
 
Quote:

When i use this and type 'group' a variable @Group is populated with things like $curmv and curmv, and not actual data.


I'm starting to think there are some old bugs that were active in the 2.37 public version that have since been fixed in the current beta cycle (I use the beta)...

Anywho, if you're looking at a datarecord variable in the Package Editor there should be a table with two columns in the Value box. The lefthand column is for the key fields, which should properly be the second argument in the #ADDKEY command (ie, "curmv"). The righthand column should be the data you want to reference, which is properly what appears as the third argument in the #ADDKEY (ie, $curmv). If $curmv is what is showing in this column, that's not right and possibly might be the above issue (ie, fixed in the beta version but not fixed in the public version). You can probably get around this with another %expand() function but you really shouldn't need it there.

What you're seeing in @Group is DEFINITELY not part of what I wrote, so assuming your code is like what I gave you then it's time to start debugging stuff. An easy way to do this is to use #PRINT at different parts of the code, to see what's happening in the %match() and to the variables it should be creating.
_________________
EDIT: I didn't like my old signature
Reply with quote
grunthork
Novice


Joined: 22 Jun 2009
Posts: 38

PostPosted: Sun Dec 20, 2009 8:03 pm   debug is probably a good idea
 
Ok so i've inserted a #print $level command in the script, right above all of the #ADDKEY stuff. When I use the group command, instead of printing something out, it prints a blank line. I also went to my variables list, and noticed that the variable $name is being created several times for each time i run the "group" command to the mud. Each one of these $name variables are called $name, and they each have a different key and value in them. The first one had 'level' as it's key, and the value was '--][ 41( 41)h 101( 131)m 50( 50)v] rottweiler' and then the next $name variable contained 'class' as the key and no value for it. The rest of the $name variables have the rest of the keys, like curmn and the like, all without dollar signs, and these are not local variables. They're being displayed in the cmud variables list. I'm not sure if this trigger is capturing correctly. Should i start over? Thanks for spending time on this. I'm very lost and I'd like to get this working someday.
Reply with quote
grunthork
Novice


Joined: 22 Jun 2009
Posts: 38

PostPosted: Sun Dec 20, 2009 8:21 pm   
 
It looks like %expand($name) isn't working correctly. My understanding is that is supposed to expand the $name variable. When I used #print %expand($name) it just prints out '$name' so there's certainly something wrong. When I do #print $name, cmud prints out a blank line. I also added
#print $name
#print @position
#print $list

and cmud printed out two blank lines, and then a line like this:
**

That was all printed BEFORE the first line that actually matches the pattern, the line that has the stats for the first person listed in the group.
Reply with quote
Display posts from previous:   
Post new topic   Reply to topic     Home » Forums » CMUD General Discussion All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

© 2009 Zugg Software. Hosted by Wolfpaw.net