17 May, 2009, boblinski wrote in the 1st comment:
Votes: 0
Okay, sorry for how long this is.. but I just thought I'd show everything I did..

merc.h said:
#define BITS_PER_INT 32 /*+track*/
#define PATH_IS_FLAG(flag, bit) ((unsigned)flag[bit/BITS_PER_INT]>>bit%BITS_PER_INT&01) /*+track*/
#define PATH_SET_FLAG(flag, bit) (flag[bit/BITS_PER_INT] |= 1 << bit%BITS_PER_INT) /*+track*/
#define PATH_MAX_VNUM 32768 /*+track*/
#define PATH_MAX_DIR 6 /*+track*/


merc.h said:
extern sh_int gsn_hunt; /*+track*/


merc.h(pc_data) said:
sh_int track_count; /*+track*/


merc.h(room_index_data) said:
ROOM_INDEX_DATA * next_track; /*+track*/
ROOM_INDEX_DATA * track_came_from; /*+track*/


interp.h said:
DECLARE_DO_FUN( do_track ); /*+track*/


interp.c said:
{"track", do_track, POS_STANDING, 0, LOG_NORMAL, 1}, /*+track*/


const.c said:
{
"track", {53, 53, 1, 1}, {2, 2, 2, 2}, /*+track*/
spell_null, TAR_IGNORE, POS_STANDING,
&gsn_hunt, SLOT (0), 0, 12,
"", "!Track!", ""}


db.c said:
sh_int gsn_hunt; /*+track*/


act_move.c said:
void do_track( CHAR_DATA *ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char arg[MAX_STRING_LENGTH];
CHAR_DATA *victim;
int direction;
bool fArea;
int skill = 100;

skill /= 4;
skill += ch->level/5;

one_argument( argument, arg );

if (IS_NPC(ch)
|| ch->level < skill_table[gsn_hunt].skill_level[ch->class])
{
send_to_char("Huh?\n\r",ch);
return;
}

if( arg[0] == '\0' )
{
send_to_char( "Whom are you trying to hunt?\n\r", ch );
return;
}

/* only imps can hunt to different areas */
fArea = ( get_trust(ch) < MAX_LEVEL );

if( fArea )
victim = get_char_area( ch, arg );
else
victim = get_char_world( ch, arg );

if( victim == NULL )
{
send_to_char("No-one around by that name.\n\r", ch );
return;
}

if( ch->in_room == victim->in_room )
{
act( "$N is here!", ch, NULL, victim, TO_CHAR );
return;
}

/*
* Deduct some movement.
*/
if( ch->move > 2 )
ch->move -= 3;
else
{
send_to_char( "You're too exhausted to hunt anyone!\n\r", ch );
return;
}

act( "$n carefully sniffs the air.", ch, NULL, NULL, TO_ROOM );
WAIT_STATE( ch, skill_table[skill_lookup("hunt")].beats );

direction = find_path(ch->in_room, victim->in_room, skill);

if( direction == -1 )
{
act( "You couldn't find a path to $N from here.",
ch, NULL, victim, TO_CHAR );
return;
}

if( direction < 0 || direction > 5 )
{
send_to_char( "Hmm… Something seems to be wrong.\n\r", ch );
return;
}

/*
* Give a random direction if the player misses the die roll.
*/
if( ( IS_NPC (ch) && number_percent () > 75) /* NPC @ 25% */
|| (!IS_NPC (ch) && number_percent () > /* PC @ norm */
ch->pcdata->learned[skill_lookup("hunt")] ) )
{
do
{
direction = number_door();
}
while((ch->in_room->exit[direction] == NULL )
|| ( ch->in_room->exit[direction]->u1.to_room == NULL) );
}

/*
* Display the results of the search.
*/
sprintf( buf, "$N is %s from here.", dir_name[direction] );
act( buf, ch, NULL, victim, TO_CHAR );
check_improve(ch,skill_lookup("hunt"),TRUE,1);
return;
}


