Magsbot Class, Session 5
Saturday March 25, 2006 6pm VRT

[Jarvis]:    hello   keshi sent me  here  as she is  slightly  detained
Magine:    ok, jarvis :)
Draco.:    ohh.. detention, eh?
Magine:    looks like people are generally detained or late this week
Draco.:    hi Magine
Magine:    hi draco
Magine:    brb...we can wait a few minutes, see if anyone else shows
Draco.:    had something quite interesting happen this morning....
Draco.:    ok..
Magine:    oh, what's that?
Draco.:    had problems with GM.. opened avatar tracking window and it showed 3 of itself there
Draco.:    never seen anything like it
Magine:    hmm, what version of magsbot?
Draco.:    fairly recent...
Draco.:    looking...
Draco.:    6.8.10
Draco.:    was only one instance running
Magine:    that was my next question: did you have other bots running too?
Draco.:    yes... we usually have 7 mags running
Draco.:    well, 8.. Keshi runs chatbot
Magine:    i mean other instances in the same mags as the gm
Draco.:    noooo
Magine:    ok
Magine:    by tracking window you mean the nearby list (ctrl-N), not the avtracking window (ctrl-k)?
Draco.:    I know is tough when you cant see it with your own eyes and look at stuff
Magine:    yeah
Draco.:    was ctl-k one
Magine:    oh ok...hmmmm
Magine:    did they show different locations?
Draco.:    ohhhhh... is another one there now
Draco.:    and 3 of another bot
Magine:    yipe
Magine:    well, i'd recommend getting a more recent mags...
Draco.:    ok... thought it was, but i will
Magine:    i was having some problems recently when i changed the disconnect recovery method
Magine:    6.8.24 is the most current, i just UL'ed today
Draco.:    oh yes,... that has been interesting
Magine:    i still need to revise the "what's new"
Draco.:    ok, cool
Magine:    hi pelican
Draco.:    is amazing how far you have come... can run months withut problems
PeLican:    helo
PeLican:    how r u?
Magine:    pretty good
Keshi:    hi i am here but may have to  leave for a  bit during  class
[Jarvis]:    hi Keshi
Magine:    hey keshi :)
Immigration Officer:    You are being joined by RedWolf.
Keshi:    RedWolf said he was coming
Magine:    yep i just got his join req
RedWolf:    here i am
Draco.:    where is Chanes?
Magine:    hi redwolf
Keshi:    His  son had a birthday party  to go to he  had to take him
Keshi:    hello  Pelican
PeLican:    hey keshi
Magine:    well i guess we can start....
PeLican:    k
Magine:    any  questions left over from last time?
RedWolf:    nope
PeLican:    no
RedWolf:    i havnt tried it yet but i will read the log from last week
Keshi:    no  i need to work with  clean glasses on and watch out for those  ;
RedWolf:    will do today
Magine:    redwolf, sorry i didn't get around to helping you with the clock sign, you didn't email to remind me :)
RedWolf:    sorry i was preoccupied with building in my world
Magine:    since we were going to talk about the behavior table today, maybe that would be a good project to do here today
Magine:    i thought of a simpler way to do it too
RedWolf:    goodie
RedWolf:    *jumps with joy*
Draco.:    you mean flaps
RedWolf:    oh yea im a bird lol
Magine:    first though, let's go thru some basics regarding the behavior table (i'll call it BT so i don't have to type "behavior table" 100 times today :D )
Keshi:    :)
Magine:    i assume you have all taken a look at the BT before? alt-B to call it up
Draco.:    Ive seen it
PeLican:    yeah
RedWolf:    yep i got it up
Magine:    there are 3 columns, Acitve, Event and Action
Magine:    the Active column merely turns a row on or off
Magine:    you double click it to toggle On/Off
Magine:    in the Event column you specify the event that you want the bot to respond to,
Magine:    and also a conditional expression that determines if the bot will respond or not
Draco.:    may I ask something about it?
Magine:    a conditonal expression, to recap a bit, is just a mathematical expression (like 2+2) that is evaluated to 0 (false) or non-0 (true)
Magine:    sure
Draco.:    when you start mags....
Draco.:    how long before all functions are available for startup trigger
Draco.:    or event
Magine:    well the STARTUP event doesn't occur until all the functions are loaded, so...immediately, as far as the BT is concerned
Magine:    are you having trouble with that?
Draco.:    hmmm...
Draco.:    yes
Draco.:    can give a specific example
Draco.:    when I start, I create a Vlist with current time for all avatars in world
Magine:    for everyone else: the STARTUP event is an event generated by Magsbot itself (as opposed to most events, that are generated by the AW world server)
Draco.:    or try.. it fails
Magine:    where do you get the current time from?
Draco.:    if I run the same script a few moments later, it works fine :)
Magine:    well, let me get back to basics for a moment here, for everyone else...
Draco.:    kk
Magine:    as i was saying, the Event column has the event name, and a conditional expression
Magine:    most events are messages sent to the bot by the world server
Magine:    for example when you type some chat into your AWB,
Magine:    your AWB sends a message to the world server with the chat string,
Magine:    and the world server then sends the chat string out to everyone who is near you in the world,
Magine:    in Magsbot, that chat message is a HEAR event
Magine:    let's add a row at the top of the BT to do some examples
PeLican:    k
Magine:    move the BT cursor (the faint outline around one cell of the table) to the top and press Alt-I (that's I as in Insert) to insert a row
Magine:    that wll create a new row there with Event=UNDEFINED and a blank Action column
Magine:    to edit the Event or Action column, either double-click them, or move the cursor to the cell and hit Enter
Magine:    that brings up the edit window...let's delete the "UNDEFINED" and replace it with HEAR
Magine:    BTW, you will note all the buttons at the bottom of the edit window: Insert Event, Insert Condition, AND, OR, Insert Function, Insert Attribute
Magine:    those give you convenient lists of events, functions, attributes etc
PeLican:    cool
Magine:    instead of typing HEAR, we could have selected it from a list of events by clicking Insert Event
Keshi:    Is ther a way to keep the  bot  window on top ?
Magine:    you can keep the main Magsbot window on top, Windows menu, Stay On Top
Magine:    that doesn't effect the BT though...sorry
Magine:    i guess i should put that on my to-do list
Keshi:    thansk   no but i need to see what you say  wheni edit
Magine:    just have to resize some windows
Draco.:    resize BT window smaller :p
Magine:    for this class i keep the AWB down to one-quarter of my screen
Magine:    you can also resize the columns of the BT by dragging on the line separating the column names at the top
Magine:    if you see what i mean
Magine:    so have you all entered HEAR in the Event column?
PeLican:    yep
RedWolf:    yep
Keshi:    yes
Magine:    ok, we will look at the Event column again in a moment, but let's first look at the Action column
Magine:    let's edit the Action column and put something in there
Magine:    let's put
Magine:    SAY $fmt["%s said <%s>",$avname,$chat]
Magine:    does everyone understand the $fmt function, btw?
PeLican:    i do
Draco.:    yes
Keshi:    maybe
Magine:    SAY $fmt["%s said <%s>",$avname,$chat]  is the same thing as SAY $avname+" said: <"+$chat+">"
Magine:    the $fmt ("format") function takes a format string, like "%s said <%s>" in this case
Keshi:    ok
Magine:    and where ever there is a %s, it replaces that with the value listed, in order, in this case $avname and $chat
Draco.:    is it better to use $fmt_ when not using the other stuff?
Magine:    yes, actually
Draco.:    okies
Magine:    the $fmt function also replaces some special character sequences like /r with something else, like /r is replaced by a return character
Magine:    but that got to be annoying, so i added the $fmt_ function (with an underscore) that does the same thing as $fmt except it ignores the /r etc
Magine:    i should have just changed the way $fmt worked, but i wanted to keep old scripts compatible (not that there were many scripts yet at that time)
Keshi:    um now what are we to put in there one more time
Magine:    in the Event column put HEAR and in the Action column put SAY $fmt["%s said <%s>",$avname,$chat]
Keshi:    ok   got it
Magine:    technical note here, in case anyone cares :D the $fmt function is like the sprintf function in C, except in C you have a collection of different specifiers for different kinds of variables, like %d, %s, %f etc.
Magine:    in magsbot it's always just %s because technically all the variables are variant types
Magine:    and if you don't understand what i just said, then you don't need to worry about it :D
PeLican:    hehe
Keshi:    and  cause i did i worry
PeLican:    wow. Im gonna rename my bot "Keshi"
Magine:    so anyway...getting back to the action we just added: you ought to be able to figure out what that is going to do, once we turn the Active column On
RedWolf:    LOL
Magine:    what do you alll think will happen?
PeLican:    it will tel us what we said
Draco.:    what it hears
Magine:    yes, the bot will echo whatever it hears
RedWolf:    cool
Keshi:    : )
[Jarvis]:    Keshi said <: )>
Magine:    another "btw":   $avname is a macro for $atr[avatar_name] and $chat is a macro for $atr[chat_message]
[Jarvis]:    Magine said <another "btw":   $avname is a macro for $atr[avatar_name] and $chat is a macro for $atr[chat_message]>
Magine:    heheh
[Jarvis]:    Magine said <heheh>
PeLican:    ok
[Opie]:    PeLican said <ok>
[Mags]:    PeLican said <ok>
RedWolf:    lol
[Jarvis]:    PeLican said <ok>
[Jarvis]:    [Opie] said <PeLican said <ok>>
[Jarvis]:    [Mags] said <PeLican said <ok>>
[Opie]:    [Mags] said <PeLican said <ok>>
[Mags]:    [Opie] said <PeLican said <ok>>
[Opie]:    RedWolf said <lol>
[Opie]:    [Jarvis] said <PeLican said <ok>>
[Opie]:    [Jarvis] said <[Opie] said <PeLican said <ok>>>
[Opie]:    [Jarvis] said <[Mags] said <PeLican said <ok>>>
[Mags]:    RedWolf said <lol>
[Jarvis]:    RedWolf said <lol>
[Mags]:    [Jarvis] said <PeLican said <ok>>
[Jarvis]:    [Opie] said <[Mags] said <PeLican said <ok>>>
[Jarvis]:    [Mags] said <[Opie] said <PeLican said <ok>>>
[Jarvis]:    [Opie] said <RedWolf said <lol>>
[Jarvis]:    [Opie] said <[Jarvis] said <PeLican said <ok>>>
[Opie]:    [Mags] said <[Opie] said <PeLican said <ok>>>
[Opie]:    [Mags] said <RedWolf said <lol>>
[Jarvis]:    [Opie] said <[Jarvis] said <[Opie] said <PeLican said <ok>>>>
[Jarvis]:    [Opie] said <[Jarvis] said <[Mags] said <PeLican said <ok>>>>
[Opie]:    [Jarvis] said <RedWolf said <lol>>
[Opie]:    [Mags] said <[Jarvis] said <PeLican said <ok>>>
[Opie]:    [Jarvis] said <[Opie] said <[Mags] said <PeLican said <ok>>>>
[Mags]:    [Jarvis] said <[Opie] said <PeLican said <ok>>>
[Opie]:    [Jarvis] said <[Mags] said <[Opie] said <PeLican said <ok>>>>
[Mags]:    [Jarvis] said <[Mags] said <PeLican said <ok>>>
[Jarvis]:    [Mags] said <RedWolf said <lol>>
[Mags]:    [Opie] said <[Mags] said <PeLican said <ok>>>
[Jarvis]:    [Mags] said <[Jarvis] said <PeLican said <ok>>>
[Mags]:    [Opie] said <RedWolf said <lol>>
[Jarvis]:    [Opie] said <[Mags] said <[Opie] said <PeLican said <ok>>>>
[Jarvis]:    [Opie] said <[Mags] said <RedWolf said <lol>>>
[Opie]:    [Jarvis] said <[Opie] said <RedWolf said <lol>>>
[Mags]:    [Opie] said <[Jarvis] said <PeLican said <ok>>>
[Opie]:    [Jarvis] said <[Opie] said <[Jarvis] said <PeLican said <ok>>>>
[Opie]:    [Jarvis] said <[Opie] said <[Jarvis] said <[Opie] said <PeLican said <ok>>>>>
[Opie]:    [Jarvis] said <[Opie] said <[Jarvis] said <[Mags] said <PeLican said <ok>>>>>

