Пример #1
0
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;
      }
   }
}
Пример #2
0
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 );
      }
   }
}
Пример #3
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;
      }
   }
}