Re: [CODE] perform_immort_invis bugfix

From: Andrey Fidrya (andrey@alex-ua.com)
Date: 02/19/00


>If you order all followers to do something that results in death of
>one follower (such as casting an offensive spell on itself or something),
>you can lose track of which mob you were up to in the "order
>followers" loop thing. This is fixed by getting the next follower before
>you make the current one execute the command, as I think Andrey's saying.

No. It's more complicated.
If you order all charmies to kill 2nd charmie and 1st charmie kills 2nd
charmie - MUD will crash because pointer to 2nd charmie is invalid.
The solution is (I posted it long time ago):

=== CUT ===
Here is my fix to do_order's crash bug:

When applying, add cloop_member variable to struct char_data in structs.h:
bool cloop_member;  /* For complicated loops handling */

Then paste in the following code:

ACMD(do_order)
{
[...]
    } else {   /* This is order "followers" */
      sprintf(buf, "$n issues the order '%s'.", message);
      act(buf, FALSE, ch, 0, 0, TO_ROOM); /* Zmey: replaced vict with 0 */

      org_room = ch->in_room; /* Pointer to ch can be lost later */

      for (vict = world[org_room].people; vict; vict = vict->next_in_room)
        if (vict->master == ch && AFF_FLAGGED(vict, AFF_CHARM)) {
          found = TRUE;
          /* Mark follower as complicated loop's member */
          vict->cloop_member = TRUE;
        } else {
          /* Otherwise, clear the mark */
          vict->cloop_member = FALSE;
        }

      if (found)
        send_to_char(OK, ch);
      else
        send_to_char("Nobody here is a loyal subject of yours!\r\n", ch);

      vict = world[org_room].people;
      while (vict) {
        if (vict->cloop_member) {
          vict->cloop_member = FALSE;
          command_interpreter(vict, message);
          /* Loop is broken now, start from beginning: */
          vict = world[org_room].people;
        } else
          vict = vict->next_in_room;
      }
    }
  }
}

Btw, currently few more functions have potential crash bugs of that
type. They can be rewritten using additional variable (cloop_member)
for vict's existence checking. The basic algorythm:
 1) Cycle through victims, mark them
 2) Cycle through victims, lookup marked ones and perform actions.
    After every action performed, resume at 1st member of list.
=== CUT ===

Andrey


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



This archive was generated by hypermail 2b30 : 04/10/01 PDT