You get the idea. :) Massive spam ensued as the bots echoed each other and echoed their echoes ad naseum. I snipped out the rest from the log here.

Magine:    TURN OFF THE ACTIVE COLUMN!

The spam dies down...

Draco.:    lol

RedWolf:    whoaaaaa
[Jarvis]:    Draco. said <lol>
[Jarvis]:    RedWolf said <whoaaaaa>
PeLican:    *head spinning
[Jarvis]:    PeLican said <*head spinning>
Magine:    lol, all the bots echoed each other as well
Magine:    in an infinite loop
RedWolf:    hmmm why my bot not repeating?
Keshi:    eek
Draco.:    thank god
Draco.:    hehe
Magine:    redwolf, did you set the Active column so it said On?
RedWolf:    yea it is on
Magine:    and your bot is in the world here with us?
RedWolf:    yea maddog is here
RedWolf:    maddog come
Magine:    is the behavior table itself on? menu Options, Behavior Table Active
RedWolf:    i did put in HEAR in Event
RedWolf:    then i put in SAY $fmt["%s said <%s>",$avname,$chat] for the action
Magine:    so you have Active=On, Event=HEAR and Action=SAY $fmt["%s said <%s>",$avname,$chat]     ?
Magine:    in a row at the TOP of the BT?
RedWolf:    no
RedWolf:    it went o the bottom of BT
RedWolf:    i dunno why it went to the bottom
Magine:    ok, it should be at the top, otherwise some other row might block it
Magine:    you probably clicked Alt-A (append) instead of Alt-I (insert), or else you had the cursor at the end when you clicked Alt-I
Magine:    but you can just more the row up
RedWolf:    move it?
RedWolf:    ok moved it
[MadDog]:    RedWolf said <ok moved it>
RedWolf:    ahhhh it works
[MadDog]:    RedWolf said <ahhhh it works>
Magine:    yes...move the cursor to the row you want to move, then use ctrl-up arrow or ctrl-down arrow to move it
[MadDog]:    Magine said <yes...move the cursor to the row you want to move, then use ctrl-up arrow or ctrl-down arrow to move it>
Magine:    heheh
[MadDog]:    Magine said <heheh>
RedWolf:    ok let me turn it off lol
[MadDog]:    RedWolf said <ok let me turn it off lol>
Magine:    ok, double-click Active so it says Off
[MadDog]:    Magine said <ok, double-click Active so it says Off>
Magine:    right
RedWolf:    done
Magine:    you can also move rows by dragging on the block to the left of the row
Magine:    or, you can select a row or multiple rows (hold shift down and use arrows to multiple select) and then cut and paste
Magine:    with alt-T to cut and alt-P to paste
Magine:    and alt-D deletes the selected row(s)
Magine:    you can also use alt-F to search for a text string
Magine:    or alt-G to move to a particular row number
Magine:    btw, you can see the number of the currently selected row in a box at the lower right
Magine:    also, alt-S will save the BT while the window is opne
[Sharra]:    Magine said <also, alt-S will save the BT while the window is opne>
Magine:    or F6 will save the BT also
Magine:    but....getting back to our example here.....
Magine:    it looks like we ought to limit what our bots echo
Keshi:    yep
Draco.:    yea.. ignore other bots :p
Magine:    so we can add a conditional expression to the Event column,that will only be "true" (non-0) under the conditions we want the bot to echo chat
[Hervey]:    ..
Magine:    that would be an idea for starters....let's tell it to ignore other bots
Magine:    there is a macro that simply checks an avatar name for brackets, to tell if it's a bot or not
Magine:    and that is @isbot
Magine:    so we could edit the Event column and change HEAR to HEAR @isbot[$avname]=0
Magine:    the expression is @isbot[$avname]=0 therefore
Magine:    oops actually i just made a mistake there
Magine:    this is a common goof too
Magine:    uhhh no nevermind, was thinking of something else :P
Magine:    i'll explain in a moment
[Opie]:    Magine said <i'll explain in a moment>
Magine:    anyway, the expression @isbot[$avname] returns 1 if $avname is a bot or 0 if not
Magine:    so @isbot[$avname]=0 is like saying "the speaker is not a bot"
RedWolf:    well i got to an meeting  i will leave my bot here and read the chat
Magine:    ok,red
PeLican:    bye red
RedWolf:    see ya
Keshi:    bye  Red
Magine:    so after making that change HEAR @isbot[$avname]=0   turn the Active column back on
PeLican:    (quick, go thru his bot's pockets
Magine:    testing
[Opie]:    Magine said <testing>
[Mags]:    Magine said <testing>
[Jarvis]:    Magine said <testing>
PeLican:    ok
[Jarvis]:    PeLican said <ok>
[Mags]:    PeLican said <ok>
[Opie]:    PeLican said <ok>
PeLican:    cool
[Mags]:    PeLican said <cool>
[Opie]:    PeLican said <cool>
[Jarvis]:    PeLican said <cool>
Magine:    a little less chaos :D
[Mags]:    Magine said <a little less chaos :D>
[Opie]:    Magine said <a little less chaos :D>
[Jarvis]:    Magine said <a little less chaos :D>
Keshi:    yes  
[Jarvis]:    Keshi said <yes   >
[Mags]:    Keshi said <yes   >
[Opie]:    Keshi said <yes   >
PeLican:                    .                     
[Opie]:    PeLican said <                .                      >
[Jarvis]:    PeLican said <                .                      >
[Mags]:    PeLican said <                .                      >
PeLican:    interesting
[Mags]:    PeLican said <interesting>
[Opie]:    PeLican said <interesting>
[Jarvis]:    PeLican said <interesting>
Keshi:    lalala  ...
[Jarvis]:    Keshi said <lalala  ...>
[Mags]:    Keshi said <lalala  ...>
[Opie]:    Keshi said <lalala  ...>
[MadDog]:    la la la la
Magine:    for another example, we could make the bot only echo our own chat, by changing the Event column to HEAR @eq[$avname,Magine]  (insert you own name there)
[Jarvis]:    Magine said <for another example, we could make the bot only echo our own chat, by changing the Event column to HEAR @eq[$avname,Magine]  (insert you own name there)>
[Mags]:    Magine said <for another example, we could make the bot only echo our own chat, by changing the Event column to HEAR @eq[$avname,Magine]  (insert you own name there)>
Magine:    test
[Jarvis]:    Magine said <test>
[Mags]:    Magine said <test>
Magine:    with that change, each bot should only echo the person whose name you put in there
[Jarvis]:    Magine said <with that change, each bot should only echo the person whose name you put in there>
[Mags]:    Magine said <with that change, each bot should only echo the person whose name you put in there>
PeLican:    hello
[Jarvis]:    PeLican said <hello>
PeLican:    hmm
[Jarvis]:    PeLican said <hmm>
[Opie]:    PeLican said <hmm>
Magine:    anyway, that's the basic idea....
[Jarvis]:    Magine said <anyway, that's the basic idea....>
[Mags]:    Magine said <anyway, that's the basic idea....>
Magine:    you can do similar things with any event, and any conditions you can think of
[Mags]:    Magine said <you can do similar things with any event, and any conditions you can think of>
Keshi:    hmm
[Jarvis]:    Keshi said <hmm>
[Hervey]:    Hi
Magine:    question?
[MadDog]:    nope
Keshi:    nono  was testing
[Jarvis]:    Keshi said <nono  was testing >
Keshi:    it  works
[Jarvis]:    Keshi said <it  works>
Magine:    oh, the goof i mentioned earlier
Draco.:    how do you know what attributes are availble for an event?
Magine:    right, good point...
Magine:    each event only has certain attributes available
Magine:    an attribute or AW attribute is information that the world server send along with the event message
Magine:    for example, with the HEAR event, you also get the avatar name and session, and the chat string
Magine:    other events have other attributes available
Magine:    you can find out what attributes are available (or valid) for a given event, but checking the sdk help
Magine:    at http://www.activeworlds.com/sdk/
Magine:    find the event on the list of events there, click that, and the documentation tells you what attribs are given with that event
Magine:    the HEAR event in Magsbot is called AW_EVENT_CHAT by the SDK
Magine:    if you look at that SDK page now, and the AW_EVENT_CHAT event, you can see that the AW_CHAT_TYPE is another attrib, telling you if the chat was spoken aloud, whispered or broadcast
Magine:    in magsbot, to get the value of an attribute, you would use the $atr or @atr functions (for string or numeric attribs, respectively)
Magine:    so AW_EVENT_TYPE would be @atr[event_type] in magsbot
Magine:    but also i made macros for some commonly used events, like $atr[chat_message] is the same as $chat
Magine:    or $atr[avatar_name] is the same as $avname
Magine:    or @atr[chat_session] is the same as @chatsession
Magine:    the common goof i mentioned earlier is using @avsession instead of @chatsession for a HEAR event
Draco.:    what is the difference between seesion and chatsession?
Draco.:    yes, hehe
Magine:    for most events, the avatar session is given in @atr[avatar_session] (duh!)
Magine:    but for chat it's @atr[chat_session]
Magine:    gotta be careful about that, or you will have some hair-pulling bugs to figure out
Magine:    in magsbot, @session refers to the session of the bot itself
Magine:    @avsession or @atr[avatar_session] refers to the session of the avatar that generated the event
Magine:    or @chatsession in the case of a HEAR event
Magine:    does all that make sense so far?
PeLican:    yeah
Draco.:    kinda, sticking to avname easier, lol
PeLican:    ive worked with avsessions before
Magine:    to summarize: attributes are data that come with each event, different attributes with each event type
Keshi:    ok
[Jarvis]:    Keshi said <ok >
PeLican:    ok
Magine:    some other handy macros in the .udf file are @whispered, @said and @broadcast
Magine:    you can use them for the condition in a HEAR event to have the bot respond only to certain chat types
Magine:    and there is also the ever-popular @cmd and @cmd_ macros
Magine:    those return true if the chat was a command directed at the bot
Magine:    the @cmd macro returns true if:  the chat was whispered to the bot, or the bot's name was the first word in the chat
PeLican:    ahh
Magine:    the @cmd_ macro does that same, but also returns true if the chat begins with a / slash
PeLican:    aha
Magine:    so let's add a new command for our bots :)
Magine:    first insert a new row at the top of the BT (just for practice, heheh)
Magine:    in the Event column, put
Magine:    HEAR @cmd_[dance]
Magine:    and in the Action column, put
Magine:    GESTUIRE 0; GESTURE 7
Magine:    ...but replace the 7 with the seq that corresponds to the dance seq for the avatar that your bot is using
[Sharra]:    Magine said <...but replace the 7 with the seq that corresponds to the dance seq for the avatar that your bot is using>
Magine:    for my bot's av, the Dance button is the 7th one, so i put gesture 7
PeLican:    Mag...did you mean GESTUIRE? (with an "I")
Magine:    GESTURE..... GESTUIRE is a typo, sorry
PeLican:    ok
Magine:    unless you are using the french edition of magsbot (j/k)
PeLican:    /dance
PeLican:    yep
PeLican:    hehe
Magine:    mags here
Magine:    mags dance
PeLican:    mine doesnt have a dance seq so i could rename the macro to "wave"
Magine:    whatever works
PeLican:    /wave
Magine:    /dance
PeLican:    /wave
PeLican:    maybe not
Magine:    hmmm, but it doesn't seem to be working
(It was, but there was a long delay.)
Draco.:    lol
Magine:    (to [Mags]) dance
Draco.:    she is shaking her head no
Magine:    oh not the right av
PeLican:    /wave
PeLican:    ok, restarted it
Magine:    it's actually seq 5 for the becca av
Magine:    restarted?
Magine:    (to [Mags]) dance
PeLican:    i turned the active column off and back on
PeLican:    then it worked
Magine:    (to [Mags]) /dance
Magine:    (to [Mags]) dance
Magine:    /dance
[Jarvis]:    Keshi said <3/25/2006ance>
Keshi:    /dance
[Jarvis]:    Keshi said <3/25/2006ance>
PeLican:    like it reloaded the changes
PeLican:    the date hehe
Keshi:    hmmm
[Jarvis]:    Keshi said <hmmm>
Magine:    yeah, because /d is replaced by the date, by $fmt

(The $fmt function converted the /d in /dance to the date, resulting in
3/25/2006ance. To avoid that, use $fmt_ instead of $fmt.)

PeLican:    /wave

Magine:    change $fmt to $fmt_ with the underscore
Magine:    /dance
Magine:    hm, for some reason, the slash form of the command isn't working
PeLican:    /wave
Magine:    but just whispering or saying <botname> dance  works
Magine:    mags dance
PeLican:    turn active off and back on
Magine:    /dance
PeLican:    /wave
Magine:    mags dance
Keshi:    /dance
Keshi:    /jarvis  dance
Keshi:    jarvis  dance
PeLican:    jarvis dunce
PeLican:    hehe
Magine:    the purpose the the GESTURE 0, btw, is to reset the bot...because once it does a gesture, it won't go thru that seq again until reset
Guri Lady:    /dance
Magine:    /dance
Keshi:    /dance
Magine:    not sure what the /dance (with a slash) isn't working here
Magine:    hm well it worked that time, when keshi said it
Keshi:    Jarvis come
PeLican:    /happy
Keshi:    jarvis  dance
Magine:    maybe mags just doesn't want to take orders from me in particular :D
Keshi:    nope
Magine:    /dance
Keshi:    /dance
Guri Lady:    hehe
Magine:    i guess there is just a bit of a delay
Guri Lady:    caught up :)
Belle. Thavas:    nicely done all *smiles*
Guri Lady:    Hello everyone :)
Guri Lady:    (( Belle ))
PeLican:    cool
PeLican:    hey GL
Belle. Thavas:    ((Guri Lady))
Guri Lady:    (( Pel ))
Guri Lady:    *hugs all*  hehe  faster but I means it :)
Magine:    now suppose you only wanted the bot to respond to you and no one else, what would you need to do?
Magine:    hi guri :)
PeLican:    define the av session?
Guri Lady:    Hey, Magine :) 
Magine:    you need to change the HEAR conditon somehow
Keshi:    /dance
Magine:    you could put:  HEAR @cmd_[dance]&&@eq[$avname,YourNameHere]
Magine:    or, you could make it so the bot would only respond to someone on the control list:
Magine:    HEAR @cmd_[dance]&&@isctrl[$avname]
Magine:    /dance
Magine:    btw, in magsbot you need to use various functions to compare strings, thus the @eq[$avname,YourNameHere]
Magine:    NOT $avname=YourNameHere
Keshi:    /dance
PeLican:    that way its always a T/F thing?
Magine:    (technically that's because the expression evaluator in magsbot can only deal with numbers)
Guri Lady:    Mine said "too many function parameters"
PeLican:    k
Guri Lady:    is it the space in my name?
Magine:    guri, what did you put exactly?
Guri Lady:    HEAR @cmd_[dance]&&@eq[$avname,YourNameHere]
Magine:    yes !
Guri Lady:    but I put in my name
Draco.:    need quotes
Guri Lady:    HEAR @cmd_[dance]&&@eq[$avname,Guri Lady]
Guri Lady:    ahhh
Magine:    in magsbot, you don't need quotes for strings IF they are all letters ,
PeLican:    she would have to replace her name with a $fmt?
Magine:    but if a string contains a space or special character other than the underscore, you need quotes
Guri Lady:    kk got yas
PeLican:    oh
Magine:    so in you case, guri, you would put HEAR @cmd_[dance]&&@eq[$avname,"guri lady"]
Guri Lady:    Yeppers  thanks :)
PeLican:    case sensitive?
Draco.:    nope
Magine:    @eq is not case sensitve
PeLican:    ok
Keshi:    /dance
Magine:    there are other functions that are
Magine:    @eq is actually a macro
Magine:    it uses the @icmp function, which is a case-insensitve string comparision
PeLican:    ok
Magine:    if you want case-sensitive you could use @cmp instead
PeLican:    gotya
Guri Lady:    /dance
Magine:    @cmp and @icmp compare string alphabetically....0 if equal, -1 is less than, 1 if greater than
Magine:    so @eq[$a,$b] is like @icmp[$a,$b]=0
Magine:    you can look up all these functions in the help, everyone
PeLican:    ok
Guri Lady:    good  hehe
Magine:    and also all of the functions and most of the macros can be found in the list you get when you use the Insert Function button in the edit window
Guri Lady:    /dance
Magine:    is it working for you now, guri?
Draco.:    is fun to find others in UDF :)
Guri Lady:    Yes. :)
Keshi:    /dance
Magine:    yes, there are some macros in the .udf file that you just have to find in there :D
Magine:    and of course, you can define your own
Draco.:    ohh.. you gonna teach us that ? ;))
PeLican:    tapping fingers...
Magine:    pelican?
Keshi:    /dance
PeLican:    waiting for you to teach me that
PeLican:    hehe
Guri Lady:    I hope so hehe
Keshi:    well i had to  reboot aw  but now  Jarvis dances
Magine:    ok, lets look at macros before we finish up today
Guri Lady:    `wb Keshi
PeLican:    k
Keshi:    ty
Magine:    you will find a EditUserDefs button on the . tab, that will open the userdefs.udf file using notepad
Magine:    (more convenient that having to navigate folders to find it....)
PeLican:    true, nice feature
Magine:    macros are just like expressions, but with arguments you can insert into them
Guri Lady:    kewl
Magine:    there's an explanation at http://www.turtleflight.com/mbh/mh_macros.htm that you can look at later
Magine:    basically, you just add them to the userdefs.udf file (at the top....because it's better not to change the Standard Macros section, so you can update it more easiy in the future)
Magine:    a macro might be simple, with no arguments ("arguments" means the parameters that you pass to a function)
Magine:    like $worldname=$atr[world_name]
Magine:    or $avname=$atr[avatar_name]
Magine:    or you can specify arguments, for example for the @eq function, you have 2 strings as the arguments
Magine:    @eq[$,$]=(@icmp[~1,~2]=0)
Magine:    ...is how that is defined
Magine:    the @eq[$,$] part shows that it requires two strings ($ indicates a string argument)
PeLican:    i see
Magine:    and in the macro definition, the ~1 and ~2 are replaced by whatever values you pass to the macro as arguments
Draco.:    :)
Guri Lady:    okay
Magine:    so when you put in your code:   @eq[$a,$b]
Magine:    that gets replaced
Magine:    by (@icmp[$a,$b]=0)
Magine:    some of the macros i defined are very complicated, they even took me some time to figure out....but you don't need to understand the definition to use the macro of course
Magine:    just to give you an example of a moderately complex one, take the $AWB macro
Magine:    that converts SDK coords to an AWB coordinate string
Magine:    $AWB[@,@,@,@]=$fmt["%s%s %s%s %sa %s",@abs[~1/1000],$if[~1<0,"S","N"],@abs[~2/1000],$if[~2<0,"E","W"],(~3/1000),(~4/10)]
Magine:    don't worry if you don't get all that, i just wanted to show you that macros can be as complicated as you like :)
Guri Lady:    *Hopes that question isn't on the test*  hehe
Belle. Thavas:    it looks beautiful *sniffs*
Draco.:    more like elegant
Draco.:    hehe Belle
Magine:    once you change or edit a macro, you need to reload the .udf file
PeLican:    is there  the ability to nest functions in a macro?
Magine:    pelican, yes
PeLican:    ok
Magine:    you can even call buttons from a macro
PeLican:    ah nice
Magine:    so if you define a button that you are going to use in code a lot,
Magine:    you could define a macro like
Magine:        @dosomething[$,@]=@ftn["[DoSomethingButton]",~1,~2]
Magine:    then in your code, instead of having to put
Magine:        @x=@ftn["[DoSomethingButton]","some string",@some_number]
Magine:    you could put
Magine:        @x=@dosomething["some string",@some_number]
PeLican:    i see
PeLican:    and there is @loop to follow that up
Magine:    there is a @loop function, yeah
PeLican:    very nice
Magine:    so you can have a loop within a macro
Magine:    draco, you asked me last time about arrays in magsbot
Draco.:    oh yes!
Magine:    magsbot doesn't have arrays, but you could use vlists to simualte them, and define a macro to make it simpler to use
Magine:    you could create a vlist to simulate an array, and use the array indexes as the variable names
Draco.:    yea.. hehe.. miss good old dimensioned arrays
Magine:    this is what i do with terrain
Magine:    magsbot can only survey one terrain page at a time (big enough for most private worlds)
Magine:    but if the world is really big and has more than one terrain page, magsbot stores the pages in a simuated array
Magine:    actually a vlist with variable names like "1,1", "1,2" etc [each element of the simulated array holds a pointer to the data for one terrain page]
Magine:    so, your homework draco, is to define a macro that would let you reference vlist variables like an array :D
Guri Lady:    yea.. then share hehe
Magine:    heheh
Draco.:    hehe.. I understand, is the syntax that gets me at times :)
Magine:    you could define the macro like @arry[@,@,@]= something
Magine:    where the arguments would be the vlist handle, and the x and y indices of the simulated array
Draco.:    ut ohhh
Magine:    yes?
Draco.:    you know me and a challenge....
Keshi:    And you even have a place to test  lol
Magine:    @arry[@,@,@]=@lv_[~1,$fmt["%s,%s",~2,~3]]   would be one way
Magine:    assuming that the vlist had varialbes with names like "1,1", "1,2" etc
Draco.:    easy for you to say
PeLican:    i have to go, I'll leave Opie
Magine:    okay pelican, see ya next time
Magine:    but for your homework draco, there is another way you could do it, where the variable names wouldn't matter
Magine:    using the $lvar_ function [which returns the value of a vlist item by it's index in the vlist]
Draco.:    was hard enough remembering to put the $ before instead of after ;)
Draco.:    on that startup example I was using @time
Magine:    do you know how to simulate a 2 dimensional array using a 1 dimensional array?
Draco.:    *attempts to change subject*
Magine:    heheh
Magine:    ok, well this is beyond the intro class here anyway
Draco.:    can peek and poke.. hehe
Draco.:    arrggghhh.. aging myself

(I remember that too: PEEK and POKE were commands in BASIC to read and write specific memory locations...ah, I remember my first home computer: it had a whole 16k of RAM!  And a cassette tape recorder to save and load programs, and a TV for the monitor.)

Magine:    well....any questions before we end for today, anyone?

Belle. Thavas:    Magine did you get my email about the function you planned to make for surveying?
Magine:    yes!
Belle. Thavas:    terrific :-)
Magine:    here it is:
Magine:    @objinzone_rel[$]=@locinzone[~1,@atr[object_z]+@ns,@atr[object_x]+@we,@atr[object_y]+@alt]
Magine:    but i haven't had a chance to test it
Belle. Thavas:    ok
Guri Lady:    Ooo  what will that do?
[MadDog]:    im listening
Guri Lady:    I read the string.. I think I can figure that out hehe
Magine:    guri, remember when we tried to survey just the fountain here, using a zone?
Guri Lady:    Yes
Magine:    we used the @objinzone macro to test each surveyed object, to see if it was in the zone, and record only the objects in the zone
Magine:    but it didn't work, because we were doing a relative survey, so all the coordinates had been adjusted
Magine:    and therefore appeared to fall outside the zone

Recap from the earlier lesson: When you do a relative survey, the bots coordinates are substracted from the coordinates of all the objects surveyed, so that they appear to be near GZ. An object at the bot's coordinates would appear in the survey as if it were at GZ. When you rebuild the survey at another location, if building in relative mode, the bot's new location will be added back into the coordinates of all the objects, so they will be rebuilt at the bot's new location. However, this causes a problem when using a conditional expression and the @objinzone function on the survey dialog, because the adjusted coordinates of the objects seem to fall outside of the zone. The solution was to create a new macro, @objinzone_rel, that works like @objinzone except that it adds the bot's location back in to the object coords before checking to see if they are in the specified zone. The survey record will still show the objects as if they are around GZ, so they can be rebuilt properly at a new location.

Guri Lady:    Yes.. it was a tad hard
Guri Lady:    for my first time using the magsbot hehe
Magine:    well this new macro, @objinzone_rel, you would use instead of @objinzone if you were doing a relative survey
Guri Lady:    awesome
Magine:    you would use that in the conditional expression box on the survey dialog
Guri Lady:    Okay :)
Magine:    all it does is to add the bot's own coords to the surveyed object coords, when testing to see if the object is within the zone
Magine:    that way the test to see if the object is in the zone should still work right
Guri Lady:    Okay I remember we talked about it now
Guri Lady:    Will we have time to test it?
Magine:    one limitation: the Start At coords on the survey dialog should not be changed, they should be left as the default = the bot's coords
Magine:    when using the @objinzone_rel macro
Belle. Thavas:    I'll test it by Monday and let you know how it goes
Magine:    we could test it now, but my back is killing me today for some reason....
Magine:    that would be great belle
Guri Lady:    awe.. sorry to hear that Magine  *hugs*
Belle. Thavas:    Yes, go relax, and thanks for this..I'll catch up when you post the log
Magine:    if there are any problems with it, email me and i can try to work them out before next time
Guri Lady:    Yes.. we can test it or watch Belle hehe
Magine:    ok...and remember you can always post on my forum  if you have any questions :)
Belle. Thavas:    I'm still at sixes and sevens on this side of the screen haha..just barely here
Magine:    sleepy saturday, me too
Guri Lady:    Thank you, Magine for sitting here and teaching us
Magine:    ok folks, see everyone next time :)
Magine:    /dance


I forgot to give RedWolf the simpler code for a clock object, so here it is:

Create two rows at the top of the Behavior Table:

Active
Event
Action
On
OBJECTCLICK @ipos["~clock",$atr[object_action]]
@@clock=@objnum;
$$clock=$ologitem[@atr[object_z],@atr[object_x],@atr[object_y],@atr[object_yaw],@atr[object_tilt],@atr[object_roll],$atr[object_model],$atr[object_description],$atr[object_action],@atr[object_owner],@atr[object_build_timestamp]];
STARTTIMER 10 1000
On
CLOCKTICK @timer=10
$mk=$gv_[clock];
@@clock=@objectchange_[@clock,@arg[1],@arg[2],@atr[login_owner],@arg[1],@arg[2],@arg[3],@arg[4],@arg_tilt,@arg_roll,$arg_model,$now,$arg_act];


Create a sign object, put "create sign;~clock" in the action field. To start the clock,or reset it if there is a disconnection, just click on it!

If you want to prevent other people from clicking it, then change the first Event to
OBJECTCLICK @ipos["~clock",$atr[object_action]]&&@isctrl[$avname]
  ..then only a controller can reset it.