Magine: hi all
ZebLith: ^^
ZebLith: Good morning Magine :)
Anubis GK: Heya there, Magine!
Anubis GK: I suppose these are the right cords!
Magine: yep
Magine: so, zeb, did you get the database stuff working with Win
ME?
ZebLith: Okay, I didn't try win me, I'm on win xp right now.
I was just about to try it again. I should have ust copied my bot
over from my main computer, but I woke up late. So...that's my goal
for this morning. :)
Magine: ok
Magine: well, can you try it out now and see how it goes?
ZebLith: yes, I just need to type everything back in. I'm
checking with the class log as well.
Magine: our scheduled topic for this last class is anything leftover
that you want to know more about...
Magine: so, anubis, any topics you'd like me to discuss today?
Anubis GK: Aye, if/when statements, and how to make it so a user
can specify a variable.
Anubis GK: *Laughs* It's an easy topic, I know....but I spent all
last night trying to figure it out.
Magine: how do you mean, specify a variable?
Anubis GK: Let me telegram you the code I have so far:
Telegram from Anubis GK, sent just now:Anubis GK: Now the problem is, that I want the users, to type a responce in the chat dialog, and from that responce, the program will take one of 2 different paths. ^_^'
SAY "All player's to there marks. The race will start in 10 seconds!";
MBWAIT 10000;
@i=10;
WHILE @i>0 {
MBWAIT 1000;
SAY $str[@i];
@i=@i-1 };
MBWAIT 1000;
SAY "GO GO GO!"
SAY "All player's to there marks. The race will start in 10 seconds!";Magine: so, how do you want the players to respond, to what?
@i=10;
WHILE @i>0 {
SAY $str[@i];
MBWAIT 1000;
@i=@i-1 };
SAY "GO GO GO!"
HEAR @eq[$chat,YES]Anubis GK: Aye, I thought of that too. Isn't there a command to only make it exicute if another event has occured?
Magine: how's it coming zeblith?
ZebLith: oh no way, it worked.
Magine: :D
ZebLith: well, sorta.
ZebLith: lol
Anubis GK: =D
Magine: sorta? what didn't work?
ZebLith: it didn't add a line to the database, but it didn't give
an error. so...>_<
ZebLith: let's try restarting this again. ^^
Magine: it didn't add a line though...when someone arrived?
ZebLith: yes, it didn't add a row to the database for a new person.
but I skipped a restart as I did it, so let's try this again. ^^
Magine: ok...
ZebLith: lol, there was the problem. I was reading a different
database. it DID work. :D
Magine: ok, cool
Magine: well now, to kill two questions with one answer, we could
do an example in which the bot asks someone a question and uses the answer
to add to the database
ZebLith: great :D
Anubis GK: Aye!
Anubis GK: ^_^
Magine: just a moment while i grab some code from the awrpg bot...it
has a nice question-and-answer system
ZebLith: okay :)
Anubis GK: Aye, that's for sure. ^_^
Anubis GK: Oh, the new coding works like a charm Magine! =D
Magine: :)
Magine: ok....let me see here....
Magine: ok...let's have the bot ask a person what their home world
is, when they first arrive
Magine: first let's make some changes to the AVATARADD event that
we did last time
IF @dbfindfirst[$fmt["Name='%s'",$avname]]=0 { DBAPPEND };Magine: change that, to this:
IF @dbfindfirst[$fmt["Name='%s'",$avname]]=0 {Magine: then, at the end of the existing code, add
@new=1;
DBAPPEND }
ELSE {
@new=0 };
IF @new {Magine: so that the whole thing should be
SAY "What is the name of your home world?";
SETITEM_ "q_"+$botname @avsession 1 }
DATASET @MyDatabase {Magine: there, that's right :D
DBTABLE MyTable;
DBACTIVE 1;
IF @dbfindfirst[$fmt["Name='%s'",$avname]]=0 {
@new=1;
DBAPPEND }
ELSE {
@new=0 };
DBEDIT;
DBFIELD Name=$avname;
DBFIELD_ ID=@atr[avatar_citizen];
DBFIELD_ LastVisit=@now;
DBPOST };
IF @new {
SAY "What is the name of your home world?";
SETITEM_ "q_"+$botname @avsession 1 }
(During the class I actually used $cat["q_",$botname] instead of "q_"+$botname. Either way would do the same thing; the $cat function just combines two strings, in this case q_ and the the bot's name. I changed it here to make it a bit simpler to understand.)
Magine: the reason for basing the list name on the bot's name is
so that if you are running other bot sessions at the same time,
Magine: each one can ask questions independently
Magine: so to put it another way, SETITEM_ $cat["q_",$botname]
@avsession 1 will create a global variable like @q_Mags:1234
with a value of 1
Magine: where 1234 would be the session number of the avatar being
asked the question.
Magine: now, to handle replies,
Magine: you would add a HEAR event, following any other HEAR events,
Magine: with this as the Event:
HEAR @reacted=0 && @asn[n,@litem[$cat["q_",$botname],@chatsession]]Magine: and this as the Action:(Note in this case, you must use $cat["q_",$botname] instead of "q_"+$botname, because the + operator for combining strings won't work when it's a function parameter.)
REM handle player reply to bot's question;Anubis GK: You weren't kidding when you said it was tricky.
@av=@chatsession;
$av=$avname;
REM REPORT $fmt["chatsession=%s pending question=%s",@av,@n];
IF @n=0 {
REM do nothing if question number + player's session number not found in list q;
BREAK };
REM otherwise free item from pending question list and call the userevent for the question;
FREEITEM_ $cat[q_,$botname] @av;
$reply=$triml[$tail[$chat,2]];
USEREVENT @n
HEAR @reacted=0 && @asn[n,@litem[$cat["q_",$botname],@chatsession]]Anubis GK: *Nods* Aye.
Magine: next, the && is just
logical "and"
Magine: so both @reacted=0 AND the rest of the condition
must be true, for the whole condition to be considered true
Magine: so let's look at the rest:
@asn[n,@litem[$cat["q_",$botname],@chatsession]]Magine: for the moment we can forget about the @asn and just look at the inner part:
@litem[$cat["q_",$botname],@chatsession]Magine: the $cat[q_,$botname] part is simple, it's just creating a string from the bot name, for example "q_Mags".
HEAR @reacted=0 && @asn[n,@litem[$cat["q_",$botname],@chatsession]]Magine: "if none of the previous rows of the table with Event=HEAR were triggered, AND if there is an item in q_botname with item number = the speaker's session number" (and incidentally assign the item value to @n)
(For example if the session of the person speaking is 1234, then the SETITEM_ command would have assigned a number to global variable @q_botname:1234 = item 1234 of list @q_botname.)
Anubis GK: Oops.
Magine: so there can only be one entry in q_Mags for each person
Magine: thus, only one pending question for each person.
Magine: what i need to explain to clarify this is,
Magine: that q_botname is a list of pending question numbers
Magine: that 1 we assigned to @q_botname:1234 stands
for question #1.
Magine: and each possible question will get it's own row in the
behavior table.
Magine: that is, each question will get a row in the behavior table
to handle the replies to that question
Anubis GK: Ahh!
ZebLith: oooh :D
Magine: but first there is a row in the table (the row we're looking
at now) that routes player chat to the correct row for the particular question.
Anubis GK: Ohhhh! *Light bulb* Makes sence now!
Magine: so the Event condition we've looked at so far,
Magine: checks to see if the bot is expecting a reply
Magine: from the particular speaker
Magine: and if a reply is being expected, then the action takes
place,
Magine: which routes the player's chat to the correct row for the
question whose reply is being waited for.
Anubis GK: Hey, that's handy for more then one thing! ^_^
Magine: and that action [to route replies to different table rows]
is this:
REM handle player reply to bot's question;ZebLith: nifty ^^
@av=@chatsession;
$av=$avname;
REM REPORT $fmt["chatsession=%s pending question=%s",@av,@n];
IF @n=0 {
REM do nothing if question number + player's session number not found in list q_botname;
BREAK };
REM otherwise free item from pending question list and call the userevent for that question number;
FREEITEM_ $cat[q_,$botname] @av;
$reply=$trim[$chat];
USEREVENT @n
In the GM bot in AWRPG, there is an additional complication:
the person speaking has to prefix a colon : to their reply, so the bot
will know they're speaking to it. To add this feature, you would make these
changes:
REM handle player reply to bot's question; |
Magine: ok, so far so good....now we need to add a USEREVENT row to handle that particular question.
[Chilaou]: What is the name of your homeworld?
Magine: heheh
ZebLith: okay, It's taking everything. bleh. >_<
Anubis GK: *does a thumbs up*
Anubis GK: Well, it's a step in the right direction?
Magine: so you would add a behavior table row with event:
USEREVENT @userevent=1Magine: and in the action for that row,
| A final summary:
1. The bot asks the question, and uses SETITEM_ to create an entry in the @q_botname list, using the session number of the person being asked as the list item number, and the question number as the value being assigned. 2. In the HEAR event, if no previous HEAR events caused a response and if the speaker's session number is found as an item number in the @q_botname list, then the question number is retrieved from the list, and the item is freed. Then a USEREVENT is generated, using the question number as the userevent number; the speaker's reply is passed to the USEREVENT in $reply, and the session and name of the speaker are passed in @av and $av. 3. In the USEREVENT where @userevent = the question number, the bot responds appropriately according to the speaker's reply. |
Magine: so...(getting back to database stuff now, heheh)....to put
the person's reply into the database
Magine: for the action in the USEREVENT row (Event: USEREVENT
@userevent=1), you could put:
REM player replies to "Home world?";Magine: note that @av, $av and $reply are already assigned in the action that called the USEREVENT.
DATASET @MyDatabase {
DBTABLE MyTable;
DBACTIVE 1;
IF @dbfindfirst[$fmt["Name='%s'",$avname]]=0 {
SAY "I can't find your data, sorry.";
BREAK };
DBEDIT;
DBFIELD "Home world"=$reply;
DBPOST }
[in the example, if the record for the arriving avatar isn't found in the database, then @dbfindfirst will return 0 and the BREAK will cause execution to leave the DATASET clause, thus ending the response. more generally, the BREAK command causes execution to leave the current context, whether it's a FOR or WHILE loop, DATASET clause, etc, or the action itself; but notice that BREAK within an IF clause doesn't just leave the IF clause, it leaves whatever is outside the IF clause. that's unique to the IF command, as far as BREAK is concerned.]
Magine: any other questions about all that?
Anubis GK: None here.
ZebLith: Ditto.
Magine: well, only a short time left for today's lession....i want
to briefly mention SQL statements, or if there are any other topics at
all you want to talk about?
ZebLith: No other topics from me; you already covered all my questions.
:)
Anubis GK: Let's talk about SQL, I'm curious what that is.
Magine: ok :)
Magine: well, SQL stands for "structured query language", and it's
a language for manipulating databases
Magine: intended to be universal, since most all serious databases
will handle SQL to some extent.
Anubis GK: It sounds familar for some reason.
Magine: it ought to be :)
Magine: you can find a lot more information about SQL syntax on
the web...for instance http://users.pandora.be/pecop/sqlr/
is a good source.
ZebLith: that looks familiar. ;)
Magine: that page just covers the simple commands though...SQL
is very large and complex, and i'm no expert
Magine: but the cool thing is....
Magine: that since most database drivers support it,
Magine: and magsbot can connect to most databases using ADO,
Magine: it was really easy for me to add SQL functionality to magsbot
Magine: even though i'm only a beginner at SQL myself :D
Anubis GK: lol, that's neat. ^_^
ZebLith: very :D
Anubis GK: Well, it certainly is an expancive resouce.
Magine: so...you can use SQL in magsbot with the DBSQLSET, DBSQLEXEC
and DBSQL commands.
Magine: using DBSQLSET you can use the various SELECT commands
in SQL to filter a database
Magine: for example
DBSQLSET "select * from Users where HP_current>10"Magine: that would be something i could use with the AWRPG database to find players whose current HP's are above 10. [you can also use the SQL select command in the SQL edit box on the magsbot database window]
@dbfindfirst[$fmt["Name='%s'",$avname]]Magine: you could use
DBSQLSET $fmt["select * from MyTable where Name='%s'",$avname]Magine: then you would use @dbreccount to see if any records with that name were found
DBSQL "update Users set HP_current=1000 where Name='Magine'"Magine: to give myself 1000 HP's, heheh
Seraph arrived and we continued to discuss bots' ability to detect collision.
Anubis GK: Hmmm, and so my original problem of how to get the bot
to recognize when someone passes a finish line remains...hmmm.
...
Magine: anubis, you could determine when someone passes a line
in other ways that collision detection
...
Magine: there's a system in magsbot for detecting if a person is
within an area [using the SetArea buttons]
Magine: to detect if an avatar is within an area, you can define
the area using the SetAreaN,S,W,E buttons on the . tab
Anubis GK: Hmmm, aye!
Magine: then in your program, use the @safe_ function
Magine: like IF @safe_["MyArea",@avsession]
We were also playing around with having the bots detect object and avatar clicks and object selection. For that you would simply use the AVATARCLICK, OBJECTCLICK or OBJECTSELECT events. Within the action for AVATARCLICK you would use $atr[clicked_name] or @atr[clicked_session] for the name or session of the avatar being clicked.
And we talked about getting bots to follow you:
Anubis GK: Because I wish to one day have pets that follow around
in Morroc.
Magine: well there is a follow command in the standard table
Magine: mags follow
[Mags]: After you...
Magine: mags stay
[Mags]: Okay, staying put.
Magine: so you can look at the code to figure out how to make yours
follow
Magine: oh there's also a follow button on the movement tab, even
simpler example