act_move.c said:
int find_path(ROOM_INDEX_DATA *from, ROOM_INDEX_DATA *to, int max_depth)
{
int bitvector[PATH_MAX_VNUM/BITS_PER_INT];
ROOM_INDEX_DATA *rlist;
ROOM_INDEX_DATA *track_room_list;
int i, depth;

bzero(bitvector, sizeof(bitvector));
PATH_SET_FLAG(bitvector, from->vnum);
track_room_list = from;
track_room_list->next_track = NULL;
for (depth = 0; depth < max_depth; depth++)
{
rlist = track_room_list;
track_room_list = NULL;
for (; rlist; rlist = rlist->next_track)
{
for (i = 0; i < PATH_MAX_DIR; i++)
{
if (!rlist->exit|| !rlist->exit->u1.to_room ||
PATH_IS_FLAG(bitvector, rlist->exit->u1.to_room->vnum))
continue;
PATH_SET_FLAG(bitvector, rlist->exit->u1.to_room->vnum);
rlist->exit->u1.to_room->track_came_from = rlist;
if (rlist->exit->u1.to_room == to)
{
if (rlist == from)
return i;
// if you need access to the entire path, this is the place to get it.
// basically it's back-tracking how it got to the destination.
// Also a good place to hinder track based on sector, weather, etc.
while (rlist->track_came_from != from)
rlist = rlist->track_came_from;
for (i = 0; i < PATH_MAX_DIR; i++)
if (from->exit&& from->exit->u1.to_room == rlist)
return i;
return -1;
}
else
{
rlist->exit->u1.to_room->next_track = track_room_list;
track_room_list = rlist->exit->u1.to_room;
}
}
}
}
return -1;
}
17 May, 2009, boblinski wrote in the 2nd comment:
Votes: 0
NOTE: My previous post was doing weird things with the last quote and wouldn't let me write stuff without putting it into a quote within itself… very weird… anyway, thats why I 'replied' with my explanation–>


Okay, obviously I'm trying to add a "track" skill to my QuickMud mud…

It's compiling right at the moment, but I know I will have done plenty wrong because I used a snippet I found combined with looking through the "Shadow" codebase and using pieces of their Track code.

The problems are:
1) I don't understand the code enough to see exactly what I have done wrong.

2) It seems to work right, and doesn't crash (as yet).. but it doesn't give me the -true- direction..

for example:
Char=level 30, track skill=100%

Vict=level 30, in the same area and 1 room west of Char.
char:
Quote
>skill
Vict is east from here.
>skill
Vict is south from here.
>skill
Vict is west from here.
>skill
Vict is east from here.


It seems that it is simply giving me a random direction each time…
17 May, 2009, Sharmair wrote in the 3rd comment:
Votes: 0
You say the trackers track skill is at 100, but the code looks up the skill in the hunt
skill. It seems to look for hunt in a few places, but the skill you setup is called track.
If you renamed the skill, you should go through the code and change all the references
to the old name. Better yet, if you already have the sn, use that instead of looking
it up again.
17 May, 2009, Davion wrote in the 4th comment:
Votes: 0
boblinski said:
NOTE: My previous post was doing weird things with the last quote and wouldn't let me write stuff without putting it into a quote within itself… very weird.


Try the code tag. It'll make things nicer for everyone ;)
17 May, 2009, boblinski wrote in the 5th comment:
Votes: 0
Davion said:
boblinski said:
NOTE: My previous post was doing weird things with the last quote and wouldn't let me write stuff without putting it into a quote within itself… very weird.


Try the code tag. It'll make things nicer for everyone ;)


I was going to.. but then I can't do the whole "act_move.c said" :cyclops:
17 May, 2009, boblinski wrote in the 6th comment:
Votes: 0
Sharmair said:
You say the trackers track skill is at 100, but the code looks up the skill in the hunt
skill. It seems to look for hunt in a few places, but the skill you setup is called track.
If you renamed the skill, you should go through the code and change all the references
to the old name. Better yet, if you already have the sn, use that instead of looking
it up again.


Lol wow, that helped a lot!

Okay, so I'm wanting to somehow count the number of rooms to tell how far away the Vict is..

Then display my output to be-
1-5 rooms away: "Bob is north of here, the trail is fresh.
5-20 rooms away: "Bob is north of here, trail is fading.
20-x rooms away: "Bob is north of here, the trail is faint.

Any tips on where/what I should be looking at to count the rooms?
17 May, 2009, Davion wrote in the 7th comment:
Votes: 0
The Code said:
// if you need access to the entire path, this is the place to get it.
// basically it's back-tracking how it got to the destination.
// Also a good place to hinder track based on sector, weather, e


Under that comment is the path. You'll either have to recreate the algorithm to map, rework it to be able to return a distance (or better yet, the entire path).
17 May, 2009, Davion wrote in the 8th comment:
Votes: 0
boblinski said:
I was going to.. but then I can't do the whole "act_move.c said" :cyclops:


That's a small price to pay for escaped bbcode tags ;). You'll note that in the code you provided to us, all I see is rlist->exit->u1.to_room, which doesn't make much sense, considering exit is an array…
17 May, 2009, Sharmair wrote in the 9th comment:
Votes: 0
boblinski said:
Okay, so I'm wanting to somehow count the number of rooms to tell how far away the Vict is..

Then display my output to be-
1-5 rooms away: "Bob is north of here, the trail is fresh.
5-20 rooms away: "Bob is north of here, trail is fading.
20-x rooms away: "Bob is north of here, the trail is faint.

Any tips on where/what I should be looking at to count the rooms?

