Druid's Bugfix List
This is an archived copy of the bugfix list found at:
http://legacy.sheltonbbs.com/~rhaas/pirate/files/smbugs.txt
which is no longer in existence. The information is now preserved here.
Disclaimer: I invite you to use your own judgement, and not take anything here as gosphel. I make errors just like everyone else, I try to the best of my abilities to make sure anything I disperse is correct, but there will always be that one time... -Druid PirateMud *** Desc: Possible playerfile modification via bestowarea and bestow. File: act_wiz.c Function: do_bestowarea() Around line: 5212 After: DISPOSE( victim->pcdata->bestowments ); Add: smash_tilde( buf ); Function: do_bestow() Around line: 5269 After: DISPOSE( victim->pcdata->bestowments ); Add: smash_tilde( buf ); *** Desc: The 'amount' of water is always the same regardless of the precipitation present due to checking the pointer and not checking the precipation value. File: magic.c Function: create_water() Around line: 2348 Change: water = UMIN( level * ( weath >= 0 ? 4 : 2 ), obj->value[0] - obj->value[1] ); To: water = UMIN( level * ( weath->precip >= 0 ? 4 : 2 ), obj->value[0] - obj->value[1] ); *** Desc: Ignores working improperly Notes: Rustry (rustry@dxcc.com) of SmaugWiz helped with the fix. File: interp.c function: check_social Around line 615 Change: CHAR_DATA *victim; To: CHAR_DATA *victim, *victim_next; Around line 617 Remove: CHAR_DATA *remfirst, *remlast, *remtemp; /* for ignore cmnd */ Replace with: CHAR_DATA *removed[128]; /* What are the chances of more than 128? */ ROOM_INDEX_DATA *room; int i = 0, k = 0; Around line:655 Remove: remfirst = NULL; remlast = NULL; remtemp = NULL; Around line 665 change: for(victim = ch->in_room->first_person; victim; victim = victim->next_in_room) { if(is_ignoring(victim, ch)) To: room = ch->in_room; for( victim = ch->in_room->first_person; victim; victim = victim_next ) { if( i == 127 ) /* No more than 128 in array */ break; victim_next = victim->next_in_room; if (is_ignoring (victim, ch)) Around line: 675 Remove: char_from_room( victim ); LINK( victim, remfirst, remlast, next_in_room, prev_in_room ); Replace with: removed[i] = victim; i++; UNLINK( victim, room->first_person, room->last_person, next_in_room, prev_in_room ); Around line: 693 Change: else if( ( victim = get_char_room( ch, arg ) ) == NULL ) To: else if( ( ( victim = get_char_room( ch, arg ) ) == NULL ) || str_cmp( victim->name, arg ) ) Around line: 701 Change: for( victim = remfirst; victim; victim = victim->next_in_room ) To: if( i != 0 ) for( k = 0, victim = removed[0]; k < i; k++, victim = removed[k] ) Around line: 781 Remove: for( victim = remfirst; victim; victim = remtemp ) { remtemp = victim->next_in_room; char_to_room( victim, ch->in_room ); } Replace with: if( i != 0 ) for( k = 0, victim = removed[0]; k < i; k++, victim = removed[k] ) { LINK( victim, room->first_person, room->last_person, next_in_room, prev_in_room ); } *** Mon Aug 26 10:41:29 AM CDT 2002 ddruidDesc: do_reply doesn't trigger speech progs File: act_comm.c Function: do_reply Around line: 1436 After: victim->pcdata->tell_history[victim->pcdata->lt_index] = STRALLOC( buf ); } Add: mprog_speech_trigger( argument, ch ); *** Mon Aug 26 10:41:44 AM CDT 2002 ddruid Desc: It is possible to defeat examine progs on objects by looking at them with 'noprog' as an argument. For example the painting in the donation room wont transfer you to the graveyard if you do a 'look painting noprog'. File: act_info.c Somewhere near the top, I put it under the includes. Add: /* * Keep players from defeating examine progs -Druid * False = do not trigger * True = Trigger */ bool EXA_prog_trigger = TRUE; Function: do_look Around line: 987 Remove: bool doexaprog; Around line: 1023 Remove: doexaprog = str_cmp( "noprog", arg2 ) && str_cmp( "noprog", arg3 ); Be sure to change all these Around lines: 1088, 1122, 1132, 1178, 1285, 1295, 1310, 1326, 1336, 1351 Change: if( doexaprog ) To: if( EXA_prog_trigger ) Function: do_examine Around line: 1572 Replace: sprintf( buf, "%s noprog", arg ); do_look( ch, buf ); With: EXA_prog_trigger = FALSE; do_look( ch, arg ); EXA_prog_trigger = TRUE; Around line: 1773 Replace: sprintf( buf, "in %s noprog", arg ); do_look( ch, buf ); With: EXA_prog_trigger = FALSE; sprintf( buf, "in %s",arg ); do_look( ch, buf ); EXA_prog_trigger = TRUE; Around line: 1783 Replace: sprintf( buf, "under %s", arg ); do_look( ch, buf ); With: EXA_prog_trigger = FALSE; sprintf( buf, "under %s", arg ); do_look( ch, buf ); EXA_prog_trigger = TRUE; *** Mon Aug 26 10:41:58 AM CDT 2002 ddruid Desc: A memory leak occurs when one prog sets off another prog of the same type (mob -> mob). The problem lies in the fact that the head of the singly linked list *_act_list is changed twice within the execution. The fix appends to the list rather than prepending. Luckily the list is small so appending isn't a loss, perhaps someone has a better idea? A condensed tree of events (mob prog example): (mob prog being parsed) aggr_update(): apdtmp = mob_act_list = 0x84ec710 mprog_wordlist_check() mprog_driver() mprog_do_command() interpret() check_social() act() <-- another mobs prog is triggered mprog_act_trigger() mob_act_add(): mob_act_list = runner = 0x84ec760 aggr_update(): mob_act_list = apdtmp->next = NULL *0x84ec760 Leaked To recreate: Force moretta to smile at gemma File: mud_prog.c Function: mob_act_add Around line: 2400 Remove the entire mob_act_add() function. Replace with: void mob_act_add( CHAR_DATA *mob ) { struct act_prog_data *runner, *tmp_mal; for( runner = mob_act_list; runner; runner = runner->next ) if( runner->vo == mob ) return; CREATE( runner, struct act_prog_data, 1 ); runner->vo = mob; runner->next = NULL; /* * The head of the list is being changed in * aggr_update, So append to the end of the list * instead. -Druid */ if( mob_act_list ) { tmp_mal = mob_act_list; while( tmp_mal->next != NULL ) tmp_mal = tmp_mal->next; /* put at the end */ tmp_mal->next = runner; } else mob_act_list = runner; } Function: room_act_add Around line: 3409 Completely remove the room_act_add() function Replace With: void room_act_add( ROOM_INDEX_DATA *room ) { struct act_prog_data *runner, *tmp_ral; for( runner = room_act_list; runner; runner = runner->next ) if( runner->vo == room ) return; CREATE( runner, struct act_prog_data, 1 ); runner->vo = room; runner->next = NULL; /* * The head of the list is being changed in * room_act_update, So append to the end of the list * instead. -Druid */ if( room_act_list ) { tmp_ral = room_act_list; while( tmp_ral->next != NULL ) tmp_ral = tmp_ral->next; /* put at the end */ tmp_ral->next = runner; } else room_act_list = runner; } Function: obj_act_add Around line: 3464 Completely remove the obj_act_add() function Replace with: void obj_act_add( OBJ_DATA *obj ) { struct act_prog_data *runner, *tmp_oal; for( runner = obj_act_list; runner; runner = runner->next ) if( runner->vo == obj ) return; CREATE( runner, struct act_prog_data, 1 ); runner->vo = obj; runner->next = NULL; /* * The head of the list is being changed in * obj_act_update, So append to the end of the list * instead. -Druid */ if( obj_act_list ) { tmp_oal = obj_act_list; while( tmp_oal->next != NULL ) tmp_oal = tmp_oal->next; /* put at the end */ tmp_oal->next = runner; } else obj_act_list = runner; } *** Mon Aug 26 10:45:05 AM CDT 2002 ddruid Desc: save_clan & save_council format string bug File: clans.c Function: save_clan Around line: 107 After: char filename[256]; Remove: char buf[MAX_STRING_LENGTH]; A few lines down Remove: sprintf( buf, "save_clan: %s has no filename", clan->name ); bug( buf, 0 ); Replace with: bug( "save_clan: %s has no filename", clan->name ); save_council is identical *** Tue Aug 27 09:13:56 PM CDT 2002 ddruid Desc: race_name never free'd File: tables.c Function: load_race_file Around line: 2835 After: bug( "Load_race_ Race (%s) bad/not found (%d)", race->race_name ? race->race_name : "name not found", ra ); Add: if( race_name ) STRFREE( race_name ); Around line: 2841 After: race_table[ra] = race; Add: if( race_name ) STRFREE( race_name ); *** Wed Aug 28 09:17:55 AM CDT 2002 ddruid Desc: Much like the previous prog leak, except that the mpact pointer is being lost. To recreate: Have an Imm sit in room 10399, using a medium level char kill the gnoll cage mobs until the pixie prog executes. File: mud_prog.c Function: mprog_act_trigger() Around line: 2441 Change: MPROG_ACT_LIST *tmp_act; To: MPROG_ACT_LIST *tmp_act, *tmp_mal; Around line: 2468 Remove: if( mob->mpactnum > 0 ) tmp_act->next = mob->mpact; else tmp_act->next = NULL; mob->mpact = tmp_act; mob->mpact->buf = str_dup( buf ); mob->mpact->ch = ch; mob->mpact->obj = obj; mob->mpact->vo = vo; mob->mpactnum++; mob_act_add( mob ); Replace with: /* * Losing the head of the list -Druid */ if( mob->mpactnum > 0 ) { tmp_mal = mob->mpact; while( tmp_mal->next != NULL ) tmp_mal = tmp_mal->next; /* Put at the end */ tmp_mal->next = tmp_act; } else mob->mpact = tmp_act; tmp_act->next = NULL; tmp_act->buf = str_dup( buf ); tmp_act->ch = ch; tmp_act->obj = obj; tmp_act->vo = vo; mob->mpactnum++; mob_act_add( mob ); Function: oprog_act_trigger() Around line: 3036 Change: MPROG_ACT_LIST *tmp_act; To: MPROG_ACT_LIST *tmp_act, *tmp_mal; Around line: 3040 Remove: if( mobj->mpactnum > 0 ) tmp_act->next = mobj->mpact; else tmp_act->next = NULL; mobj->mpact = tmp_act; mobj->mpact->buf = str_dup( buf ); mobj->mpact->ch = ch; mobj->mpact->obj = obj; mobj->mpact->vo = vo; mobj->mpactnum++; obj_act_add( mobj ); Replace with: /* * Losing the head of the list -Druid */ if( mobj->mpactnum > 0 ) { tmp_mal = mobj->mpact; while( tmp_mal->next != NULL ) tmp_mal = tmp_mal->next; /* Put at the end */ tmp_mal->next = tmp_act; } else mobj->mpact = tmp_act; tmp_act->next = NULL; tmp_act->buf = str_dup( buf ); tmp_act->ch = ch; tmp_act->obj = obj; tmp_act->vo = vo; mobj->mpactnum++; obj_act_add( mobj ); Function: rprog_act_trigger() Around line: 3205 Change: MPROG_ACT_LIST *tmp_act; To: MPROG_ACT_LIST *tmp_act, *tmp_mal; Around line: 3209 Remove: if( room->mpactnum > 0 ) tmp_act->next = room->mpact; else tmp_act->next = NULL; room->mpact = tmp_act; room->mpact->buf = str_dup( buf ); room->mpact->ch = ch; room->mpact->obj = obj; room->mpact->vo = vo; room->mpactnum++; room_act_add( room ); Replace with: /* * Losing the head of the list -Druid */ if( room->mpactnum > 0 ) { tmp_mal = room->mpact; while( tmp_mal->next != NULL ) tmp_mal = tmp_mal->next; /* Put at the end */ tmp_mal->next = tmp_act; } else room->mpact = tmp_act; tmp_act->next = NULL; tmp_act->buf = str_dup( buf ); tmp_act->ch = ch; tmp_act->obj = obj; tmp_act->vo = vo; room->mpactnum++; room_act_add( room ); *** Tue Sep 03 02:15:11 PM CDT 2002 ddruid Desc: temp is never free'd File: save.c Function: fread_char() Around line: 1205 After: if( lstat( fname, &fst ) == -1 ) { Add: if( temp ) STRFREE( temp ); Around line: 1239 After: LINK( inode, ch->pcdata->first_ignored, ch->pcdata->last_ignored, next, prev ); } Add: if( temp ) STRFREE( temp ); *** Tue Sep 17 11:47:12 AM CDT 2002 ddruid Desc: Advance (demotion of imm) not removing holylight or bestowments. File: act_wiz.c Function: do_advance() Around line: 3209 Change: if( victim->level <= LEVEL_AVATAR && IS_IMMORTAL( victim ) ) To: if( victim->level >= LEVEL_AVATAR && IS_IMMORTAL( victim ) ) *** Tue Sep 17 12:28:21 PM CDT 2002 ddruid Based off bug reported by Mage for Rom, his still contained a bug though. Desc: 2 bugs really, The first is that only one characters equipment is being checked for alignment problems rather than the entire group. Second, if a char dies from a zap_prog the loop is terminated prematurely. File: fight.c Function: group_gain() Around line: 3464 Change: CHAR_DATA *gch; To: CHAR_DATA *gch, *gch_next; Around line: 3491 Change: for( gch = ch->in_room->first_person; gch; gch = gch->next_in_room ) { OBJ_DATA *obj; OBJ_DATA *obj_next; To: for( gch = ch->in_room->first_person; gch; gch = gch_next ) { OBJ_DATA *obj; OBJ_DATA *obj_next; gch_next = gch->next_in_room; Around line: 3519 Change: for( obj = ch->first_carrying; obj; obj = obj_next ) { obj_next = obj->next_content; if( obj->wear_loc == WEAR_NONE ) continue; if( ( IS_OBJ_STAT( obj, ITEM_ANTI_EVIL ) && IS_EVIL( ch ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_GOOD ) && IS_GOOD( ch ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_NEUTRAL ) && IS_NEUTRAL( ch ) ) ) { act( AT_MAGIC, "You are zapped by $p.", ch, obj, NULL, TO_CHAR ); act( AT_MAGIC, "$n is zapped by $p.", ch, obj, NULL, TO_ROOM ); obj_from_char( obj ); obj = obj_to_room( obj, ch->in_room ); oprog_zap_trigger( ch, obj ); /* mudprogs */ if( char_died( ch ) ) return; To: for( obj = gch->first_carrying; obj; obj = obj_next ) { obj_next = obj->next_content; if( obj->wear_loc == WEAR_NONE ) continue; if( ( IS_OBJ_STAT( obj, ITEM_ANTI_EVIL ) && IS_EVIL( gch ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_GOOD ) && IS_GOOD( gch ) ) || ( IS_OBJ_STAT( obj, ITEM_ANTI_NEUTRAL ) && IS_NEUTRAL( gch ) ) ) { act( AT_MAGIC, "You are zapped by $p.", gch, obj, NULL, TO_CHAR ); act( AT_MAGIC, "$n is zapped by $p.", gch, obj, NULL, TO_ROOM ); obj_from_char( obj ); obj = obj_to_room( obj, gch->in_room ); oprog_zap_trigger( gch, obj ); /* mudprogs */ if( char_died( gch ) ) break; *** Thu Sep 19 02:36:10 PM CDT 2002 ddruid Desc: Memory Leak (sort of) when new player created due to double alocation comm.c Function: nanny() Around line: 2130 Remove: ch->pcdata->clan_name = STRALLOC( "" ); Around line: 2249 Remove: /* * Display_prompt interprets blank as default */ ch->pcdata->prompt = STRALLOC( "" ); ***