IPTSCRAE SCRIPTING LESSON SIX
Stringing Her Along
Because the Palace system is primarily a "chat" environment, the manipulation of what is said on the screen and thus used in your code is of utmost importance. All of the text you see on the screen is manipulated as strings. Within your code, string literals must be encased in double quotes, for Example: "string". If you need to include a quote symbol within a string, precede it with a backslash: "these \"doublequotes\" are okay". In your scripts, the maximum length of a simple string is 256 characters. You can get around this limitation, however, by concatenating multiple strings together using the & operator:

"This part of the string" " plus that part of the string" & "make a whole sentence." & SAY

If you recall, in a previous lesson, you can also use the + operator to accomplish the same results. The maximum length of a compound string is 4096 characters.

The following two functions will manipulate the letters in the top piece of data on the stack. MAKE SURE that you are applying these to strings!

"< string >" LOWERCASE
This function takes the top piece of data from the stack, converts it to all lowercase letters and put it back on the stack.

"< string >" UPPERCASE
This function takes the top piece of data from the stack, converts it to all uppercase letters and puts it back on the stack.

When you are using a simple comparison like: CHATSTR "words" == IF, upper and lower case don't matter. The comparison is case INsensitive. However, for other comparisons it is important. For example:

"< string >" "< stringPattern >"SUBSTR
This function searches string for stringPattern and returns 1 if it is found; otherwise, it returns a 0. This command is not case sensitive! Therefore, it will find "MyName" in the string "thisismyname".

So, if everything you see on the screen were text strings, how would you ever do mathematical computations with it? Or, conversely, how would you convert your userID, for example, into a string you can then SAY? These two functions take care of that:

< number > ITOA
This function ("Integer TO ASCII") takes a numeric variable from the top of the stack, converts it to a character string, and places it back on the stack. Numerals must be converted to character strings before you can use text-based commands (such as SAY) on them. You've already used this in class.

"< string >" ATOI
This function ("Ascii TO Integer") converts a character string to a number. Strings - even numerals spoken as text strings - must be converted to integers before you can do math with them.

Gripes and GREPSTR
Basically all of your routines so far have used the format:

} CHATSTR "whatever" == IF

Now, here are some key commands that let you respond much more intelligently to what is said:

"< string >" "< pattern >" GREPSTR
This function performs a case-sensitive search for the specified pattern within the specified string, and returns TRUE (1) if the pattern is found. It may be placed in the INCHAT or OUTCHAT handler to operate directly on CHATSTR. The rules for pattern matching are that any character matches itself, unless it is one of the following special control characters:

.
(This character is a "period".) This matches any single character except a newline (end of line character). This means that it matches spaces, too!

[0-9] [a-z]
The brackets indicate a set. In the first case, ANY number between 0 and 9 will match. In the second case ANY LOWERCASE letter between a and z will match.

*
Any pattern, followed by * matches zero or more instances of the pattern.

+
Any pattern, followed by + matches one or more instances of the pattern.

^
This symbol anchors the pattern match to the beginning of a line or string. For example: "^Hello", indicates that the word "Hello" must be at the BEGINNING of the string. In addition, this symbol is also used in sets. For example: [^0-9] would match anything EXCEPT the numbers 0 through 9.

$
This symbol anchors the pattern match to the end of the line or string. For example: "later$" means that the word "later" must be the last characters for the pattern to match.

( )
The parenthesis are used to tag sections of the pattern for later use with GREPSUB, a sub-text substitution command.

\
This means "match the character following me". You can use it in front of the other control characters to turn them into literals, rather than controls.

The most common usage of the GREPSTR function is:

} CHATSTR "-pattern-" GREPSTR IF

It returns one (true) if the data string matches the pattern, and zero (false) if it does not. Here is a sample pattern, as found in your default cyborg:

} CHATSTR "^give (.*) (.*)$" GREPSTR IF

The words "give", and the spaces, are taken literally. It would mean as follows:

1. ^ This piece must start at the beginning of the data. So the first characters in the CHATSTR must be g-i-v-e for this to match.
2. The word "give" must be followed by a space.
3. ".*" is a "catchall". It means any characters (spaces, punctuation, letters, numbers, even those weird characters you see in people's names!) repeated any number of times. By surrounding this with the parenthesis, you are saying "Save this for later use!"
4. This must be followed by another space.
5. Then another set of any characters must be in the CHATSTR, and, again, by placing the parenthesis around you, you are saving it to use later.
6. The $ indicates that the pattern must be the end of the string, with nothing "left over"

So if CHATSTR was:

"give beer Mark" it would match
"give mark beer" would match
"give beer" would NOT match. There is only one set of characters after the word "give"

Another very common format that is used with the GREPSTR function is:

"^command-name (.*)$" GREPSTR

That is the format used by any command that lets you specify one piece of data after the command name. For instance, msay lets you say the word msay, followed by what you want to say. A routine to drop a prop that is specified by name would use this. In the give routine above, it uses two pieces of data separated by a space (it can get confused, though, when those pieces of data have a space in them. A space is a space, and it can't read your mind!) - the two pieces being a person's name and a prop name.

Remember GREPSTR is very definitely case sensitive. Sometime, people try to overcome that by using a set, such as [Rr], so that either a capital or a lower case letter is accepted. It might be easier to change the string, using the LOWERCASE command, depending on the situation.

SUBstitution Please!
To use those pieces of your string that you saved using the parenthesis, you use the following function:

"<replacementPattern>" GREPSUB
This function is executed in conjunction with a GREPSTR command. It locates specified sections within a string, and fills them with any text that was "captured" by placing the parenthesis around them when you used GREPSTR. The replacement pattern uses the special Symbols $1 through $9 to refer to these captured character strings.

In other words, whatever was captured between the ( ) in the pattern is stored in memory under a number from 1 to 9. It is stored sequentially, the first () in the pattern being 1, the second 2, etc.... You can retrieve that data with GREPSUB by saying:

"$1" GREPSUB

You can also mix and match by specifying something other than just the data in the pattern string:

"$2 was said before $1" GREPSUB SAY

That command would take the data in the second ( ) from the last GREPSTR, put it in the beginning, put the data in the first ( ) at the end, and would then say that whole string.

If all this seems a bit complicated, don't worry too much. I started by simply altering existing forms just a bit, and learning from there. (In fact, I'm sure there are many subtleties I don't know).

HOMEWORK:
1. Make a routine that is triggered only when a wizard with a badge on says "jump". If that happens, you say "how high?"

2. When anyone besides you mentions your name in conversation, a routine will make you say "I heard that!"

3. Make a routine which will put four copies of a specified prop around a person- one above, one below, one to the left, and one to the right- when you whisper "wreath -propname-" to them.

4. Using variables, make a routine that will put an X of props through your position when you say "-propname- marks me!"

CHALLENGE:
Write a routine that will count the number of characters in a user's name.

NOTES:
Another method for including special characters within strings is by using \x<hexValue>. For example, to include doublequotes within a string:

"These \x22doublequotes\x22 are OK."

hexValue means the hexadecimal value for the character. This system works for other characters as well, but may produce unwanted results when displayed inside a chat bubble.

<Previous> <Iptscrae> <Next>