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; } } }
SKILLTYPE *fread_skill( FILE * fp, bool Player ) { char buf[MAX_STRING_LENGTH]; const char *word; bool fMatch; SKILLTYPE *skill; CREATE( skill, SKILLTYPE, 1 ); skill->guild = -1; skill->style = -1; for( ;; ) { word = feof( fp ) ? "End" : fread_word( fp ); fMatch = FALSE; switch ( UPPER( word[0] ) ) { case '*': fMatch = TRUE; fread_to_eol( fp ); break; case 'A': KEY( "Alignment", skill->alignment, fread_number( fp ) ); if( !str_cmp( word, "Affect" ) || !str_cmp( word, "AffectData" ) ) { AFFECT_DATA *aff = fread_fuss_affect( fp, word ); if( aff ) LINK( aff, skill->first_affect, skill->last_affect, next, prev ); fMatch = TRUE; break; } break; case 'C': KEY( "Charge", skill->charge, fread_float( fp ) ); if ( !str_cmp( word, "Code" ) ) { if( Player ) break; SPELL_FUN *spellfun; DO_FUN *dofun; const char *w = fread_word( fp ); fMatch = TRUE; if( !str_cmp( word, "(null)" ) ) break; else if( !str_prefix( "do_", w ) && ( dofun = skill_function(w) ) != skill_notfound ) { skill->skill_fun = dofun; skill->spell_fun = NULL; skill->skill_fun_name = str_dup(w); } else if( str_prefix( "do_", w ) && ( spellfun = spell_function(w) ) != spell_notfound ) { skill->spell_fun = spellfun; skill->skill_fun = NULL; skill->spell_fun_name = str_dup(w); } else { bug( "%s: unknown skill/spell %s", __FUNCTION__, w ); skill->spell_fun = spell_null; } break; } KEY( "Components", skill->components, fread_string( fp ) ); KEY( "Cooldown", skill->cooldown, fread_number( fp ) ); KEY( "Cost", skill->cost, fread_bitvector( fp ) ); break; case 'D': KEY( "DamageDetails", skill->base_roll_boost, fread_float( fp ) ); KEY( "Dammsg", skill->noun_damage, fread_string( fp ) ); KEY( "Damtype", skill->damtype, fread_bitvector( fp ) ); KEY( "Dice", skill->dice, fread_string( fp ) ); KEY( "Diechar", skill->die_char, fread_string( fp ) ); KEY( "Dieroom", skill->die_room, fread_string( fp ) ); KEY( "Dievict", skill->die_vict, fread_string( fp ) ); KEY( "Difficulty", skill->difficulty, fread_number( fp ) ); break; case 'E': if( !str_cmp( word, "End" ) ) return skill; break; case 'F': if( !str_cmp( word, "FactorID" ) ) { FACTOR_DATA *factor; fMatch = TRUE; if( ( factor = copy_factor( get_factor_from_id( fread_number( fp ) ) ) ) == NULL ) break; LINK( factor, skill->first_factor, skill->last_factor, next, prev ); break; } KEY( "Flags", skill->flags, fread_number( fp ) ); break; case 'G': KEY( "Guild", skill->guild, fread_number( fp ) ); break; case 'H': KEY( "Hitchar", skill->hit_char, fread_string( fp ) ); KEY( "Hitroom", skill->hit_room, fread_string( fp ) ); KEY( "Hitvict", skill->hit_vict, fread_string( fp ) ); KEY( "HP", skill->min_hp, fread_number( fp ) ); break; case 'I': KEY( "Immchar", skill->imm_char, fread_string( fp ) ); KEY( "Immroom", skill->imm_room, fread_string( fp ) ); KEY( "Immvict", skill->imm_vict, fread_string( fp ) ); break; case 'M': KEY( "Mana", skill->min_mana, fread_number( fp ) ); KEY( "Minlevel", skill->min_level, fread_number( fp ) ); KEY( "Minpos", skill->minimum_position, fread_number( fp ) ); KEY( "Misschar", skill->miss_char, fread_string( fp ) ); KEY( "Missroom", skill->miss_room, fread_string( fp ) ); KEY( "Missvict", skill->miss_vict, fread_string( fp ) ); KEY( "Move", skill->min_move, fread_number( fp ) ); break; case 'N': KEY( "Name", skill->name, fread_string( fp ) ); break; case 'P': KEY( "Participants", skill->participants, fread_number( fp ) ); break; case 'R': KEY( "Rounds", skill->beats, fread_number( fp ) ); break; case 'S': KEY( "Saves", skill->saves, fread_number( fp ) ); KEY( "Slot", skill->slot, fread_number( fp ) ); if( !str_cmp( word, "StatBoost" ) ) { STAT_BOOST *stat_boost; fMatch = TRUE; CREATE( stat_boost, STAT_BOOST, 1 ); stat_boost->from_id = fread_number( fp ); stat_boost->location = fread_number( fp ); stat_boost->modifier = fread_float( fp ); LINK( stat_boost, skill->first_statboost, skill->last_statboost, next, prev ); } KEY( "Style", skill->style, fread_number( fp ) ); break; case 'T': KEY( "Target", skill->target, fread_number( fp ) ); KEY( "Teachers", skill->teachers, fread_string( fp ) ); KEY( "Threat", skill->threat, fread_number( fp ) ); KEY( "Type", skill->type, get_skill( fread_word( fp ) ) ); break; case 'V': KEY( "Value", skill->value, fread_number( fp ) ); break; case 'W': KEY( "Wearoff", skill->msg_off, fread_string( fp ) ); break; } if( !fMatch ) { sprintf( buf, "Fread_skill: no match: %s", word ); bug( buf, 0 ); } } }
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; } } }