Thread

Totally confused about object query (Sdk)

Totally confused about object query // Sdk

1  |  

pj47

Mar 30, 2000, 12:21am
Hi-

Can someone who knows about object querying tell me what I am doing wrong?
I am trying to get a bot to change an object into a teleport (and, of
course, eventually change it back). I tried to modify the SDK Sample 2
DJBot program and it works fine at ground zero (with the object at 1N 1W)
when I leave the querying commands as in the sample program.

The problem is when I try to translate it to an object that my world reports
as being at 17N 9W and that Buildbot says is at 17600NS 9700WE 10110A.
(Note: it is at about 101.1 altitude, although I don't think that matters).

It seems to me that I need to make the following changes to the querying
code to find this object:
1) Change first query command to aw_query (1, 2, sequence)
2) Also change the query command in void handle_query (int rc) to aw_query
(1, 2, sequence)
3) Change to cell_x == 9 && cell_x==17 in void handle_cell_object (void)

However, this just goes into a continual loop looking for x number of bytes
over and over (query never seems to end). What am I missing? It appears
that the query is not being updated at 16N 8W.

[Also, out of curiosity, how does the SDK get away with things like:
if (rc = aw_query (0, 0, sequence))

I'm a novice but it seems I was trained that you need double equal signs for
Boolean expressions]

FYI. The code I am using is below:

#include "stdafx.h"
#include "aw.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define FIVE_MINUTES (5 * 60 * 1000)
#define CHANGE_OBJECT "dreser01.rwx"
#define WORLD "hitchhke"

void handle_cell_begin (void);
void handle_cell_object (void);
void handle_query (int rc);
void change_object (void);

int owner;
int sequence[3][3];
int obj_x;
int obj_y;
int obj_z;
int obj_yaw;
int obj_number = 0;
int cell_x;
int cell_z;


main (int argc, char *argv[])
{

int rc;

/* check command line */
if (argc < 3) {
printf ("Usage: %s number password\n", argv[0]);
exit (1);
}

/* initialize Active Worlds API */
if (rc = aw_init (AW_BUILD)) {
printf ("Unable to initialize API (reason %d)\n", rc);
exit (1);
}

/* install cell update event handlers */
aw_event_set (AW_EVENT_CELL_BEGIN, handle_cell_begin);
aw_event_set (AW_EVENT_CELL_OBJECT, handle_cell_object);

/* install query callback */
aw_callback_set (AW_CALLBACK_QUERY, handle_query);

/* create bot instance */
if (rc = aw_create (0, 0, 0)) {
printf ("Unable to create bot instance (reason %d)\n", rc);
exit (1);
}

/* log bot into the universe */
owner = atoi (argv[1]);
aw_int_set (AW_LOGIN_OWNER, owner);
aw_string_set (AW_LOGIN_PRIVILEGE_PASSWORD, argv[2]);
aw_string_set (AW_LOGIN_NAME, "Jed");
if (rc = aw_login ()) {
printf ("Unable to login (reason %d)\n", rc);
exit (1);
}

/* log bot into the world */
if (rc = aw_enter (WORLD, 0)) {
printf ("Unable to enter world (reason %d)\n", rc);
exit (1);
}

/* issue first property query for the ground zero area so that we can
locate
the SPEAKER_OBJECT */
printf ("Looking for object...\n");
if (rc = aw_query (1, 2, sequence)) {
printf ("Unable to query property (reason %d)\n", rc);
exit (1);
}

/* wait for query to complete and then change music every five minutes */
while (!(rc = aw_wait (FIVE_MINUTES)))
if (obj_number)
change_object();

/* close everything down */
aw_destroy ();
aw_term ();
return 0;

}

