[NOTE: This fix is not necessary if you are running AFKMud 1.4]
The previously posted memory leak fix for polymorph.c caused a crash bug. The following will correct this properly:
In polymorph.c, find:
#define KEY( literal, field, value )
if ( !str_cmp( word, literal ) )
{
field = value;
fMatch = TRUE;
break;
}
Under that, add:
#define MKEY( literal, field, value )
if( !str_cmp( word, literal ) )
{
if( field )
DISPOSE( field );
field = value;
fMatch = TRUE;
break;
}
Now find fread_morph further down, replace with the following:
/*
* Read in one morph structure
*/
MORPH_DATA *fread_morph ( FILE *fp )
{
MORPH_DATA *morph;
char *arg;
char temp[MAX_STRING_LENGTH];
char *word;
int i;
bool fMatch;
word = feof (fp) ? "End" : fread_word (fp);
if ( !str_cmp ( word, "End" ) )
return NULL;
CREATE ( morph, MORPH_DATA, 1 );
morph_defaults ( morph );
if( morph->name )
DISPOSE( morph->name );
morph->name = str_dup ( word );
for (;
{
word = feof (fp) ? "End" : fread_word (fp);
fMatch = FALSE;
switch (UPPER (word[0]))
{
case 'A':
KEY ( "Absorb", morph->absorb, fread_number( fp ) );
KEY ( "Armor", morph->ac, fread_number ( fp ) );
KEY ( "Affected", morph->affected_by, fread_bitvector( fp ) );
break;
case 'C':
KEY( "Charisma", morph->cha, fread_number ( fp ) );
if ( !str_cmp ( word, "Class" ) )
{
fMatch = TRUE;
arg = fread_string( fp );
while( arg[0] != '�' )
{
arg = one_argument( arg, temp );
for ( i=0; i who_name ) )
{
SET_BIT( morph->class, (1 <con, fread_number ( fp ) );
if ( !str_cmp ( word, "CastAllowed" ) )
{
fMatch = TRUE;
morph->cast_allowed = fread_number( fp );
}
break;
case 'D':
MKEY( "Damroll", morph->damroll, fread_string_nohash(fp));
KEY( "DayFrom", morph->dayfrom, fread_number( fp ) );
KEY( "DayTo", morph->dayto, fread_number( fp ) );
KEY( "Defpos", morph->defpos, fread_number( fp ) );
MKEY( "Description",morph->description,fread_string_nohash(fp));
KEY( "Dexterity", morph->dex, fread_number ( fp ) );
KEY( "Dodge", morph->dodge, fread_number( fp ) );
break;
case 'E':
if (!str_cmp (word, "End"
)
return morph;
break;
case 'F':
KEY( "FavourUsed", morph->favourused, fread_number( fp ) );
break;
case 'H':
MKEY( "Help", morph->help, fread_string_nohash(fp));
MKEY( "Hit", morph->hit, fread_string_nohash(fp));
MKEY( "Hitroll", morph->hitroll, fread_string_nohash(fp));
KEY( "HpUsed", morph->hpused, fread_number( fp ) );
break;
case 'I':
KEY( "Intelligence", morph->inte, fread_number( fp ) );
KEY( "Immune", morph->immune, fread_number( fp ) );
break;
case 'K':
MKEY( "Keywords", morph->key_words, fread_string_nohash(fp));
break;
case 'L':
KEY( "Level", morph->level, fread_number ( fp ) );
MKEY( "Longdesc", morph->long_desc, fread_string_nohash(fp));
KEY( "Luck", morph->lck, fread_number( fp ) );
break;
case 'M':
MKEY( "Mana", morph->mana, fread_string_nohash(fp));
KEY( "ManaUsed", morph->manaused, fread_number( fp ) );
MKEY( "MorphOther", morph->morph_other,fread_string_nohash(fp));
MKEY( "MorphSelf", morph->morph_self, fread_string_nohash(fp));
MKEY( "Move", morph->morph_self, fread_string_nohash(fp));
KEY( "MoveUsed", morph->moveused, fread_number( fp ) );
break;
case 'N':
KEY( "NoAffected", morph->no_affected_by, fread_bitvector(fp));
KEY( "NoImmune", morph->no_immune, fread_number( fp ) );
KEY( "NoResistant", morph->no_resistant, fread_number(fp));
MKEY( "NoSkills", morph->no_skills, fread_string_nohash(fp));
KEY( "NoSuscept", morph->no_suscept, fread_number(fp));
if ( !str_cmp ( word, "NoCast" ) )
{
fMatch = TRUE;
morph->no_cast = fread_number( fp );
}
break;
case 'O':
if ( !str_cmp( word, "Objs" ) )
{
fMatch = TRUE;
morph->obj[0] = fread_number( fp );
morph->obj[1] = fread_number( fp );
morph->obj[2] = fread_number( fp );
}
if ( !str_cmp( word, "Objuse" ) )
{
fMatch = TRUE;
morph->objuse[0] = fread_number( fp );
morph->objuse[1] = fread_number( fp );
morph->objuse[2] = fread_number( fp );
}
break;
case 'P':
KEY( "Parry", morph->parry, fread_number( fp ) );
KEY( "Pkill", morph->pkill, fread_number( fp ) );
break;
case 'R':
if ( !str_cmp ( word, "Race" ) )
{
fMatch = TRUE;
arg = fread_string_nohash ( fp );
arg = one_argument( arg, temp );
while ( temp[0] != '�' )
{
for ( i=0; i race_name ) )
{
SET_BIT( morph->race, (1 <resistant, fread_number( fp ) );
break;
case 'S':
KEY("SaveBreath", morph->saving_breath, fread_number( fp ) );
KEY("SavePara", morph->saving_para_petri, fread_number( fp ) );
KEY("SavePoison", morph->saving_poison_death,fread_number(fp));
KEY("SaveSpell", morph->saving_spell_staff, fread_number(fp));
KEY("SaveWand", morph->saving_wand, fread_number(fp));
KEY("Sex", morph->sex, fread_number( fp ) );
MKEY("ShortDesc",morph->short_desc, fread_string_nohash(fp));
MKEY("Skills", morph->skills, fread_string_nohash(fp));
KEY("Strength", morph->str, fread_number( fp ) );
KEY("Suscept", morph->suscept, fread_number( fp ) );
break;
case 'T':
KEY("Timer", morph->timer, fread_number( fp ) );
KEY("TimeFrom", morph->timefrom, fread_number( fp ) );
KEY("TimeTo", morph->timeto, fread_number( fp ) );
KEY("Tumble", morph->tumble, fread_number( fp ) );
break;
case 'U':
MKEY("UnmorphOther",morph->unmorph_other,fread_string_nohash(fp));
MKEY("UnmorphSelf",morph->unmorph_self,fread_string_nohash(fp));
KEY("Used", morph->used, fread_number( fp ) );
break;
case 'V':
KEY("Vnum", morph->vnum, fread_number( fp ) );
break;
case 'W':
KEY("Wisdom", morph->wis, fread_number( fp ) );
break;
}
if (!fMatch)
{
bug( "Fread_morph: no match: %s", word );
/* Bailing out on this morph as something may be messed up
* this is going to have lots of bugs from the load_morphs this
* way, but it is better than possibly having the memory messed
* up! --Shaddai
*/
free_morph( morph );
return NULL;
}
}
}