#include "ctype.h" #include "sys/types.h" #include "stdio.h" #include "stdlib.h" #include "define.h" #include "struct.h" /* * CONSTANTS */ const char* rsflags_mob [] = { "Leader", "Follower", "Sentinel", "Night", "Day", "Aggressive", "" }; const char* rsflags_obj [] = { "Container", "Inside", "Unknown", "Unused1", "Unused2", "" }; const char* reset_pos_name [] = { "sleeping", "meditating", "resting", "standing" }; const char* reset_pos_abbrev [] = { "Slee", "Medi", "Rest", "Stan" }; const int rspos_index [] = { POS_SLEEPING, POS_MEDITATING, POS_RESTING, POS_STANDING }; /* * LOCAL FUNCTIONS */ void extract ( reset_data* ); char* set_rsflags ( char_data*, reset_data*, char* ); void display ( char_data*, reset_data*, int ); void modify_reset ( char_data*, reset_data*, char* ); void rowhere_key ( char_data*, obj_clss_data* ); void register_reset ( char_data*, room_data* ); obj_data* create ( obj_clss_data*, reset_data*, mob_data* ); void mob_setup ( mob_data*, room_data* ); void place ( obj_data*, reset_data*, room_data*, mob_data*, obj_data*& ); void reset_mob ( reset_data*, room_data*, mob_data*&, char_data*& ); void reset_obj ( reset_data*, room_data*, mob_data*, obj_data*& ); void reset_table ( reset_data*, int, room_data*, mob_data*, obj_data*& ); int rtable_calls; /* * RESET_DATA CLASS */ Reset_Data :: Reset_Data( ) { record_new( sizeof( reset_data ), MEM_RESET ); next = NULL; chances = ( 100 + ( 90 << 24 ) ); vnum = 0; flags = ( 1 << RSFLAG_REROLL ); count = 0; liquid = 0; return; } Reset_Data :: ~Reset_Data( ) { record_delete( sizeof( reset_data ), MEM_RESET ); return; } /* * SUPPORT ROUTINES */ void extract( reset_data* reset ) { for( int i = 0; i < mob_list; i++ ) if( mob_list[i]->reset == reset ) mob_list[i]->reset = NULL; delete reset; } char* name( reset_data* reset ) { if( reset == NULL ) return "none"; return "somewhere"; } /* * ONLINE EDITING COMMAND */ void do_reset( char_data* ch, char* argument ) { room_data* room; wizard_data* wizard; wizard = (wizard_data*) ch; if( !strcasecmp( argument, "room" ) ) { reset_room( ch->in_room ); send( ch, "Room reset.\n\r" ); return; } if( !strcasecmp( argument, "area" ) ) { for( room = ch->in_room->area->room_first; room != NULL; room = room->next ) reset_room( room ); send( ch, "Area reset.\n\r" ); return; } edit_reset( ch, argument, ch->in_room->reset, RST_ROOM ); } void do_mreset( char_data* ch, char* argument ) { species_data* species; wizard_data* wizard; wizard = (wizard_data*) ch; if( ( species = wizard->mob_edit ) == NULL ) { send( ch, "You aren't editing any mob.\n\r" ); return; } edit_reset( ch, argument, species->reset, RST_MOB ); } void edit_reset( char_data* ch, char* argument, reset_data*& list, int type, const char* name ) { reset_data* reset; reset_data* prev; int i, j; if( *argument == '\0' ) { if( name != empty_string ) { page_centered( ch, "-=- %s -=-", name ); page( ch, "\n\r" ); } display( ch, list, type ); return; } if( type == RST_ROOM ) ch->in_room->area->modified = TRUE; if( number_arg( argument, i ) ) { if( *argument == '\0' ) { send( ch, "What flag or option do you want to set?\n\r" ); return; } if( ( reset = locate( list, i ) ) == NULL ) { send( ch, "No reset exists with that number.\n\r" ); return; } if( isdigit( *argument ) && number_arg( argument, j ) ) { if( j == i ) { send( ch, "Moving a reset to where it already is does nothing\ interesting.\n\r" ); return; } if( j == 1 ) { remove( list, reset ); reset->next = list; list = reset; } else { if( j < 1 || j > count( list ) ) { send( ch, "You can only move a reset to a sensible position.\n\r" ); return; } remove( list, reset ); prev = locate( list, j-1 ); reset->next = prev->next; prev->next = reset; } send( ch, "Reset %d moved to position %d.\n\r", i, j ); return; } argument = set_rsflags( ch, reset, argument ); modify_reset( ch, reset, argument ); return; } if( matches( argument, "delete" ) ) { if( list == NULL ) { send( ch, "The list of resets is empty.\n\r" ); return; } if( !strcasecmp( argument, "all" ) ) { for( reset = list; reset != NULL; reset = list ) { list = list->next; extract( reset ); } send( ch, "All resets deleted.\n\r" ); return; } if( ( reset = locate( list, atoi( argument ) ) ) == NULL ) { send( ch, "No reset with that number found to delete.\n\r" ); return; } send( ch, "Reset deleted.\n\r" ); remove( list, reset ); extract( reset ); return; } if( matches( argument, "table" ) ) { if( *argument == '\0' ) { send( ch, "What rtable do you wish to reset?\n\r" ); return; } if( number_arg( argument, i ) ) { if( --i < 0 || i >= num_rtable ) { send( ch, "No rtable exists with that index.\n\r" ); return; } } else { for( i = 0; !matches( argument, rtable_list[i]->name ); ) { if( ++i >= num_rtable ) { send( ch, "No such rtable exists.\n\r" ); return; } } } send( ch, "Reset for rtable %d '%s' added.\n\r", i+1, rtable_list[i]->name ); reset = new reset_data; reset->vnum = i; reset->flags = 0; reset->value = 0; append( list, reset ); return; } thing_data* thing; mob_data* npc; obj_data* obj; if( ( thing = one_thing( ch, argument, "reset", ch->array, &ch->contents ) ) == NULL ) return; if( ( npc = mob( thing ) ) != NULL ) { if( type != RST_ROOM ) { send( ch, "You can't reset a mob on a mob or in a table.\n\r" ); return; } reset = new reset_data; reset->vnum = npc->species->vnum; reset->flags = ( 1 << RSFLAG_MOB ) | ( 1 << RSFLAG_REROLL ); reset->value = RSPOS_STANDING; append( list, reset ); send( ch, "Reset for %s added.\n\r", npc ); return; } if( ( obj = object( thing ) ) != NULL ) { reset = new reset_data; reset->vnum = obj->pIndexData->vnum; reset->flags = ( 1 << RSFLAG_OBJECT ) | ( 1 << RSFLAG_REROLL ); reset->value = -2; append( list, reset ); send( ch, "Reset for %s added.\n\r", obj ); return; } send( ch, "You can't reset %s.\n\r", thing ); } void display( char_data* ch, reset_data* reset, int type ) { char buf [ TWO_LINES ]; char flags [ 32 ]; char liquid [ 32 ]; char rust [ 5 ]; int* chances; int i, j, k; obj_clss_data* obj_clss; species_data* species; if( reset == NULL ) { send( ch, "No resets found.\n\r" ); return; } page_underlined( ch, "Nmbr Rrl 1_Ch 2_Ch 3_Ch Rust %sLiq Flags Vnum Descr\n\r", type == RST_TABLE ? "" : "Posi " ); for( i = 1; reset != NULL; i++, reset = reset->next ) { chances = unpack_int( reset->chances ); if( is_set( &reset->flags, RSFLAG_OBJECT ) ) { obj_clss = get_obj_index( reset->vnum ); for( k = 0, j = RSFLAG_LEADER; j < MAX_RSFLAG; j++ ) { if( is_set( &reset->flags, j ) ) flags[k++] = rsflags_obj[ j-RSFLAG_LEADER ][0]; } flags[k] = '\0'; sprintf( liquid, ( obj_clss != NULL && ( obj_clss->item_type == ITEM_DRINK_CON || obj_clss->item_type == ITEM_FOUNTAIN ) ) ? liquid_table[reset->liquid].name : " " ); liquid[3] = '\0'; if( obj_clss->metal( ) && !is_set( obj_clss->extra_flags, OFLAG_RUST_PROOF ) ) sprintf( rust, "%3d%%", chances[3] ); else sprintf( rust, " " ); if( type == RST_TABLE ) sprintf( buf, "[%2d] %c%c%c %3d%% %3d%% %3d%% %s %s %-5s %4d %s\n\r", i, is_set( &reset->flags, RSFLAG_REROLL ) ? '*' : ' ', is_set( &reset->flags, RSFLAG_REROLL+1 ) ? '*' : ' ', is_set( &reset->flags, RSFLAG_REROLL+2 ) ? '*' : ' ', chances[0], chances[1], chances[2], rust, liquid, flags, reset->vnum, truncate( name_brief( obj_clss ), 29 ) ); else sprintf( buf, "[%2d] %c%c%c %3d%% %3d%% %3d%% %s %s %s %-5s %4d %s\n\r", i, is_set( &reset->flags, RSFLAG_REROLL ) ? '*' : ' ', is_set( &reset->flags, RSFLAG_REROLL+1 ) ? '*' : ' ', is_set( &reset->flags, RSFLAG_REROLL+2 ) ? '*' : ' ', chances[0], chances[1], chances[2], rust, wear_abbrev[ reset->value+2 ], liquid, flags, reset->vnum, truncate( name_brief( obj_clss ), 29 ) ); } else if( is_set( &reset->flags, RSFLAG_MOB ) ) { species = get_species( reset->vnum ); for( k = 0, j = RSFLAG_LEADER; j < MAX_RSFLAG; j++ ) { if( is_set( &reset->flags, j ) ) flags[k++] = rsflags_mob[ j-RSFLAG_LEADER ][0]; } flags[k] = '\0'; sprintf( buf, "[%2d] %c%c%c %3d%% %3d%% %3d%% %s %-5s %4d %s\n\r", i, is_set( &reset->flags, RSFLAG_REROLL ) ? '*' : ' ', is_set( &reset->flags, RSFLAG_REROLL+1 ) ? '*' : ' ', is_set( &reset->flags, RSFLAG_REROLL+2 ) ? '*' : ' ', chances[0], chances[1], chances[2], reset_pos_abbrev[ reset->value ], flags, reset->vnum, species == NULL ? "## Null Pointer?? ##" : species->Name( ) ); } else { *flags = '\0'; if( type == RST_TABLE ) sprintf( buf, "[%2d] %c%c%c %3d%% %3d%% %3d%% %-5s TBL %s\n\r", i, is_set( &reset->flags, RSFLAG_REROLL ) ? '*' : ' ', is_set( &reset->flags, RSFLAG_REROLL+1 ) ? '*' : ' ', is_set( &reset->flags, RSFLAG_REROLL+2 ) ? '*' : ' ', chances[0], chances[1], chances[2], flags, truncate( rtable_list[reset->vnum]->name, 29 ) ); else sprintf( buf, "[%2d] %c%c%c %3d%% %3d%% %3d%% %s %-5s TBL %s\n\r", i, is_set( &reset->flags, RSFLAG_REROLL ) ? '*' : ' ', is_set( &reset->flags, RSFLAG_REROLL+1 ) ? '*' : ' ', is_set( &reset->flags, RSFLAG_REROLL+2 ) ? '*' : ' ', chances[0], chances[1], chances[2], wear_abbrev[reset->value+2], flags, truncate( rtable_list[reset->vnum]->name, 29 ) ); } page( ch, buf ); } } char* set_rsflags( char_data* ch, reset_data* reset, char* argument ) { bool set; int i; const char** flags; flags = ( is_set( &reset->flags, RSFLAG_MOB ) ? rsflags_mob : rsflags_obj ); for( ; ; ) { if( *argument != '+' && *argument != '-' ) return argument; set = ( *argument++ == '+' ); for( ; *argument != '\0' && *argument != ' '; argument++ ) { for( i = 0; flags[i][0] != '\0'; i++ ) if( toupper( *argument ) == flags[i][0] ) { assign_bit( &reset->flags, RSFLAG_LEADER+i, set ); send( ch, "%s flag set %s.\n\r", flags[i], true_false( &reset->flags, RSFLAG_LEADER+i ) ); break; } if( *argument >= '1' && *argument <= '3' ) { i = *argument-'1'; assign_bit( &reset->flags, RSFLAG_REROLL+i, set ); send( ch, "Reroll bit %d set %s.\n\r", i+1, true_false( &reset->flags, RSFLAG_REROLL+i ) ); } else if( flags[i][0] == '\0' ) { send( ch, "Unknown flag -- %c\n\r", *argument ); } } for( ; *argument == ' '; argument++ ); } } void modify_reset( char_data* ch, reset_data* reset, char* argument ) { int* chances = unpack_int( reset->chances ); bool flag; if( *argument == '\0' ) return; argument = set_rsflags( ch, reset, argument ); if( *argument == '\0' ) return; #define rpn( i ) reset_pos_name[i] #define rwn( i ) reset_wear_name[i] #define ltn( i ) liquid_table[i].name if( is_set( &reset->flags, RSFLAG_MOB ) ) { class type_field type_list[] = { { "Position", MAX_RESET_POS, &rpn(0), &rpn(1), &reset->value }, { "", 0, NULL, NULL, NULL } }; if( process( type_list, ch, "reset", argument ) ) return; } else { reset->value += 2; class type_field type_list[] = { { "position", MAX_ITEM_WEAR-1, &rwn(0), &rwn(1), &reset->value }, { "liquid", MAX_ENTRY_LIQUID, <n(0), <n(1), &reset->liquid }, { "", 0, NULL, NULL, NULL } }; flag = process( type_list, ch, "reset", argument ); reset->value -= 2; if( flag ) return; } #undef rpn #undef rwn #undef ltn class int_field int_list[] = { { "Vnum", 0, 9999, &reset->vnum }, { "1_Chance", 0, 100, &chances[0] }, { "2_Chance", 0, 100, &chances[1] }, { "3_Chance", 0, 100, &chances[2] }, { "Rust", 0, 100, &chances[3] }, { "", 0, 0, NULL } }; if( process( int_list, ch, "reset", argument ) ) { reset->chances = pack_int( chances ); return; } send( ch, "Unknown Field - See help reset.\n\r" ); return; } /* * MAIN ROUTINE TO RESET AN AREA */ bool passes( reset_data* reset, int* roll ) { int* chances; chances = unpack_int( reset->chances ); for( int i = 0; i < 3; i++ ) if( is_set( &reset->flags, RSFLAG_REROLL+i ) ) roll[i] = -102; for( int i = 0; i < 3; i++ ) { if( chances[i] > 0 ) { if( roll[i] == -102 ) roll[i] = number_range( 0, 99 ); else if( roll[i] < 0 ) { roll[i] = -101; return FALSE; } if( ( roll[i] -= chances[i] ) >= 0 ) return FALSE; } else { if( roll[i] == -101 || roll[i] >= 0 ) return FALSE; } } return TRUE; } void reset_room( room_data* room ) { char_data* leader = NULL; mob_data* mob = NULL; int roll [ 3 ]; int count = -1; exit_data* exit; exit_data* back; obj_data* container = NULL; obj_data* obj; reset_data* reset; int* w1; int* w2; if( is_set( &room->room_flags, RFLAG_SAVE_ITEMS ) ) return; for( int i = room->contents-1; i >= 0; i-- ) if( ( obj = object( room->contents[i] ) ) != NULL && obj->pIndexData->vnum != OBJ_CORPSE_PC ) obj->Extract( ); for( int i = 0; i < 3; i++ ) roll[i] = -102; for( reset = room->reset; reset != NULL; reset = reset->next ) { if( count < 0 || ( is_set( &reset->flags, RSFLAG_REROLL ) && ( is_set( &reset->flags, RSFLAG_MOB ) || reset->value == -2 ) ) ) count = reset->count; if( count <= 0 && passes( reset, roll ) ) { if( is_set( &reset->flags, RSFLAG_MOB ) ) { reset_mob( reset, room, mob, leader ); } else if( is_set( &reset->flags, RSFLAG_OBJECT ) ) { reset_obj( reset, room, mob, container ); } else { rtable_calls = 0; reset_table( reset, reset->vnum, room, mob, container ); } } } /* OPEN, CLOSE DOORS */ int reset_flags [] = { EX_RESET_CLOSED, EX_RESET_LOCKED, EX_RESET_OPEN }; int status_flags [] = { EX_CLOSED, EX_LOCKED, EX_CLOSED }; int value [] = { 1,1,0 }; for( int i = 0; i < room->exits; i++ ) { exit = room->exits[i]; if( is_set( &exit->exit_info, EX_ISDOOR ) ) { w1 = &exit->exit_info; if( ( back = reverse( exit ) ) != NULL ) { if( player_in_room( exit->to_room ) ) continue; w2 = &back->exit_info; } else { w2 = w1; } for( int j = 0; j < 3; j++ ) if( is_set( w1, reset_flags[j] ) ) { assign_bit( w1, status_flags[j], value[j] ); assign_bit( w2, status_flags[j], value[j] ); } } } set_bit( &room->room_flags, RFLAG_RESET0 ); set_bit( &room->room_flags, RFLAG_RESET1 ); set_bit( &room->room_flags, RFLAG_RESET2 ); return; } /* * OBJECT RESET FUNCTION */ obj_data* create( obj_clss_data* obj_clss, reset_data* reset, mob_data* mob ) { obj_data* obj; int* chances; obj = create( obj_clss ); chances = unpack_int( reset->chances ); enchant_object( obj ); set_alloy( obj, 10 ); rust_object( obj, chances[3] ); if( is_set( &obj_clss->size_flags, SFLAG_RANDOM ) ) set_bit( &obj->size_flags, mob == NULL ? number_range( SFLAG_TINY, SFLAG_GIANT ) : wear_size( mob ) ); if( obj_clss->item_type == ITEM_DRINK_CON || obj_clss->item_type == ITEM_FOUNTAIN ) obj->value[2] = reset->liquid; return obj; } void place( obj_data* obj, reset_data* reset, room_data* room, mob_data* mob, obj_data*& container ) { if( is_set( &reset->flags, RSFLAG_INSIDE ) ) { if( container == NULL ) { bug( "Reset_Obj: Inside flag with no container - %s %d", room != NULL ? "Room" : "Species", room != NULL ? room->vnum : mob->species->vnum ); obj->Extract( ); return; } obj->To( container ); } else if( reset->value == -2 ) { if( room == NULL ) { bug( "Reset_Obj: Ground Object with NULL room - Species %d", mob->species->vnum ); obj->Extract( ); return; } obj->To( room ); stop_events( obj, execute_decay ); } else { if( mob == NULL ) { bug( "Reset_Obj: Wear loc with null mob - Room %d", room->vnum ); obj->Extract( ); return; } if( reset->value >= 0 ) { obj->position = reset->value; obj->To( &mob->wearing ); } else obj->To( mob ); } if( is_set( &reset->flags, RSFLAG_CONTAINER ) ) container = obj; } void reset_obj( reset_data* reset, room_data* room, mob_data* mob, obj_data*& container ) { obj_clss_data* obj_clss; if( ( obj_clss = get_obj_index( reset->vnum ) ) == NULL || ( room == NULL && is_set( obj_clss->extra_flags, OFLAG_BODY_PART ) ) ) return; if( mob != NULL && mob->pShop != NULL && reset->value == -1 ) return; place( create( obj_clss, reset, mob ), reset, room, mob, container ); return; } /* * RESET TABLE FUNCTION */ void reset_table( reset_data* base_reset, int n, room_data* room, mob_data* mob, obj_data*& container ) { obj_clss_data* obj_clss; obj_data* obj; reset_data* reset; int roll [ 3 ]; int i; if( n < 0 || n >= num_rtable ) { bug( "Reset_Table: Invalid table." ); bug( "-- Index = %d", n ); return; } rtable_calls++; if( rtable_calls >= 100 ) { if( rtable_calls == 100 ) bug( "Reset_Table: Infinite lookup chain." ); return; } for( i = 0; i < 3; i++ ) roll[i] = -102; for( reset = rtable_list[n]->reset; reset != NULL; reset = reset->next ) if( passes( reset, roll ) ) { if( is_set( &reset->flags, RSFLAG_OBJECT ) ) { if( ( obj_clss = get_obj_index( reset->vnum ) ) == NULL ) return; obj = create( obj_clss, reset, mob ); place( obj, base_reset, room, mob, container ); } else { reset_table( base_reset, reset->vnum, room, mob, container ); } } return; } /* * MOB RESET FUNCTIONS */ void reset_mob( reset_data* reset, room_data* room, mob_data*& mob, char_data*& leader ) { species_data* species; if( ( is_set( &reset->flags, RSFLAG_NIGHT ) && is_day( ) ) || ( is_set( &reset->flags, RSFLAG_DAY ) && !is_day( ) ) ) return; if( ( species = get_species( reset->vnum ) ) == NULL ) return; mob = create_mobile( species ); if( is_set( &reset->flags, RSFLAG_SENTINEL ) || is_set( &mob->species->act_flags, ACT_SENTINEL ) ) { set_bit( &mob->status, STAT_SENTINEL ); } else { delay_wander( new event_data( execute_wander, mob ) ); } if( is_set( &reset->flags, RSFLAG_AGGRESSIVE ) ) set_bit( &mob->status, STAT_AGGR_ALL ); mob->To( room ); mob->position = rspos_index[ reset->value ]; mob->reset = reset; mob_setup( mob, room ); register_reset( mob, room ); mreset_mob( mob ); if( leader != NULL && is_set( &reset->flags, RSFLAG_FOLLOWER ) ) add_follower( mob, leader ); if( is_set( &reset->flags, RSFLAG_LEADER ) ) leader = mob; } void register_reset( char_data* mob, room_data* room ) { reset_data* mark = room->reset; reset_data* reset; for( reset = room->reset; ; reset = reset->next ) { if( is_set( &reset->flags, RSFLAG_REROLL ) ) mark = reset; if( reset == mob->reset ) break; } mark->count++; mob->reset = mark; } void unregister_reset( char_data* mob ) { if( mob->reset != NULL ) mob->reset->count--; } void mob_setup( mob_data* mob, room_data* room ) { shop_data* shop; if( room->is_dark( ) ) set_bit( mob->affected_by, AFF_INFRARED ); for( shop = shop_list; shop != NULL; shop = shop->next ) if( shop->room == room && shop->keeper == mob->species->vnum ) mob->pShop = shop; set_trainer( mob, room ); } /* * MRESET FUNCTIONS */ void mreset_mob( mob_data* mob ) { reset_data* reset; obj_data* container = NULL; int roll [ 3 ]; int i; for( i = 0; i < 3; i++ ) roll[i] = -102; for( reset = mob->species->reset; reset != NULL; reset = reset->next ) if( passes( reset, roll ) ) { if( is_set( &reset->flags, RSFLAG_OBJECT ) ) { reset_obj( reset, NULL, mob, container ); } else { rtable_calls = 0; reset_table( reset, reset->vnum, NULL, mob, container ); } } return; } thing_array* get_skin_list( species_data* species ) { obj_data* obj; obj_clss_data* obj_clss = NULL; thing_array* list = NULL; reset_data* reset; int roll [ 3 ]; for( int i = 0; i < 3; i++ ) roll[i] = -102; for( reset = species->reset; reset != NULL; reset = reset->next ) if( ( obj_clss = get_obj_index( reset->vnum ) ) != NULL && is_set( obj_clss->extra_flags, OFLAG_BODY_PART ) ) break; if( reset == NULL ) return (thing_array*) -1; for( reset = species->reset; reset != NULL; reset = reset->next ) { if( !passes( reset, roll ) || ( obj_clss = get_obj_index( reset->vnum ) ) == NULL || !is_set( obj_clss->extra_flags, OFLAG_BODY_PART ) ) continue; if( list == NULL ) list = new thing_array; obj = create( obj_clss ); *list += obj; } return list; } /* * SHOP RESET FUNCTION */ void reset_shop( mob_data* ch ) { reset_data* reset; obj_data* obj; int roll [ 3 ]; for( int i = 0; i < 3; i++ ) roll[i] = -102; for( reset = ch->reset->next; reset != NULL; reset = reset->next ) { if( !is_set( &reset->flags, RSFLAG_OBJECT ) || reset->value == -2 ) break; if( passes( reset, roll ) && reset->value == -1 ) { obj = create( get_obj_index( reset->vnum ) ); set_bit( obj->extra_flags, OFLAG_IDENTIFIED ); set_bit( obj->extra_flags, OFLAG_KNOWN_LIQUID ); if( obj->pIndexData->item_type == ITEM_DRINK_CON ) obj->value[2] = reset->liquid; obj->To( ch ); consolidate( obj ); } } } /* * DISK ROUTINES */ void load( FILE* fp, reset_data*& list ) { reset_data* reset; int i; for( ; ; ) { if( ( i = fread_number( fp ) ) == -1 ) break; reset = new reset_data; reset->vnum = i; reset->flags = fread_number( fp ); reset->chances = fread_number( fp ); reset->value = fread_number( fp ); reset->liquid = fread_number( fp ); append( list, reset ); } return; } void write( FILE* fp, reset_data* reset ) { for( ; reset != NULL; reset = reset->next ) fprintf( fp, "%d %d %d %d %d\n", reset->vnum, reset->flags, reset->chances, reset->value, reset->liquid ); fprintf( fp, "-1\n" ); } /* * COMMANDS TO LOCATE RESETS */ bool has_reset( obj_clss_data* obj_clss ) { area_data* area; room_data* room; reset_data* reset; species_data* species; int i; for( area = area_list; area != NULL; area = area->next ) for( room = area->room_first; room != NULL; room = room->next ) for( reset = room->reset; reset != NULL; reset = reset->next ) if( is_set( &reset->flags, RSFLAG_OBJECT ) && reset->vnum == obj_clss->vnum ) return TRUE; for( i = 0; i < MAX_SPECIES; i++ ) { if( ( species = species_list[i] ) == NULL ) continue; for( reset = species->reset; reset != NULL; reset = reset->next ) if( is_set( &reset->flags, RSFLAG_OBJECT ) && reset->vnum == obj_clss->vnum ) return TRUE; } return FALSE; } /* * ROWHERE ROUTINES */ void do_rowhere( char_data* ch, char* argument ) { char tmp [ TWO_LINES ]; action_data* action; area_data* area; custom_data* custom; mprog_data* mprog; obj_clss_data* obj_clss; reset_data* reset; room_data* room; shop_data* shop; species_data* species; const char* name; bool first = TRUE; bool found; int vnum, index; int i, j; int flags; if( !get_flags( ch, argument, &flags, "p", "Rowhere" ) ) return; if( *argument == '\0' ) { send( ch, "Syntax: rowhere <object>\n\r" ); return; } vnum = atoi( argument ); for( index = 0; index < MAX_OBJ_INDEX; index++ ) { if( ( obj_clss = obj_index_list[index] ) == NULL ) continue; name = obj_clss->Name( ); if( !is_name( argument, name ) && obj_clss->vnum != vnum ) continue; page( ch, "\n\r" ); sprintf( tmp, "--- %s (%d) ---", name, index ); tmp[4] = toupper( tmp[4] ); page_centered( ch, tmp ); page( ch, "\n\r" ); first = FALSE; found = FALSE; /* SEARCH MRESETS */ for( i = 0; i < MAX_SPECIES; i++ ) { if( ( species = species_list[i] ) == NULL ) continue; for( reset = species->reset; reset != NULL; reset = reset->next ) { if( obj_clss->vnum == reset->vnum && is_set( &reset->flags, RSFLAG_OBJECT ) ) { page( ch, " On %s\n\r", species->Name( ) ); found = TRUE; } } if( is_set( &flags, 0 ) ) { if( search_oload( species->attack->binary, index ) ) { page( ch, " Loads in attack prog on mob #%d.\n\r", i ); found = TRUE; } for( j = 1, mprog = species->mprog; mprog != NULL; j++, mprog = mprog->next ) if( search_oload( mprog->binary, index ) ) { page( ch, " Loads in mprog #%d on mob #%d.\n\r", j, i ); found = TRUE; } } } /* SEARCH ROOM RESETS */ for( area = area_list; area != NULL; area = area->next ) { for( room = area->room_first; room != NULL; room = room->next ) { species = NULL; for( reset = room->reset; reset != NULL; reset = reset->next ) { if( is_set( &reset->flags, RSFLAG_MOB ) ) { species = get_species( reset->vnum ); continue; } if( obj_clss->vnum != reset->vnum || !is_set( &reset->flags, RSFLAG_OBJECT ) ) continue; found = TRUE; if( reset->value == -2 ) { page( ch, " At %s [%d]\n\r", room->name, room->vnum ); } else if( species == NULL ) { page( ch, " [BUG] Illegal reset structure [%d]\n\r", room->vnum ); } else { page( ch, " On %s at %s [%d]\n\r", species->Name( ), room->name, room->vnum ); } } } } if( is_set( &flags, 0 ) ) { for( area = area_list; area != NULL; area = area->next ) for( room = area->room_first; room != NULL; room = room->next ) for( j = 1, action = room->action; action != NULL; j++, action = action->next ) if( action->binary != NULL && search_oload( action->binary, index ) ) { page( ch, " Loads in action #%d in room #%d.\n\r", j, room->vnum ); found = TRUE; } } /* SEARCH TABLES */ for( i = 0; i < num_rtable; i++ ) for( reset = rtable_list[i]->reset; reset != NULL; reset = reset->next ) if( reset->vnum == index && is_set( &reset->flags, RSFLAG_OBJECT ) ) { page( ch, " In rtable %d, %s.\n\r", i+1, rtable_list[i]->name ); found = TRUE; } /* SEARCH SHOPS */ for( shop = shop_list; shop != NULL; shop = shop->next ) for( custom = shop->custom; custom != NULL; custom = custom->next ) { if( custom->item == obj_clss ) { page( ch, " Custom in room %d\n\r", shop->room->vnum ); } for( i = 0; i < MAX_INGRED; i++ ) if( custom->ingred[i] == obj_clss ) { page( ch, " Ingredient for making %s in room %d\n\r", custom->item->Name( ), shop->room->vnum ); found = TRUE; } } /* SEARCH SPELLS */ for( i = 0; i < MAX_SPELL; i++ ) for( j = 0; j < MAX_SPELL_WAIT; j++ ) if( abs( spell_table[i].reagent[j] ) == index ) { page( ch, " Reagent for spell %s\n\r", spell_table[i].name ); found = TRUE; break; } /* CORPSE? */ for( i = 0; i < MAX_SPECIES; i++ ) { if( ( species = species_list[i] ) == NULL ) continue; if( species->corpse == index ) { page( ch, " Corpse of %s\n\r", species ); found = TRUE; } } rowhere_key( ch, obj_clss ); if( !found ) page_centered( ch, " None found" ); } if( first ) send( ch, "Nothing like that in hell, earth, or heaven.\n\r" ); return; } void rowhere_key( char_data* ch, obj_clss_data* key ) { area_data* area; obj_clss_data* container; room_data* room; int index; if( key->item_type != ITEM_KEY ) return; for( area = area_list; area != NULL; area = area->next ) for( room = area->room_first; room != NULL; room = room->next ) for( int i = 0; i < room->exits; i++ ) if( room->exits[i]->key == key->vnum ) page( ch, " -- Unlocks %s door of room %d --\n\r", dir_table[ room->exits[i]->direction ].name, room->vnum ); for( index = 0; index < MAX_OBJ_INDEX; index++ ) if( ( container = obj_index_list[index] ) != NULL && container->item_type == ITEM_CONTAINER && container->value[2] == key->vnum ) page( ch, " -- Unlocks object %d, %s --\n\r", index, container->Name( ) ); return; } void do_rmwhere( char_data* ch, char* argument ) { action_data* action; area_data* area; reset_data* reset; room_data* room; species_data* species; species_data* undead; bool first = TRUE; bool found = TRUE; int vnum; int flags; if( !get_flags( ch, argument, &flags, "p", "Rowhere" ) ) return;; if( *argument == '\0' ) { send( ch, "Syntax: rmwhere <mob>\n\r" ); return; } vnum = atoi( argument ); for( int i = 1; i < MAX_SPECIES; i++ ) { if( ( species = species_list[i] ) == NULL || ( vnum != i && !is_name( argument, species->Name( ) ) ) ) continue; page( ch, "%s%s:\n\r", ( first ? "" : "\n\r" ), species->Name( ) ); first = FALSE; found = FALSE; for( area = area_list; area != NULL; area = area->next ) for( room = area->room_first; room != NULL; room = room->next ) for( reset = room->reset; reset != NULL; reset = reset->next ) if( reset->vnum == i && is_set( &reset->flags, RSFLAG_MOB ) ) { page( ch, " at %s [%5d]\n\r", room->name, room->vnum ); found = TRUE; } for( int j = 1; j < MAX_SPECIES; j++ ) { if( ( undead = species_list[j] ) != NULL ) { if( undead->zombie == i ) { page( ch, " -- Zombie form of %s, mob #%d --\n\r", undead->Name( ), j ); found = TRUE; } if( undead->skeleton == i ) { page( ch, " -- Skeletal form of %s, mob #%d --\n\r", undead->Name( ), j ); found = TRUE; } } } if( is_set( &flags, 0 ) ) { for( area = area_list; area != NULL; area = area->next ) { for( room = area->room_first; room != NULL; room = room->next ) { action = room->action; for( int j = 1; action != NULL; j++, action = action->next ) if( search_mload( action->binary, i ) ) { page( ch, " --> Loads in action #%d in room #%d <--\n\r", j, room->vnum ); found = TRUE; } } } } if( !found ) page( ch, " no resets found\n\r" ); } if( first ) send( ch, "Nothing like that in hell, earth, or heaven.\n\r" ); return; }