void change_object (void)
{

int rc;
char action[100];

aw_int_set (AW_OBJECT_OLD_NUMBER, obj_number);
aw_int_set (AW_OBJECT_OLD_X, obj_x);
aw_int_set (AW_OBJECT_OLD_Z, obj_z);
aw_int_set (AW_OBJECT_X, obj_x);
aw_int_set (AW_OBJECT_Y, obj_y);
aw_int_set (AW_OBJECT_Z, obj_z);
aw_int_set (AW_OBJECT_YAW, obj_yaw);
aw_int_set (AW_OBJECT_OWNER, owner);
aw_string_set (AW_OBJECT_MODEL, CHANGE_OBJECT);
aw_string_set (AW_OBJECT_DESCRIPTION, "");
sprintf (action, "create solid off, visible off;bump teleport 5N 5W
102a");
aw_string_set (AW_OBJECT_ACTION, action);
if (rc = aw_object_change ())
printf ("Unable to change object (reason %d)\n", rc);
else {
printf ("Object changed.\n");
obj_number = aw_int (AW_OBJECT_NUMBER);
}

}

void handle_cell_begin (void)
{

int sector_x;
int sector_z;

/* This is called to indicate we are receiving the contents of a new cell.
All
we need to do here is update the sequence number array for the next
call to
aw_query (). */
cell_x = aw_int (AW_CELL_X);
cell_z = aw_int (AW_CELL_Z);
sector_x = aw_sector_from_cell (cell_x);
sector_z = aw_sector_from_cell (cell_z);
sequence[sector_z + 1][sector_x + 1] = aw_int (AW_CELL_SEQUENCE);

}

void handle_cell_object (void)
{

/* This is called once for each object in each cell that we are querying.
We
check to see if the object is the OBJECT we are looking for, by
checking the name of the object and the cell it is located in. */
if (cell_x == 9 && cell_z == 17 &&
!strcmp (aw_string (AW_OBJECT_MODEL), CHANGE_OBJECT)) {
obj_x = aw_int (AW_OBJECT_X);
obj_y = aw_int (AW_OBJECT_Y);
obj_z = aw_int (AW_OBJECT_Z);
obj_yaw = aw_int (AW_OBJECT_YAW);
obj_number = aw_int (AW_OBJECT_NUMBER);
printf ("Object located!\n");
change_object();
}

}

void handle_query (int rc)
{

/* This is called when the server has stopped sending property data. If
we haven't
found the speaker yet, then we check if the query is complete, and if
not,
issue a new query with the updated sequence numbers to continue the
update. */
if(!obj_number)
if (!aw_bool (AW_QUERY_COMPLETE))
aw_query (1, 2, sequence);
else
/* the query is complete but we didn't find the speaker! :( */
printf ("Couldn't find object.\n");

}

canopus

Mar 30, 2000, 2:34am
Maybe one problem is with the final line of handle_cell_begin:

sequence[sector_z + 1][sector_x + 1] = aw_int (AW_CELL_SEQUENCE);

This adds a constant value of 1 to sector_x and sector_z, which only
works in the SDK Sample situation (an object right at GroundZero, so
that 1 - intended_sector_x/intended_sector_z = 1 - 0 = 1). You need to
compute the difference for your initial Sector_Numbers, & add those two
constants to sector_x and sector_z. When I wrote the Delphi version of
Sample 2, I put the midispk at 1S 78W [SectorX=10, SectorZ=0], so that
this would be clear from the Sample, which looks for sequence[sector_z +
1, sector_x - 9]. (The Delphi API, the Samples, & the Delphi
Encapsulation of the SDK are now posted at
http://www.canopus.org/delphi/delphi.html.) Your Query is set to start
out at SectorX=2, SectorZ=1. So 1 - 2 = -1 and 1 - 1 = 0, your
constants. I think I got that right...it's always all little confusing.

It wouldn't hurt to retain the paranoid code line from the sample that
says "if (sector_x < 9) or (sector_x > 11) or (sector_z < -1) or
(sectorz > 1) then exit" // and maybe raise an error. (Your intended
Sector_Numbers are the middle ones of your Zone.)

[I think the line of C code which bothers you means "set rc to the
return value of aw_query(..), &, treating rc as a Boolean (either zero
or nonzero), do one of the following". But I'm used to Delphi, & could
easily be wrong about compact lines of C code.]


[View Quote]

andon13

Mar 30, 2000, 2:57pm
About what the AW SDK samples do . . .

[Also, out of curiosity, how does the SDK get away with things like:
if (rc = aw_query (0, 0, sequence))

I'm a novice but it seems I was trained that you need double equal signs for
Boolean expressions]




Well . . . What this is REALLY saying is :

Forget about the If for now.

int rc = aw_query(0,0, sequence);
If (rc) /* Actually equates to : If (rc == true), but you do not need to do
this in C++ . . . If you wanted the code to execute if rc was false, you'd
do : If (!rc), where '!' is the C++ symbol for NOT (In C it was '~', that's
why Class Destructors are always ClassName::~ClassName(void);, but that's
another story :)) */
..
..
..

Where it will execute the code in the If block if rc is Non-Zero.
In the case of AW, Non-Zero (in terms of BOOL : true) would be an Error Code
.. . .
So, you then use the newly set rc to determine the error code.

If no error occurred, rc will be set to 0 (false)
And it will continue on past the If . . .


This is Roland's method for a somewhat decent Error Notification method.

Ideally, he would Throw a CException with the error text containing all of
the data passed by the calling function, etc . . .
This is how I do it in my SDKs, and it works great!

His concern is that it wouldn't be as easily portable to other Languages if
he added some C++ ONLY extensions to the SDK.



Anyway, I use this method a lot, all it really does is save space in your
code, since you could just as easily write it the way I demonstrated above.



Now, about your AW Object Querying, sorry . . . Can't help you there, I
tried using that once for my DJ Bot, but got so confused I just gave up :)