This is a breath first search algorithm (it searched all rooms one away, then goes on to 2 away
and so on) and in this version it keeps track of where it is at with the variable depth. It looks
like depth+1 would be the distance when the function returns. The main problem here is you
would want to return two different things from the function, you could 1) pack both data points
in one int, then split them off in the calling function, 2) make the function return a struct that
has the two members, or 3) pass in a pointer to a variable in the calling function that the
function can write to (there are probably more ways, but these come to mind).

Using method 3, you could change the calling function to have an int called distance, then
call like so (I would also initialize it to 0):
direction = find_path(ch->in_room, victim->in_room, skill, &distance);

The prototype of the find_path() would be:
int find_path(ROOM_INDEX_DATA *from, ROOM_INDEX_DATA *to, int max_depth, int* dist)

And at the start of the for using depth have this:
for (depth = 0; depth < max_depth; depth++)
{
*dist = depth+1;
rlist = track_room_list;

Then in the track function use distance to figure what to say.
18 May, 2009, David Haley wrote in the 10th comment:
Votes: 0
Davion said:
boblinski said:
I was going to.. but then I can't do the whole "act_move.c said" :cyclops:


That's a small price to pay for escaped bbcode tags ;). You'll note that in the code you provided to us, all I see is rlist->exit->u1.to_room, which doesn't make much sense, considering exit is an array…

Besides, code is far less legible when not monospace-formatted. I usually don't even look at code until it gets correctly formatted :smile:
18 May, 2009, quixadhal wrote in the 11th comment:
Votes: 0
Davion said:
boblinski said:
I was going to.. but then I can't do the whole "act_move.c said" :cyclops:


That's a small price to pay for escaped bbcode tags ;). You'll note that in the code you provided to us, all I see is rlist->exit->u1.to_room, which doesn't make much sense, considering exit is an array…


It makes sense… it's just not doing what the author probably intended. exit->u1.to_room == (*exit).u1.to_room == exit[0].u1.to_room. It won't crash as long as exit[0] is defined (north?), but it also won't look in any other directions.

Have I mentioned that I hate C. :alien:
18 May, 2009, David Haley wrote in the 12th comment:
Votes: 0
Actually since exit is an array of pointers to exits, the variable 'exit' is of type pointer to pointer to exit, not just pointer to exit. The compiler would complain about trying to take the field of a thing of type pointer to pointer, and in any case, 'exit' isn't guaranteed at all to point to the same thing as exit[0]. So it's not really a sensible thing to do, never mind the fact that it doesn't do what was intended…
18 May, 2009, boblinski wrote in the 13th comment:
Votes: 0
Could someone maybe point out exactly what isn't doing what it's supposed to.. and possibly explain what it's doing and what it's meant to be doing…
18 May, 2009, David Haley wrote in the 14th comment:
Votes: 0
See post #8.
18 May, 2009, boblinski wrote in the 15th comment:
Votes: 0
Oh, right, I see now that the "quote" tags did stuff things up a little.. here is the actual find_path():

int find_path(ROOM_INDEX_DATA *from, ROOM_INDEX_DATA *to, int max_depth, int *dist)
{
int bitvector[PATH_MAX_VNUM/BITS_PER_INT];
ROOM_INDEX_DATA *rlist;
ROOM_INDEX_DATA *track_room_list;
int i, depth;
// int distance = 0;

bzero(bitvector, sizeof(bitvector));
PATH_SET_FLAG(bitvector, from->vnum);
track_room_list = from;
track_room_list->next_track = NULL;
for (depth = 0; depth < max_depth; depth++)
{
*dist = depth+1;
rlist = track_room_list;
track_room_list = NULL;
for (; rlist; rlist = rlist->next_track)
{
for (i = 0; i < PATH_MAX_DIR; i++)
{
if (!rlist->exit[i] || !rlist->exit[i]->u1.to_room ||
PATH_IS_FLAG(bitvector, rlist->exit[i]->u1.to_room->vnum))
continue;
PATH_SET_FLAG(bitvector, rlist->exit[i]->u1.to_room->vnum);
rlist->exit[i]->u1.to_room->track_came_from = rlist;
if (rlist->exit[i]->u1.to_room == to)
{
if (rlist == from)
return i;
// if you need access to the entire path, this is the place to get it.
// basically it's back-tracking how it got to the destination.
// Also a good place to hinder track based on sector, weather, etc.
while (rlist->track_came_from != from)
rlist = rlist->track_came_from;
for (i = 0; i < PATH_MAX_DIR; i++)
if (from->exit[i] && from->exit[i]->u1.to_room == rlist)
return i;
return -1;
}
else
{
rlist->exit[i]->u1.to_room->next_track = track_room_list;
track_room_list = rlist->exit[i]->u1.to_room;
}
}
}
}
return -1;
}
0.0/15