Re: Newbie question--next_in_room

From: Gary Barnett (gbarnett@POLARNET.COM)
Date: 09/19/97


On Friday, September 19, 1997 10:12 AM, Justin
[SMTP:c616077@showme.missouri.edu] wrote:
> > > Does next_in_room ever equal NULL, or does it just wrap around to the
> > > first person/npc again?  I'm trying to find an example in the code
> > > where
> > > it goes through the occupants on a room one by one so that I can make a
> > > spell that hits a character at random.  Anyone know of a place in the
> > > code
>
> > Here's a piece of code to do that:
> >
> > struct char_data *vict, *next_v;
> >
> >   for (vict = world[ch->in_room].people; vict; vict = next_v) {
> >        next_v = vict->next_in_room;
> >        if (vict && (vict->in_room == ch->in_room)) {
> >         /* put your spell on vict here */
>
> Now, isn't this going to go through each and every char/npc in room except
> the caster?  I need it to just hit _one_ character/npc, at random, and
> then stop.  Like two mages fighting, one has previously cast "reflect
> electricity", and the other casts "call lightning".  It's going to bounce
> off the first mage's shield and possibly hit something else in the room,
> but not nesseccarily.  Will this work?  Looks like I need to add some
> checks for ch=vict...

Well, you have two choices.

1) Easier -- Just have a random check at each person in the loop and
    when it succeeds, bail out. Then you have to worry about not having
    selected everyone. I hate those kind of special checks.. so..

2) Harder - Run through the loop once and count how many targets you
    have. Then pick one at random, then run through the loop again until
    you reach the one you want. You could also create an array or linked
    list to hold the people in the room so you could pick directly, but that
    approach isn't indicated here, imho.

 int num_found=0, roll=0;

 for (vict = world[ch->in_room].people; vict; vict = vict->next_in_room)
    if (vict && (vict->in_room == ch->in_room) && (ch != vict))
        num_found++;
 if (!num_found) {
   send_to_char("Nobody around...\r\n",ch)
   return;
 }
 roll = number(1, x);

 for (vict = world[ch->in_room].people; vict; vict = next_v) {
       next_v = vict->next_in_room;
       if (vict && (vict->in_room == ch->in_room) && (ch != vict))
          roll--;
       if (!roll)
            /* gotcha -- apply spell here. */
 }

the (vict->in_room == ch->in_room) check is redundant. I use it because
I am paranoid :-)

If you are wanting objects to be the target as well you'd need another
loop through the objs in the room and a check to determine which one
got hit.

All in all, a good idea! Wish I was using magic, lots of cool stuff I miss
out on :-)

This is mailer code, so you might have to fiddle with it a bit.

--Mallory

I can picture in my mind a world without war, a world without hate.
And I can picture us attacking that world, because they'd never
expect it.     - Jack Handey


     +------------------------------------------------------------+
     | Ensure that you have read the CircleMUD Mailing List FAQ:  |
     | http://democracy.queensu.ca/~fletcher/Circle/list-faq.html |
     +------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 12/08/00 PST