Best Regards,
Andon M. Coleman

Senior Programmer,
R&D

Nothing, Inc.
http://www.nothing-inc.com/ - Under construction . . .


[View Quote]

ima genius

Mar 30, 2000, 5:37pm
--------------8711A261E0C25DAB5F98FF50
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi,
First of all, rc is an integer. You should not confuse people by comparing
it to 'true' or 'false' since those are for booleans. In if statements, C/C++
considers something 0 or NULL as false and anything else as true. == is the
comparison operator and = is the assignment operator. What

if (rc = aw_query (0, 0, sequence))

really means is this:

rc = aw_query (0, 0, sequence);
if (rc != 0) {...}.

However, it is a lot easier to put all in one line. Also, for integers in C,
it was still if (!rc) which would be true if rc was 0. ~ is the bitwise not
operator, you shouldn't confuse this with the logical not operator (!).
- Ima


[View Quote] > [Also, out of curiosity, how does the SDK get away with things like:
> if (rc = aw_query (0, 0, sequence))
>
> I'm a novice but it seems I was trained that you need double equal signs for
> Boolean expressions]
>

> If (rc) /* Actually equates to : If (rc == true), but you do not need to do
> this in C++ . . . If you wanted the code to execute if rc was false, you'd
> do : If (!rc), where '!' is the C++ symbol for NOT (In C it was '~', that's
> why Class Destructors are always ClassName::~ClassName(void);, but that's
> another story :)) */
>

--------------8711A261E0C25DAB5F98FF50
Content-Type: text/html; charset=us-ascii
Content-Transfer-Encoding: 7bit

<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
Hi,
<br>&nbsp;&nbsp;&nbsp; First of all, rc is an integer.&nbsp; You should
not confuse people by comparing it to 'true' or 'false' since those are
for booleans. In if statements, C/C++ considers something 0 or NULL as
false and anything else as true.&nbsp; == is the comparison operator and
= is the assignment operator.&nbsp; What
<p>if (rc = aw_query (0, 0, sequence))
<p>really means is this:
<p>rc = aw_query (0, 0, sequence);
<br>if (rc != 0) {...}.
<p>&nbsp;&nbsp;&nbsp; However, it is a lot easier to put all in one line.
Also, for integers in C, it was still if (!rc) which would be true if rc
was 0.&nbsp; ~ is the bitwise not operator, you shouldn't confuse this
with the logical not operator (!).
<br>&nbsp;&nbsp;&nbsp; - Ima
<br>&nbsp;
[View Quote] <blockquote TYPE=CITE>
<pre>If (rc) /* Actually equates to : If (rc == true), but you do not need to do
this in C++ . . . If you wanted the code to execute if rc was false, you'd
do : If (!rc), where '!' is the C++ symbol for NOT (In C it was '~', that's
why Class Destructors are always ClassName::~ClassName(void);, but that's
another story :)) */</pre>
</blockquote>
</html>

--------------8711A261E0C25DAB5F98FF50--

pj47

Mar 30, 2000, 11:16pm
I understand that the functions are returning an int (i.e., rc), and I know
that 0 is false and anything else is true. But, it seems to me that you get
the same thing by:

if (aw_query (0, 0, sequence)) ...

and you save on the "rc =" in front and you avoid the possible confusion of
= vs. ==.



[View Quote] [View Quote] If (rc) /* Actually equates to : If (rc == true), but you do not need to do
this in C++ . . . If you wanted the code to execute if rc was false, you'd
do : If (!rc), where '!' is the C++ symbol for NOT (In C it was '~', that's
why Class Destructors are always ClassName::~ClassName(void);, but that's
another story :)) */

pj47

Mar 30, 2000, 11:31pm
Thanks so much for the help!!! That the sequence array has the format:

sequence[sector_z + constant][sector_x + constant]

and that it must end up as sequence[1][1] is about as clear as mud. Now
that I consider it, it makes sense. Someone should make this clear in the
sample program because it appears that I am not the only person who didn't
get this point.

Wish I could buy you a beer. Have a virtual one on me.

PJ47

[View Quote]

ima genius

Mar 31, 2000, 12:07am
That would work, however you could not tell which error occurred. You could
just tell than an error occurred.
- Ima

[View Quote] > I understand that the functions are returning an int (i.e., rc), and I know
> that 0 is false and anything else is true. But, it seems to me that you get
> the same thing by:
>
> if (aw_query (0, 0, sequence)) ...
>
> and you save on the "rc =" in front and you avoid the possible confusion of
> = vs. ==.
>
[View Quote]

1  |  
Awportals.com is a privately held community resource website dedicated to Active Worlds.
Copyright (c) Mark Randall 2006 - 2024. All Rights Reserved.
Awportals.com   ·   ProLibraries Live   ·   Twitter   ·   LinkedIn