So i was thinking about your tracking code, and this is an approach i would
try...

struct track_data
{
    TRACK_DATA *next_in_room;
    CHAR_DATA *victim;
    int                     dir_from;
    int                     dir_to;
    int                     age;
};

TRACK_DATA *new_track(void)
void *free_track(THAR_DATA *track)

(using the same format as the rest of recycle stuff, using a track_free)

in char_data:
     int                        from_dir;
in room_index_data:
     TRACK_DATA *tracking;

now what i would do is every time a character left a room, they created a
track data for the last room.  Also i would make dir_from in the track
data -1 if the character 'orginated there'  (aka gate spell, or signed on
the game or something) so in move_char it'd be something like this:

if ( do_track )
{
    track = new_track();
    track->victim = ch;
    track->dir_to = door;
    track->dir_from = ch->from_dir;
    /*since you copied a static one in your new_track, age should already be
0*/

    /*id put it in front so the older tracks are in the back if you wanna do
some code for
    /*overlapping stuff*/
    track->next_in_room = was_in_room->tracking;
    was_in_room->tracking = track;
}

so your going to need a check whenever someone signs on/gates/gotos that the
dir_from is -1, also you'll need to make the check in move_char to make the
rev_door[door] = ch->from_dir...  You'll prolly want to make a character
that leaves a room via gate his tracks end with a -1 too... its up to you.
Now you have to go through all the rooms whenever you want to increase the
age on tracks... and do that, but that should be relatively straitforward.
The only problem with this way i see is whenever a character quits(like
Dennis said) your going to have to do a huge ass for(;;) loop that cycles
through rooms checking for the track->victim == ch then erase it...
Perhaps use the players id instead of the char_data in the track_data...
then in update tracks, add a simple if(!is_playing_id(track->id) delete the
track... that seems to be better memory usage if your ok with making a new
function to check if an id is signed on(a function i already use, and would
prolly imp for this, if you get me psyched about your cool code enough to
try something of your own.)
    Another way of doing it is to link them all to characters instead of
rooms(or in addition to rooms) perhaps a character has a TRACK_DATA
*all_tracks that just points to each of his tracks? that would seem to me it
would help memory useage when he quits the game...
    Now none of this will compile, but i always found it helpful for another
view on what was going on.  I'm by no stretch even remotely as good of a
coder as Most of these other people that have helped you out, but i figured
i'd try to help, so far this list has been really helpful to me, and I wish
to help anyone i can too.
    Thats some of my thoughts on it... lemme know what you choose for a
final result and how it works out, im intersted in this, it looks like you
have a good start for something
Feel free to use any of my help(if its right/you like it) or feel free to
tell me what i did wrong... I don't even mind lower case flames.   ;)

-Josh

----- Original Message -----
From: "Dennis" <[EMAIL PROTECTED]>
To: "Daniel Byer" <[EMAIL PROTECTED]>
Cc: <[email protected]>
Sent: Wednesday, April 24, 2002 12:54 AM
Subject: Re: Tracking Continued


> On Tue, 23 Apr 2002, Daniel Byer wrote:
>
> > Well, I finally finished my tracking code. So, I compiled it, ran into
> > some stupid little errors, fixed them, and finally got the code working.
> > Only to discover that the mud went in to a horrible, horrible crash (to
> > the best of my knowledge). The only feedback I got from the terminal was
> > "Bus error"
> >
> > Those are generally bad. :P
>
> I agree.  I haven't seen a good bus error in quite a while.
>
> > I'm going to post the relevant code/location, and the feedback I
> > received.
> >
> > In "void move_char( CHAR_DATA *ch, int door, bool follow )" in
> > "act_move.c", directly before "char_from_room( ch );" and "char_to_room
> > ( ch, to_room );"
> > /* TRACKING CODE. COMPLETE(?). */
> >      if ( do_track ) {
> >          send_to_char( "DO_TRACK IS TRUE\n\r", ch );
> >          if ( in_room->tracking ) {
>
> This should be a linked list search.  Just looking at the first entry will
> not work how you want if somebody else enters the room before you leave.
>
> >              if ( in_room->tracking->player == ch ) {
>
> Small gotcha here... Using a pointer to ch isn't gonna work correctly
> unless you go through and remove every track this character has when
> they exit the mud (fairly computationally expensive).
>
> >                  in_room->tracking->dir_to = door;
> >                  in_room->tracking->age = 0;
> >              }
> >              else {
> >                  if ( ( inTrack = alloc_mem( sizeof( TRACK_DATA ) ) ) !=
> > NULL ) {
> >                      inTrack->player = ch;
> >                      inTrack->age = 0;
> >                      inTrack->dir_to = door;
> >                      in_room->tracking->next = inTrack;
>
> Don't forget to set "inTrack->next = NULL;".  And you'll probably want
> to also initialize inTrack->dir_from to keep from getting weird results.
>
> I'd suggest moving half of this allocation/initialization code to it's
> own function, similar to all the new_XXX() in recycle.c.
>
> >                      send_to_char( "Allocated. First block.\n\r", ch );
> >                  }
> >              }
> >          }
> >          else {
> >              if ( ( inTrack = alloc_mem( sizeof( TRACK_DATA ) ) ) !=
> > NULL ) {
> >                  inTrack->player = ch;
> >                  inTrack->age = 0;
> >                  inTrack->dir_to = door;
> >                  in_room->tracking = inTrack;
> >                  send_to_char( "Allocated. Second block.\n\r", ch );
> >              }
> >          }
> >
> >          if ( to_room->tracking ) {
> >              if ( to_room->tracking->player == ch ) {
> >                  to_room->tracking->dir_from = rev_dir[door];
> >                  to_room->tracking->age = 0;
>
> Same comments about the linked list search apply here also.  This will
> not work as you want if somebody else enters the room before you enter
> it again.
>
> >              }
> >              else {
> >                  if ( ( toTrack = alloc_mem( sizeof( TRACK_DATA ) ) ) !=
> > NULL ) {
> >                      toTrack->player = ch;
> >                      toTrack->age = 0;
> >                      toTrack->dir_from = rev_dir[door];
> >                      to_room->tracking->next = toTrack;
> >                      send_to_char( "Allocated. Third block.\n\r", ch );
> >                  }
> >              }
> >          }
> >          else {
> >              if ( ( toTrack = alloc_mem( sizeof( TRACK_DATA ) ) ) !=
> > NULL ) {
> >                  toTrack->player = ch;
> >                  toTrack->age = 0;
> >                  toTrack->dir_from = rev_dir[door];
> >                  to_room->tracking = inTrack;
> >                  send_to_char( "Allocated. Fourth block.\n\r", ch );
> >              }
> >          }
> >
> >      }
> > /* END TRACKING CODE */
> >
> > do_track is just a bool to determine if the tracking code should be
> > executed. An example, is do_track will be false if ch is an immortal.
> > The "Allocated. X block" send_to_char()s are there just so I can walk
> > around and determine if things are supposedly working.
> >
> > the track_data struct, located in "merc.h":
> > /* BEGIN TRACK STRUCT */
> > struct track_data
> > {
> >      CHAR_DATA * player; /* player to pass through exit */
> >      sh_int age; /* age of tracks */
> >      sh_int dir_to; /* direction tracks go to */
> >      sh_int dir_from; /* direction tracks come from */
> >      TRACK_DATA * next; /* next tracking data, say, if another
> > player passes through exit */
> > };
> > /* END TRACK STRUCT */
> >
> > room_index_data contains a TRACK_DATA struct, with the name "tracking."
> >
> > In "void load_rooms( FILE *fp )" in "db.c", at very bottom, right before
> > "iHash = vnum % MAX_KEY_HASH;":
> > /* This is to initialize the tracking struct.. was causing funny things
> > to happen before I added this line */
> > pRoomIndex->tracking = NULL;
> > /* end */
> >
> > In "void reset_area( AREA_DATA *pArea )" in "db.c",  case 'R': directly
> > after the "for ( d0 = 0; d0 < pReset->arg2 - 1; d0++ )" loop finishes
> > (this code is located AFTER the loop, and AFTER the bracket directly
> > after it, thus past the if/else statement):
>
> Hmm.. I don't see the if/else statement you're referring to in stock code.
> Are you saying this code is inside case 'R'?  If so, it shouldn't be.
>
> > /*
> >      * This is the tracking reset code. Every PULSE_AREA, we
> > update/destroy the tracks
> > */
> > if ( pRoomIndex->tracking ) {
>
> This if is not necessary.  The for takes care of it.
>
> >      for ( ; !pRoomIndex->tracking; ) { /* I just saw this now.. should
I
> > not have the ! in there? */
>
> Correct.  The ! should not be there.
>
> This loop has quite a few problems.
> What if you don't delete the first track?  Then pRoomIndex->tracking
> will be true still (after you fix the loop and take out the !), and
> the loop will continue forever.  Actually, this applies to any entry
> you don't delete, after you have deleted everything in front of it.
>
> On the other hand, if you do delete the first track, it will try to
> free that same memory yet again (see the note below about resetting
> pRoomIndex->tracking to NULL to fix this).
>
> Now on to my biggest problem with the loop: It doesn't handle deleting
> the 2nd or 3rd or whatever entry without deleting the 1st.
>
> The loop should be much more complex to take care of iterating through
> the list and deleting entries out of it correctly.  The rest of the
> stuff in the loop looks good though.
>
> >          killTrack = FALSE;
> >          pRoomIndex->tracking->age += pRoomIndex->tracking->age;
>
> I don't understand what this line is doing.  Doubling the age?  Why?
> Didn't you set it to 0 before?  0 + 0 = 0.  Did you mean += 1 instead?
>
> >          switch ( pRoomIndex->sector_type ) {
> >          case 0: case 1:
> >              if ( pRoomIndex->tracking->age >= ( 3 * PULSE_AREA ) )
> >              {
> >                  killTrack = TRUE;
> >                  break;
> >              }
> >          case 2: case 4: case 5:
> >              if ( pRoomIndex->tracking->age >= ( 7 * PULSE_AREA ) )
> >              {
> >                  killTrack = TRUE;
> >                  break;
> >              }
> >          case 3:
> >              if ( pRoomIndex->tracking->age >= ( 15 * PULSE_AREA ) )
> >              {
> >                  killTrack = TRUE;
> >                  break;
> >              }
> >          case 10:
> >              if ( pRoomIndex->tracking->age >= ( 10 * PULSE_AREA ) )
> >              {
> >                  killTrack = TRUE;
> >                  break;
> >              }
> >          }
> >
> >          if ( killTrack )
> >          {
> >              if ( pRoomIndex->tracking->next ) {
> >                  if ( ( tmpTrack = alloc_mem( sizeof( *tmpTrack ) ) ) !=
> > NULL ) {
>
> Uhhh.. what's this????
>
> >                      tmpTrack = pRoomIndex->tracking->next;
>
> Oops.. Just lost the memory we allocated on the last line. (BAD THING!)
>
> >                      free_mem( pRoomIndex->tracking, sizeof
> > ( *pRoomIndex->tracking ) );
> >                      pRoomIndex->tracking = tmpTrack;
> >                  }
> >              }
> >              else {
> >                  free_mem( pRoomIndex->tracking, sizeof
> > ( *pRoomIndex->tracking ) );
>
> Forgot to set "pRoomIndex->tracking = NULL;"
>
> >              }
> >          }
> >      }
> > }
> > /* END */
>
> I don't know what would be causing the bus error, but try fixing
> some of this stuff and see if it helps.
>
>
> On a side note: This was a very good email.  A very detailed description
> of the problem and all the relevant code listed.  If only everyone
> who posted with problems could do this.
>
>
> Dennis
>
>
>
> --
> ROM mailing list
> [email protected]
> http://www.rom.org/cgi-bin/mailman/listinfo/rom


Reply via email to