Re: [CODE]Game crashes when any mob is killed

From: Jared Buckley (jaredb@ti.com)
Date: 12/15/98


Posted this a while back, but here it is again for posterity...

------------------------------------------------------------------

I figure most people who've already installed dg-scripts pl5a have found
this one, since you really can't run the MUD unless you fix it.  But for
the archives here it is anyway:

------------------------------------------------------------------

Environment:

Win95 OSR2, MSVC++ 5.0, circle30bpl14, dg_scripts pl5a

Description:

Base Circle 3.0 patch level 14 with dg scripts pl5a installed crashes
when a mob is killed in the normal course of battle with a mortal.

Action:

Debug on source shows a memory exception in hitprcnt_mtrigger() in
dg_triggers.c at line:

if (!SCRIPT_CHECK(ch, MTRIG_HITPRCNT) || !FIGHTING(ch) ||
AFF_FLAGGED(ch, AFF_CHARM))

Analysis of the variable ch shows it to be undefined/filled with
garbage.  hitprcnt_trigger() is called in only one place in the source
code; at the end of hit().

Solution:

Since hitprcnt_mtrigger() is called in only one place and passed only
one variable, ch, the variable must be getting set to null somewhere
before the end of hit.  Turns out the problem is in damage() (also in
fight.c) when the victim dies, he/she/it is extracted from the game
resulting in a screwed up/null pointer.

Put in a sanity check before hitprcnt_mtrigger() to make sure we
don't call it for non-existing mobs:

add vict_dmg to the int's defined in hit() in fight.c:
   int w_type, victim_ac, calc_thaco, dam, diceroll, vict_dmg;

change the last 5 lines of hit() in fight.c from:

if (type == SKILL_BACKSTAB) {
  dam *= backstab_mult(GET_LEVEL(ch));
  damage(ch, victim, dam, SKILL_BACKSTAB);
  }
 else
  damage(ch, victim, dam, w_type);}

/* check if the victim has a hitprcnt trigger */
hitprcnt_mtrigger(victim);

to:

if (type == SKILL_BACKSTAB) {
  dam *= backstab_mult(GET_LEVEL(ch));
  vict_dmg = damage(ch, victim, dam, SKILL_BACKSTAB);
  }
 else
  vict_dmg = damage(ch, victim, dam, w_type);}

/* check if the victim has a hitprcnt trigger */
if (vict_dmg != -1)
  hitprcnt_mtrigger(victim);

Why?  Because damage returns a -1 when the victim dies.  This check then
helps us avoid calling hitprcnt_mtrigger() for a null pointer.


     +------------------------------------------------------------+
     | 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 : 12/15/00 PST