/* Rare item counting function taken from the Tartarus codebase, a * ROM 2.4b derivitive by Ceran. Modified for Smaug compatibility by Samson */ int scan_pfiles( const char *dirname, const char *filename, bool updating ) { FILE *fpChar; char fname[256]; int adjust = 0; snprintf( fname, 256, "%s/%s", dirname, filename ); // log_string( fname ); if( !( fpChar = fopen( fname, "r" ) ) ) { perror( fname ); return 0; } for( ;; ) { int vnum = 0, counter = 1; char letter; const char *word; string tempstring; obj_index *pObjIndex = NULL; letter = fread_letter( fpChar ); if( ( letter != '#' ) && ( !feof( fpChar ) ) ) continue; word = ( feof( fpChar ) ? "End" : fread_word( fpChar ) ); if( word[0] == '\0' ) { bug( "%s: EOF encountered reading file!", __FUNCTION__ ); word = "End"; } // log_string( word ); if( !str_cmp( word, "End" ) ) break; if( !str_cmp( word, "OBJECT" ) ) { word = ( feof( fpChar ) ? "End" : fread_word( fpChar ) ); if( word[0] == '\0' ) { bug( "%s: EOF encountered reading file!", __FUNCTION__ ); word = "End"; } if( !str_cmp( word, "End" ) ) break; if( !str_cmp( word, "Nest" ) ) { fread_number( fpChar ); word = feof( fpChar ) ? "End" : fread_word( fpChar ); } if( !str_cmp( word, "Count" ) ) { counter = fread_number( fpChar ); word = feof( fpChar ) ? "End" : fread_word( fpChar ); } if( !str_cmp( word, "Name" ) ) { tempstring = fread_flagstring( fpChar ); word = feof( fpChar ) ? "End" : fread_word( fpChar ); } if( !str_cmp( word, "ShortDescr" ) ) { tempstring = fread_flagstring( fpChar ); word = feof( fpChar ) ? "End" : fread_word( fpChar ); } if( !str_cmp( word, "Description" ) ) { tempstring = fread_flagstring( fpChar ); word = feof( fpChar ) ? "End" : fread_word( fpChar ); } if( !str_cmp( word, "ActionDesc" ) ) { tempstring = fread_flagstring( fpChar ); word = feof( fpChar ) ? "End" : fread_word( fpChar ); } if( !str_cmp( word, "Ovnum" ) ) { vnum = fread_number( fpChar ); if( ( pObjIndex = get_obj_index( vnum ) ) == NULL ) { bug( "%s: %s has bad obj vnum.", __FUNCTION__, filename ); adjust = 1; /* So it can clean out the bad object - Samson 4-16-00 */ } word = feof( fpChar ) ? "End" : fread_word( fpChar ); } if( !str_cmp( word, "Ego" ) && pObjIndex ) { int ego = fread_number( fpChar ); if( ego >= sysdata->minego ) { if( !updating ) { pObjIndex->count += counter; log_printf( "%s: Counted %d of Vnum %d", filename, counter, vnum ); } else adjust = 1; } } } } FCLOSE( fpChar ); return adjust; }
/* * Read in actual realm data. */ void fread_realm( realm_data * realm, FILE * fp ) { int file_ver = 0; for( ;; ) { const char *word = feof( fp ) ? "End" : fread_word( fp ); switch ( UPPER( word[0] ) ) { default: bug( "%s: no match: %s", __func__, word ); fread_to_eol( fp ); break; case '*': fread_to_eol( fp ); break; case 'B': STDSKEY( "Badge", realm->badge ); KEY( "Board", realm->board, fread_number( fp ) ); break; case 'D': STDSKEY( "Description", realm->realmdesc ); break; case 'E': if( !str_cmp( word, "End" ) ) return; break; case 'F': STDSKEY( "Filename", realm->filename ); break; case 'L': STDSKEY( "Leader", realm->leader ); STDSKEY( "Leadrank", realm->leadrank ); break; case 'M': KEY( "Members", realm->members, fread_short( fp ) ); break; case 'N': STDSKEY( "Name", realm->name ); break; case 'T': if( !str_cmp( word, "Type" ) ) { const char *temp = fread_flagstring( fp ); int value = get_realm_type_name( temp ); if( value < 0 || value > MAX_REALM ) { bug( "%s: Invalid realm type: %s. Setting to None.", __func__, temp ); value = 0; } realm->type = value; } break; case 'V': KEY( "Version", file_ver, fread_number( fp ) ); break; } } }
void fread_fuss_object( FILE * fp, area_data * tarea ) { obj_index *pObjIndex = nullptr; bool oldobj = false; for( ;; ) { const char *word = ( feof( fp ) ? "#ENDOBJECT" : fread_word( fp ) ); if( word[0] == '\0' ) { log_printf( "%s: EOF encountered reading file!", __func__ ); word = "#ENDOBJECT"; } switch ( word[0] ) { default: bug( "%s: no match: %s", __func__, word ); fread_to_eol( fp ); break; case '#': if( !str_cmp( word, "#ENDOBJECT" ) ) { if( !oldobj ) { obj_index_table.insert( map < int, obj_index * >::value_type( pObjIndex->vnum, pObjIndex ) ); tarea->objects.push_back( pObjIndex ); ++top_obj_index; } return; } // Format of this section is identical to AFKMud. Let's cheat :) if( !str_cmp( word, "#EXDESC" ) ) { extra_descr_data *ed = fread_afk_exdesc( fp ); if( ed ) pObjIndex->extradesc.push_back( ed ); break; } // Format of this section is identical to AFKMud. Let's cheat :) if( !str_cmp( word, "#MUDPROG" ) ) { mud_prog_data *mprg = new mud_prog_data; fread_afk_mudprog( fp, mprg, pObjIndex ); pObjIndex->mudprogs.push_back( mprg ); ++top_prog; break; } break; case 'A': if( !str_cmp( word, "Action" ) ) { const char *desc = fread_flagstring( fp ); if( desc && desc[0] != '\0' && str_cmp( desc, "(null)" ) ) pObjIndex->action_desc = STRALLOC( desc ); break; } if( !str_cmp( word, "Affect" ) || !str_cmp( word, "AffectData" ) ) { affect_data *af = fread_fuss_affect( fp, word ); if( af ) pObjIndex->affects.push_back( af ); break; } break; case 'F': if( !str_cmp( word, "Flags" ) ) { flag_set( fp, pObjIndex->extra_flags, fuss_o_flags ); break; } break; case 'K': KEY( "Keywords", pObjIndex->name, fread_string( fp ) ); break; case 'L': if( !str_cmp( word, "Long" ) ) { const char *desc = fread_flagstring( fp ); if( desc && desc[0] != '\0' && str_cmp( desc, "(null)" ) ) pObjIndex->objdesc = STRALLOC( desc ); break; } break; case 'S': KEY( "Short", pObjIndex->short_descr, fread_string( fp ) ); if( !str_cmp( word, "Spells" ) ) { switch ( pObjIndex->item_type ) { default: break; case ITEM_PILL: case ITEM_POTION: case ITEM_SCROLL: pObjIndex->value[1] = skill_lookup( fread_word( fp ) ); pObjIndex->value[2] = skill_lookup( fread_word( fp ) ); pObjIndex->value[3] = skill_lookup( fread_word( fp ) ); break; case ITEM_STAFF: case ITEM_WAND: pObjIndex->value[3] = skill_lookup( fread_word( fp ) ); break; case ITEM_SALVE: pObjIndex->value[4] = skill_lookup( fread_word( fp ) ); pObjIndex->value[5] = skill_lookup( fread_word( fp ) ); break; } break; } if( !str_cmp( word, "Stats" ) ) { const char *ln = fread_line( fp ); int x1, x2, x3, x4, x5; x1 = x2 = x3 = x5 = 0; x4 = 9999; sscanf( ln, "%d %d %d %d %d", &x1, &x2, &x3, &x4, &x5 ); pObjIndex->weight = x1; pObjIndex->weight = UMAX( 1, pObjIndex->weight ); pObjIndex->cost = x2; pObjIndex->ego = x3; pObjIndex->level = x4; pObjIndex->layers = x5; pObjIndex->socket[0] = STRALLOC( "None" ); pObjIndex->socket[1] = STRALLOC( "None" ); pObjIndex->socket[2] = STRALLOC( "None" ); if( pObjIndex->ego >= sysdata->minego ) { log_printf( "Item %d gaining new rare item limit of 1", pObjIndex->vnum ); pObjIndex->limit = 1; /* Sets new limit since stock zones won't have one */ } else pObjIndex->limit = 9999; /* Default value, this should more than insure that the shit loads */ pObjIndex->ego = -2; break; } break; case 'T': if( !str_cmp( word, "Type" ) ) { int value = get_otype( fread_flagstring( fp ) ); if( value < 0 ) { bug( "%s: vnum %d: Object has invalid type! Defaulting to trash.", __func__, pObjIndex->vnum ); value = get_otype( "trash" ); } pObjIndex->item_type = value; break; } break; case 'V': if( !str_cmp( word, "Values" ) ) { const char *ln = fread_line( fp ); int x1, x2, x3, x4, x5, x6; x1 = x2 = x3 = x4 = x5 = x6 = 0; sscanf( ln, "%d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6 ); pObjIndex->value[0] = x1; pObjIndex->value[1] = x2; pObjIndex->value[2] = x3; pObjIndex->value[3] = x4; pObjIndex->value[4] = x5; pObjIndex->value[5] = x6; break; } if( !str_cmp( word, "Vnum" ) ) { bool tmpBootDb = fBootDb; fBootDb = false; int vnum = fread_number( fp ); list < area_data * >::iterator iarea; for( iarea = arealist.begin( ); iarea != arealist.end( ); ++iarea ) { area_data *area = *iarea; if( !str_cmp( area->filename, tarea->filename ) ) continue; bool area_conflict = check_area_conflict( area, vnum, vnum ); if( area_conflict ) { log_printf( "ERROR: %s has vnum conflict with %s!", tarea->filename, ( area->filename ? area->filename : "(invalid)" ) ); log_printf( "%s occupies vnums : %-6d - %-6d", ( area->filename ? area->filename : "(invalid)" ), area->low_vnum, area->hi_vnum ); log_printf( "%s wants to use vnum: %-6d", tarea->filename, vnum ); log_string( "This is a fatal error. Program terminated." ); exit( 1 ); } } if( get_obj_index( vnum ) ) { if( tmpBootDb ) { fBootDb = tmpBootDb; bug( "%s: vnum %d duplicated.", __func__, vnum ); // Try to recover, read to end of duplicated object and then bail out for( ;; ) { word = feof( fp ) ? "#ENDOBJECT" : fread_word( fp ); if( !str_cmp( word, "#ENDOBJECT" ) ) return; } } else { pObjIndex = get_obj_index( vnum ); log_printf_plus( LOG_BUILD, sysdata->build_level, "Cleaning object: %d", vnum ); pObjIndex->clean_obj( ); oldobj = true; } } else { pObjIndex = new obj_index; pObjIndex->clean_obj( ); } pObjIndex->vnum = vnum; pObjIndex->area = tarea; fBootDb = tmpBootDb; if( fBootDb ) { if( !tarea->low_vnum ) tarea->low_vnum = vnum; if( vnum > tarea->hi_vnum ) tarea->hi_vnum = vnum; } break; } break; case 'W': if( !str_cmp( word, "WFlags" ) ) { flag_set( fp, pObjIndex->wear_flags, w_flags ); break; } break; } } }
void fread_fuss_mobile( FILE * fp, area_data * tarea ) { mob_index *pMobIndex = nullptr; bool oldmob = false; for( ;; ) { const char *word = ( feof( fp ) ? "#ENDMOBILE" : fread_word( fp ) ); if( word[0] == '\0' ) { log_printf( "%s: EOF encountered reading file!", __func__ ); word = "#ENDMOBILE"; } switch ( word[0] ) { default: log_printf( "%s: no match: %s", __func__, word ); fread_to_eol( fp ); break; case '#': // We can cheat here since the prog formats are identical :) if( !str_cmp( word, "#MUDPROG" ) ) { mud_prog_data *mprg = new mud_prog_data; fread_afk_mudprog( fp, mprg, pMobIndex ); pMobIndex->mudprogs.push_back( mprg ); ++top_prog; break; } if( !str_cmp( word, "#ENDMOBILE" ) ) { if( !oldmob ) { mob_index_table.insert( map < int, mob_index * >::value_type( pMobIndex->vnum, pMobIndex ) ); tarea->mobs.push_back( pMobIndex ); ++top_mob_index; } return; } break; case 'A': if( !str_cmp( word, "Actflags" ) ) { flag_set( fp, pMobIndex->actflags, fuss_act_flags ); break; } if( !str_cmp( word, "Affected" ) ) { flag_set( fp, pMobIndex->affected_by, aff_flags ); break; } if( !str_cmp( word, "Attacks" ) ) { flag_set( fp, pMobIndex->attacks, attack_flags ); break; } if( !str_cmp( word, "Attribs" ) ) { const char *ln = fread_line( fp ); int x1, x2, x3, x4, x5, x6, x7; x1 = x2 = x3 = x4 = x5 = x6 = x7 = 0; sscanf( ln, "%d %d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6, &x7 ); pMobIndex->perm_str = x1; pMobIndex->perm_int = x2; pMobIndex->perm_wis = x3; pMobIndex->perm_dex = x4; pMobIndex->perm_con = x5; pMobIndex->perm_cha = x6; pMobIndex->perm_lck = x7; break; } break; case 'B': if( !str_cmp( word, "Bodyparts" ) ) { flag_set( fp, pMobIndex->body_parts, part_flags ); break; } break; case 'C': if( !str_cmp( word, "Class" ) ) { const char *class_word = fread_flagstring( fp ); short Class = get_fuss_npc_class( class_word ); if( Class < 0 || Class >= MAX_NPC_CLASS ) { bug( "%s: vnum %d: Mob has invalid class: %s. Defaulting to warrior.", __func__, pMobIndex->vnum, class_word ); Class = get_npc_class( "warrior" ); } pMobIndex->Class = Class; break; } break; case 'D': if( !str_cmp( word, "Defenses" ) ) { flag_set( fp, pMobIndex->defenses, defense_flags ); break; } if( !str_cmp( word, "DefPos" ) ) { short position = get_npc_position( fread_flagstring( fp ) ); if( position < 0 || position >= POS_MAX ) { bug( "%s: vnum %d: Mobile in invalid default position! Defaulting to standing.", __func__, pMobIndex->vnum ); position = POS_STANDING; } pMobIndex->defposition = position; break; } if( !str_cmp( word, "Desc" ) ) { const char *desc = fread_flagstring( fp ); if( desc && desc[0] != '\0' && str_cmp( desc, "(null)" ) ) pMobIndex->chardesc = STRALLOC( desc ); break; } break; case 'G': if( !str_cmp( word, "Gender" ) ) { short sex = get_npc_sex( fread_flagstring( fp ) ); if( sex < 0 || sex > SEX_FEMALE ) { bug( "%s: vnum %d: Mobile has invalid sex! Defaulting to neuter.", __func__, pMobIndex->vnum ); sex = SEX_NEUTRAL; } pMobIndex->sex = sex; break; } break; case 'I': if( !str_cmp( word, "Immune" ) ) { flag_set( fp, pMobIndex->immune, ris_flags ); break; } break; case 'K': KEY( "Keywords", pMobIndex->player_name, fread_string( fp ) ); break; case 'L': KEY( "Long", pMobIndex->long_descr, fread_string( fp ) ); break; case 'P': if( !str_cmp( word, "Position" ) ) { short position = get_npc_position( fread_flagstring( fp ) ); if( position < 0 || position >= POS_MAX ) { bug( "%s: vnum %d: Mobile in invalid position! Defaulting to standing.", __func__, pMobIndex->vnum ); position = POS_STANDING; } pMobIndex->position = position; break; } break; case 'R': if( !str_cmp( word, "Race" ) ) { const char *race_word = fread_flagstring( fp ); short race = get_fuss_npc_race( race_word ); if( race < 0 || race >= MAX_NPC_RACE ) { bug( "%s: vnum %d: Mob has invalid race: %s Defaulting to monster.", __func__, pMobIndex->vnum, race_word ); race = get_npc_race( "monster" ); } pMobIndex->race = race; break; } if( !str_cmp( word, "RepairData" ) ) { int iFix; repair_data *rShop = new repair_data; rShop->keeper = pMobIndex->vnum; for( iFix = 0; iFix < MAX_FIX; ++iFix ) rShop->fix_type[iFix] = fread_number( fp ); rShop->profit_fix = fread_number( fp ); rShop->shop_type = fread_number( fp ); rShop->open_hour = fread_number( fp ); rShop->close_hour = fread_number( fp ); pMobIndex->rShop = rShop; repairlist.push_back( rShop ); ++top_repair; break; } if( !str_cmp( word, "Resist" ) ) { flag_set( fp, pMobIndex->resistant, ris_flags ); break; } break; case 'S': // Unused - this is autocalced in mobindex.cpp if( !str_cmp( word, "Saves" ) ) { fread_line( fp ); break; } KEY( "Short", pMobIndex->short_descr, fread_string( fp ) ); if( !str_cmp( word, "ShopData" ) ) { int iTrade; shop_data *pShop = new shop_data; pShop->keeper = pMobIndex->vnum; for( iTrade = 0; iTrade < MAX_TRADE; ++iTrade ) pShop->buy_type[iTrade] = fread_number( fp ); pShop->profit_buy = fread_number( fp ); pShop->profit_sell = fread_number( fp ); pShop->profit_buy = URANGE( pShop->profit_sell + 5, pShop->profit_buy, 1000 ); pShop->profit_sell = URANGE( 0, pShop->profit_sell, pShop->profit_buy - 5 ); pShop->open_hour = fread_number( fp ); pShop->close_hour = fread_number( fp ); pMobIndex->pShop = pShop; shoplist.push_back( pShop ); ++top_shop; break; } if( !str_cmp( word, "Speaks" ) ) { flag_set( fp, pMobIndex->speaks, lang_names ); if( pMobIndex->speaks.none( ) ) pMobIndex->speaks.set( LANG_COMMON ); break; } if( !str_cmp( word, "Speaking" ) ) { string speaking, flag; int value; speaking = fread_flagstring( fp ); speaking = one_argument( speaking, flag ); value = get_langnum( flag ); if( value < 0 || value >= LANG_UNKNOWN ) bug( "Unknown speaking language: %s", flag.c_str() ); else pMobIndex->speaking = value; if( !pMobIndex->speaking ) pMobIndex->speaking = LANG_COMMON; break; } if( !str_cmp( word, "Specfun" ) ) { const char *temp = fread_flagstring( fp ); if( !pMobIndex ) { bug( "%s: Specfun: Invalid mob vnum!", __func__ ); break; } if( !( pMobIndex->spec_fun = m_spec_lookup( temp ) ) ) { bug( "%s: Specfun: vnum %d, no spec_fun called %s.", __func__, pMobIndex->vnum, temp ); pMobIndex->spec_funname.clear( ); } else pMobIndex->spec_funname = temp; break; } if( !str_cmp( word, "Stats1" ) ) { const char *ln = fread_line( fp ); int x1, x2, x3, x4, x5, x6; x1 = x2 = x3 = x4 = x5 = x6 = 0; sscanf( ln, "%d %d %d %d %d %d", &x1, &x2, &x3, &x4, &x5, &x6 ); pMobIndex->alignment = x1; pMobIndex->level = x2; pMobIndex->mobthac0 = x3; pMobIndex->ac = x4; pMobIndex->gold = x5; pMobIndex->exp = -1; // Converts to AFKMud auto-calc exp break; } if( !str_cmp( word, "Stats2" ) ) { const char *ln = fread_line( fp ); int x1, x2, x3; x1 = x2 = x3 = 0; sscanf( ln, "%d %d %d", &x1, &x2, &x3 ); pMobIndex->hitnodice = pMobIndex->level; pMobIndex->hitsizedice = 8; pMobIndex->hitplus = x3; break; } if( !str_cmp( word, "Stats3" ) ) { const char *ln = fread_line( fp ); int x1, x2, x3; x1 = x2 = x3 = 0; sscanf( ln, "%d %d %d", &x1, &x2, &x3 ); pMobIndex->damnodice = x1; pMobIndex->damsizedice = x2; pMobIndex->damplus = x3; break; } if( !str_cmp( word, "Stats4" ) ) { const char *ln = fread_line( fp ); int x1, x2, x3, x4, x5; x1 = x2 = x3 = x4 = x5 = 0; sscanf( ln, "%d %d %d %d %d", &x1, &x2, &x3, &x4, &x5 ); pMobIndex->height = x1; pMobIndex->weight = x2; pMobIndex->numattacks = x3; pMobIndex->hitroll = x4; pMobIndex->damroll = x5; break; } if( !str_cmp( word, "Suscept" ) ) { flag_set( fp, pMobIndex->susceptible, ris_flags ); break; } break; case 'V': if( !str_cmp( word, "Vnum" ) ) { bool tmpBootDb = fBootDb; fBootDb = false; int vnum = fread_number( fp ); list < area_data * >::iterator iarea; for( iarea = arealist.begin( ); iarea != arealist.end( ); ++iarea ) { area_data *area = *iarea; if( !str_cmp( area->filename, tarea->filename ) ) continue; bool area_conflict = check_area_conflict( area, vnum, vnum ); if( area_conflict ) { log_printf( "ERROR: %s has vnum conflict with %s!", tarea->filename, ( area->filename ? area->filename : "(invalid)" ) ); log_printf( "%s occupies vnums : %-6d - %-6d", ( area->filename ? area->filename : "(invalid)" ), area->low_vnum, area->hi_vnum ); log_printf( "%s wants to use vnum: %-6d", tarea->filename, vnum ); log_string( "This is a fatal error. Program terminated." ); exit( 1 ); } } if( get_mob_index( vnum ) ) { if( tmpBootDb ) { fBootDb = tmpBootDb; bug( "%s: vnum %d duplicated.", __func__, vnum ); // Try to recover, read to end of duplicated mobile and then bail out for( ;; ) { word = feof( fp ) ? "#ENDMOBILE" : fread_word( fp ); if( !str_cmp( word, "#ENDMOBILE" ) ) return; } } else { pMobIndex = get_mob_index( vnum ); log_printf_plus( LOG_BUILD, sysdata->build_level, "Cleaning mobile: %d", vnum ); pMobIndex->clean_mob( ); oldmob = true; } } else { pMobIndex = new mob_index; pMobIndex->clean_mob( ); } pMobIndex->vnum = vnum; pMobIndex->area = tarea; fBootDb = tmpBootDb; if( fBootDb ) { if( !tarea->low_vnum ) tarea->low_vnum = vnum; if( vnum > tarea->hi_vnum ) tarea->hi_vnum = vnum; } break; } break; } } }
void fread_fuss_room( FILE * fp, area_data * tarea ) { room_index *pRoomIndex = NULL; bool oldroom = false; for( ;; ) { const char *word = ( feof( fp ) ? "#ENDROOM" : fread_word( fp ) ); if( word[0] == '\0' ) { log_printf( "%s: EOF encountered reading file!", __func__ ); word = "#ENDROOM"; } switch ( word[0] ) { default: bug( "%s: no match: %s", __func__, word ); fread_to_eol( fp ); break; case '#': if( !str_cmp( word, "#ENDROOM" ) ) { if( !oldroom ) { room_index_table.insert( map < int, room_index * >::value_type( pRoomIndex->vnum, pRoomIndex ) ); tarea->rooms.push_back( pRoomIndex ); ++top_room; } return; } // Format of this section is identical to AFKMud. Let's cheat :) if( !str_cmp( word, "#EXIT" ) ) { fread_afk_exit( fp, pRoomIndex ); break; } // Format of this section is identical to AFKMud. Let's cheat :) if( !str_cmp( word, "#EXDESC" ) ) { extra_descr_data *ed = fread_afk_exdesc( fp ); if( ed ) pRoomIndex->extradesc.push_back( ed ); break; } // Format of this section is identical to AFKMud. Let's cheat :) if( !str_cmp( word, "#MUDPROG" ) ) { mud_prog_data *mprg = new mud_prog_data; fread_afk_mudprog( fp, mprg, pRoomIndex ); pRoomIndex->mudprogs.push_back( mprg ); ++top_prog; break; } break; case 'A': if( !str_cmp( word, "Affect" ) || !str_cmp( word, "AffectData" ) ) { affect_data *af = fread_fuss_affect( fp, word ); if( af ) pRoomIndex->permaffects.push_back( af ); break; } break; case 'D': KEY( "Desc", pRoomIndex->roomdesc, fread_string_nohash( fp ) ); break; case 'F': if( !str_cmp( word, "Flags" ) ) { flag_set( fp, pRoomIndex->flags, fuss_r_flags ); break; } break; case 'N': KEY( "Name", pRoomIndex->name, fread_string( fp ) ); break; // Format of this section is identical to AFKMud. Let's cheat :) case 'R': CLKEY( "Reset", pRoomIndex->load_reset( fp, false ) ); break; case 'S': if( !str_cmp( word, "Sector" ) ) { const char *sec_type = fread_flagstring( fp ); int sector = get_fuss_sectypes( sec_type ); if( sector < 0 || sector >= SECT_MAX ) { bug( "%s: Room #%d has bad sector type: %s", __func__, pRoomIndex->vnum, sec_type ); sector = 1; } pRoomIndex->sector_type = sector; pRoomIndex->winter_sector = -1; break; } if( !str_cmp( word, "Stats" ) ) { const char *ln = fread_line( fp ); int x1, x2, x3, x4; x1 = x2 = x3 = x4 = 0; sscanf( ln, "%d %d %d %d", &x1, &x2, &x3, &x4 ); pRoomIndex->tele_delay = x1; pRoomIndex->tele_vnum = x2; pRoomIndex->tunnel = x3; pRoomIndex->max_weight = x4; break; } break; case 'V': if( !str_cmp( word, "Vnum" ) ) { bool tmpBootDb = fBootDb; fBootDb = false; int vnum = fread_number( fp ); list < area_data * >::iterator iarea; for( iarea = arealist.begin( ); iarea != arealist.end( ); ++iarea ) { area_data *area = *iarea; if( !str_cmp( area->filename, tarea->filename ) ) continue; bool area_conflict = check_area_conflict( area, vnum, vnum ); if( area_conflict ) { log_printf( "ERROR: %s has vnum conflict with %s!", tarea->filename, ( area->filename ? area->filename : "(invalid)" ) ); log_printf( "%s occupies vnums : %-6d - %-6d", ( area->filename ? area->filename : "(invalid)" ), area->low_vnum, area->hi_vnum ); log_printf( "%s wants to use vnum: %-6d", tarea->filename, vnum ); log_string( "This is a fatal error. Program terminated." ); exit( 1 ); } } if( get_room_index( vnum ) ) { if( tmpBootDb ) { fBootDb = tmpBootDb; bug( "%s: vnum %d duplicated.", __func__, vnum ); // Try to recover, read to end of duplicated room and then bail out for( ;; ) { word = feof( fp ) ? "#ENDROOM" : fread_word( fp ); if( !str_cmp( word, "#ENDROOM" ) ) return; } } else { pRoomIndex = get_room_index( vnum ); log_printf_plus( LOG_BUILD, sysdata->build_level, "Cleaning room: %d", vnum ); pRoomIndex->clean_room( ); oldroom = true; } } else { pRoomIndex = new room_index; pRoomIndex->clean_room( ); } pRoomIndex->vnum = vnum; pRoomIndex->area = tarea; fBootDb = tmpBootDb; if( fBootDb ) { if( !tarea->low_vnum ) tarea->low_vnum = vnum; if( vnum > tarea->hi_vnum ) tarea->hi_vnum = vnum; } if( !pRoomIndex->resets.empty( ) ) { if( fBootDb ) { int count = 0; list < reset_data * >::iterator rst; bug( "%s: WARNING: resets already exist for this room.", __func__ ); for( rst = pRoomIndex->resets.begin( ); rst != pRoomIndex->resets.end( ); ++rst ) { reset_data *rtmp = *rst; ++count; if( !rtmp->resets.empty( ) ) count += rtmp->resets.size( ); } } else { /* * Clean out the old resets */ log_printf_plus( LOG_BUILD, sysdata->build_level, "Cleaning resets: %s", tarea->name ); pRoomIndex->clean_resets( ); } } break; } break; } } }