//
// E_processGamePropsBlock
//
// Process a single gameproperties block.
//
static void E_processGamePropsBlock(cfg_t *props)
{
   // Flags

   if(IS_SET(ITEM_GPROP_FLAGSADD))
   {
      const char *flagstr = cfg_getstr(props, ITEM_GPROP_FLAGSADD);

      GameModeInfo->flags |= E_ParseFlags(flagstr, &gmi_flagset);
   }

   if(IS_SET(ITEM_GPROP_FLAGSREM))
   {
      const char *flagstr = cfg_getstr(props, ITEM_GPROP_FLAGSREM);
      unsigned int curFlags = GameModeInfo->flags;

      GameModeInfo->flags &= ~E_ParseFlags(flagstr, &gmi_flagset);

      GameModeInfo->flags |= (curFlags & GIF_SHAREWARE); // nice try, bitch.
   }

   if(IS_SET(ITEM_GPROP_MFLAGSADD))
   {
      const char *flagstr = cfg_getstr(props, ITEM_GPROP_MFLAGSADD);

      GameModeInfo->missionInfo->flags |= E_ParseFlags(flagstr, &mission_flagset);
   }

   if(IS_SET(ITEM_GPROP_MFLAGSREM))
   {
      const char *flagstr = cfg_getstr(props, ITEM_GPROP_MFLAGSREM);

      GameModeInfo->missionInfo->flags &= ~E_ParseFlags(flagstr, &mission_flagset);
   }

   // Demo Loop Properties

   if(IS_SET(ITEM_GPROP_TITLETICS))
      GameModeInfo->titleTics = cfg_getint(props, ITEM_GPROP_TITLETICS);
   
   if(IS_SET(ITEM_GPROP_ADVISORTICS))
      GameModeInfo->advisorTics = cfg_getint(props, ITEM_GPROP_ADVISORTICS);
   
   if(IS_SET(ITEM_GPROP_PAGETICS))
      GameModeInfo->pageTics = cfg_getint(props, ITEM_GPROP_PAGETICS);

   // Menu Properties
   if(IS_SET(ITEM_GPROP_MENUBKGND))
   {
      E_setDynamicString(GameModeInfo->menuBackground, GI_STR_MENUBKGND, 
                         cfg_getstr(props, ITEM_GPROP_MENUBKGND));
   }

   if(IS_SET(ITEM_GPROP_TRANSFRAME))
   {
      int stateNum = E_StateNumForName(cfg_getstr(props, ITEM_GPROP_TRANSFRAME));

      if(stateNum >= 0 &&
         (states[stateNum]->dehnum >= 0 || E_AutoAllocStateDEHNum(stateNum)))
      {
         GameModeInfo->transFrame = states[stateNum]->dehnum;
      }
   }

   if(IS_SET(ITEM_GPROP_MENUSKVASND))
   {
      sfxinfo_t *snd = E_SoundForName(cfg_getstr(props, ITEM_GPROP_MENUSKVASND));

      if(snd && (snd->dehackednum >= 0 || E_AutoAllocSoundDEHNum(snd)))
         GameModeInfo->skvAtkSound = snd->dehackednum;
   }

   if(IS_SET(ITEM_GPROP_MENUOFFSET))
      GameModeInfo->menuOffset = cfg_getint(props, ITEM_GPROP_MENUOFFSET);

   if(IS_SET(ITEM_GPROP_MENUPTR1) && GameModeInfo->menuCursor->numpatches >= 1)
   {
      E_setDynamicString(GameModeInfo->menuCursor->patches[0], GI_STR_MENUPTR1,
                         cfg_getstr(props, ITEM_GPROP_MENUPTR1));
   }

   if(IS_SET(ITEM_GPROP_MENUPTR2) && GameModeInfo->menuCursor->numpatches >= 2)
   {
      E_setDynamicString(GameModeInfo->menuCursor->patches[1], GI_STR_MENUPTR2,
                         cfg_getstr(props, ITEM_GPROP_MENUPTR2));
   }

   // Border Properties

   if(IS_SET(ITEM_GPROP_BORDERFLAT))
   {
      E_setDynamicString(GameModeInfo->borderFlat, GI_STR_BORDERFLAT,
                         cfg_getstr(props, ITEM_GPROP_BORDERFLAT));
   }

   if(IS_SET(ITEM_GPROP_BORDERTL))
   {
      E_setDynamicString(GameModeInfo->border->c_tl, GI_STR_BORDERTL, 
                         cfg_getstr(props, ITEM_GPROP_BORDERTL));
   }

   if(IS_SET(ITEM_GPROP_BORDERTOP))
   {
      E_setDynamicString(GameModeInfo->border->top, GI_STR_BORDERTOP, 
                         cfg_getstr(props, ITEM_GPROP_BORDERTOP));
   }

   if(IS_SET(ITEM_GPROP_BORDERTR))
   {
      E_setDynamicString(GameModeInfo->border->c_tr, GI_STR_BORDERTR, 
                         cfg_getstr(props, ITEM_GPROP_BORDERTR));
   }

   if(IS_SET(ITEM_GPROP_BORDERLEFT))
   {
      E_setDynamicString(GameModeInfo->border->left, GI_STR_BORDERLEFT, 
                         cfg_getstr(props, ITEM_GPROP_BORDERLEFT));
   }

   if(IS_SET(ITEM_GPROP_BORDERRIGHT))
   {
      E_setDynamicString(GameModeInfo->border->right, GI_STR_BORDERRIGHT, 
                         cfg_getstr(props, ITEM_GPROP_BORDERRIGHT));
   }

   if(IS_SET(ITEM_GPROP_BORDERBL))
   {
      E_setDynamicString(GameModeInfo->border->c_bl, GI_STR_BORDERBL, 
                         cfg_getstr(props, ITEM_GPROP_BORDERBL));
   }

   if(IS_SET(ITEM_GPROP_BORDERBOTT))
   {
      E_setDynamicString(GameModeInfo->border->bottom, GI_STR_BORDERBOTT, 
                         cfg_getstr(props, ITEM_GPROP_BORDERBOTT));
   }

   if(IS_SET(ITEM_GPROP_BORDERBR))
   {
      E_setDynamicString(GameModeInfo->border->c_br, GI_STR_BORDERBR, 
                         cfg_getstr(props, ITEM_GPROP_BORDERBR));
   }

   // Console Properties

   if(IS_SET(ITEM_GPROP_CCHARSPERLN))
      GameModeInfo->c_numCharsPerLine = cfg_getint(props, ITEM_GPROP_CCHARSPERLN);

   if(IS_SET(ITEM_GPROP_CBELLSOUND))
   {
      sfxinfo_t *snd = E_SoundForName(cfg_getstr(props, ITEM_GPROP_CBELLSOUND));

      if(snd && (snd->dehackednum >= 0 || E_AutoAllocSoundDEHNum(snd)))
         GameModeInfo->c_BellSound = snd->dehackednum;
   }

   if(IS_SET(ITEM_GPROP_CCHATSOUND))
   {
      sfxinfo_t *snd = E_SoundForName(cfg_getstr(props, ITEM_GPROP_CCHATSOUND));

      if(snd && (snd->dehackednum >= 0 || E_AutoAllocSoundDEHNum(snd)))
         GameModeInfo->c_ChatSound = snd->dehackednum;
   }

   if(IS_SET(ITEM_GPROP_CBACKDROP))
   {
      E_setDynamicString(GameModeInfo->consoleBack, GI_STR_CBACKDROP,
                         cfg_getstr(props, ITEM_GPROP_CBACKDROP));
   }

   // HUD Properties

   if(IS_SET(ITEM_GPROP_PAUSEPATCH))
   {
      E_setDynamicString(GameModeInfo->pausePatch, GI_STR_PAUSEPATCH,
                         cfg_getstr(props, ITEM_GPROP_PAUSEPATCH));
   }

   // Gamesim Properties

   if(IS_SET(ITEM_GPROP_PUFFTYPE))
   {
      const char *name = cfg_getstr(props, ITEM_GPROP_PUFFTYPE);

      if(E_ThingNumForName(name) >= 0)
         E_setDynamicString(GameModeInfo->puffType, GI_STR_PUFFTYPE, name);
   }

   if(IS_SET(ITEM_GPROP_TELEFOGTYPE))
   {
      const char *name = cfg_getstr(props, ITEM_GPROP_TELEFOGTYPE);

      if(E_ThingNumForName(name) >= 0)
         E_setDynamicString(GameModeInfo->teleFogType, GI_STR_TELEFOGTYPE, name);
   }

   if(IS_SET(ITEM_GPROP_TELEFOGHT))
   {
      int num = cfg_getint(props, ITEM_GPROP_TELEFOGHT);

      GameModeInfo->teleFogHeight = num * FRACUNIT;
   }

   if(IS_SET(ITEM_GPROP_TELESOUND))
   {
      sfxinfo_t *snd = E_SoundForName(cfg_getstr(props, ITEM_GPROP_TELESOUND));

      if(snd && (snd->dehackednum >= 0 || E_AutoAllocSoundDEHNum(snd)))
         GameModeInfo->teleSound = snd->dehackednum;
   }

   if(IS_SET(ITEM_GPROP_THRUSTFACTR))
      GameModeInfo->thrustFactor = (int16_t)cfg_getint(props, ITEM_GPROP_THRUSTFACTR);

   if(IS_SET(ITEM_GPROP_DEFPCLASS))
   {
      E_setDynamicString(GameModeInfo->defPClassName, GI_STR_DEFPCLASS,
                         cfg_getstr(props, ITEM_GPROP_DEFPCLASS));
   }

   // Determines behavior of the Teleport_EndGame line special when LevelInfo
   // has not provided a specific finale type for the level.
   if(IS_SET(ITEM_GPROP_FINTYPE))
   {
      int finaleType = E_StrToNumLinear(finaleTypeStrs, FINALE_NUMFINALES, 
                                        cfg_getstr(props, ITEM_GPROP_FINTYPE));

      if(finaleType >= 0 && finaleType < FINALE_NUMFINALES)
         GameModeInfo->teleEndGameFinaleType = finaleType;
   }

   // Finale Properties

   if(IS_SET(ITEM_GPROP_FINALEX))
      GameModeInfo->fTextPos->x = cfg_getint(props, ITEM_GPROP_FINALEX);

   if(IS_SET(ITEM_GPROP_FINALEY))
      GameModeInfo->fTextPos->y = cfg_getint(props, ITEM_GPROP_FINALEY);

   if(IS_SET(ITEM_GPROP_CASTTITLEY))
      GameModeInfo->castTitleY = cfg_getint(props, ITEM_GPROP_CASTTITLEY);

   if(IS_SET(ITEM_GPROP_CASTNAMEY))
      GameModeInfo->castNameY = cfg_getint(props, ITEM_GPROP_CASTNAMEY);

   // Intermission Properties

   if(IS_SET(ITEM_GPROP_INTERPIC))
   {
      E_setDynamicString(GameModeInfo->interPic, GI_STR_INTERPIC,
                         cfg_getstr(props, ITEM_GPROP_INTERPIC));
   }

   // Sound Properties

   if(IS_SET(ITEM_GPROP_DEFMUSNAME))
   {
      E_setDynamicString(GameModeInfo->defMusName, GI_STR_DEFMUSNAME,
                         cfg_getstr(props, ITEM_GPROP_DEFMUSNAME));
   }

   if(IS_SET(ITEM_GPROP_DEFSNDNAME))
   {
      E_setDynamicString(GameModeInfo->defSoundName, GI_STR_DEFSNDNAME,
                         cfg_getstr(props, ITEM_GPROP_DEFSNDNAME));
   }
   
   // Credit Screen Properties

   if(IS_SET(ITEM_GPROP_CREDITBKGND))
   {
      E_setDynamicString(GameModeInfo->creditBackground, GI_STR_CREDITBKGND,
                         cfg_getstr(props, ITEM_GPROP_CREDITBKGND));
   }

   if(IS_SET(ITEM_GPROP_CREDITY))
      GameModeInfo->creditY = cfg_getint(props, ITEM_GPROP_CREDITY);

   if(IS_SET(ITEM_GPROP_CREDITTSTEP))
      GameModeInfo->creditTitleStep = cfg_getint(props, ITEM_GPROP_CREDITTSTEP);
   
   // Exit Properties
   
   if(IS_SET(ITEM_GPROP_ENDTEXTNAME))
   {
      E_setDynamicString(GameModeInfo->endTextName, GI_STR_ENDTEXTNAME,
                         cfg_getstr(props, ITEM_GPROP_ENDTEXTNAME));
   }
}
Beispiel #2
0
//
// E_ProcessCast
//
// Creates the DOOM II cast call information
//
static void E_ProcessCast(cfg_t *cfg)
{
   static bool firsttime = true;
   int i, numcastorder = 0, numcastsections = 0;
   cfg_t **ci_order;

   E_EDFLogPuts("\t* Processing cast call\n");
   
   // get number of cast sections
   numcastsections = cfg_size(cfg, SEC_CAST);

   if(firsttime && !numcastsections) // on main parse, at least one is required.
      E_EDFLoggedErr(2, "E_ProcessCast: no cast members defined.\n");

   firsttime = false;

   E_EDFLogPrintf("\t\t%d cast member(s) defined\n", numcastsections);

   // haleyjd 11/21/11: allow multiple runs
   if(castorder)
   {
      int i;

      // free names
      for(i = 0; i < max_castorder; i++)
      {
         if(castorder[i].name)
            efree(castorder[i].name);
      }
      // free castorder
      efree(castorder);
      castorder = NULL;
      max_castorder = 0;
   }

   // check if the "castorder" array is defined for imposing an
   // order on the castinfo sections
   numcastorder = cfg_size(cfg, SEC_CASTORDER);

   E_EDFLogPrintf("\t\t%d cast member(s) in castorder\n", numcastorder);

   // determine size of castorder
   max_castorder = (numcastorder > 0) ? numcastorder : numcastsections;

   // allocate with size+1 for an end marker
   castorder = estructalloc(castinfo_t, max_castorder + 1);
   ci_order  = ecalloc(cfg_t **, sizeof(cfg_t *), max_castorder);

   if(numcastorder > 0)
   {
      for(i = 0; i < numcastorder; ++i)
      {
         const char *title = cfg_getnstr(cfg, SEC_CASTORDER, i);         
         cfg_t *section    = cfg_gettsec(cfg, SEC_CAST, title);

         if(!section)
         {
            E_EDFLoggedErr(2, 
               "E_ProcessCast: unknown cast member '%s' in castorder\n", 
               title);
         }

         ci_order[i] = section;
      }
   }
   else
   {
      // no castorder array is defined, so use the cast members
      // in the order they are encountered (for backward compatibility)
      for(i = 0; i < numcastsections; ++i)
         ci_order[i] = cfg_getnsec(cfg, SEC_CAST, i);
   }


   for(i = 0; i < max_castorder; ++i)
   {
      int j;
      const char *tempstr;
      int tempint = 0;
      cfg_t *castsec = ci_order[i];

      // resolve thing type
      tempstr = cfg_getstr(castsec, ITEM_CAST_TYPE);
      if(!tempstr || 
         (tempint = E_ThingNumForName(tempstr)) == -1)
      {
         E_EDFLoggedWarning(2, "Warning: cast %d: unknown thing type %s\n",
                            i, tempstr);

         tempint = UnknownThingType;
      }
      castorder[i].type = tempint;

      // get cast name, if any -- the first seventeen entries can
      // default to using the internal string editable via BEX strings
      tempstr = cfg_getstr(castsec, ITEM_CAST_NAME);
      if(cfg_size(castsec, ITEM_CAST_NAME) == 0 && i < 17)
         castorder[i].name = NULL; // set from DeHackEd
      else
         castorder[i].name = estrdup(tempstr); // store provided value

      // get stopattack flag (used by player)
      castorder[i].stopattack = cfg_getbool(castsec, ITEM_CAST_SA);

      // process sound blocks (up to four will be processed)
      tempint = cfg_size(castsec, ITEM_CAST_SOUND);
      for(j = 0; j < 4; ++j)
      {
         castorder[i].sounds[j].frame = 0;
         castorder[i].sounds[j].sound = 0;
      }
      for(j = 0; j < tempint && j < 4; ++j)
      {
         int num;
         sfxinfo_t *sfx;
         const char *name;
         cfg_t *soundsec = cfg_getnsec(castsec, ITEM_CAST_SOUND, j);

         // if these are invalid, just fill them with zero rather
         // than causing an error, as they're very unimportant

         // name of sound to play
         name = cfg_getstr(soundsec, ITEM_CAST_SOUNDNAME);
         
         // haleyjd 03/22/06: modified to support dehnum auto-allocation
         if((sfx = E_EDFSoundForName(name)) == NULL)
         {
            E_EDFLoggedWarning(2, "Warning: cast member references invalid sound %s\n",
                               name);
            castorder[i].sounds[j].sound = 0;
         }
         else
         {
            if(sfx->dehackednum != -1 || E_AutoAllocSoundDEHNum(sfx))
               castorder[i].sounds[j].sound = sfx->dehackednum;
            else
            {
               E_EDFLoggedWarning(2, "Warning: could not auto-allocate a DeHackEd number "
                                     "for sound %s\n", name);
               castorder[i].sounds[j].sound = 0;
            }
         }

         // name of frame that triggers sound event
         name = cfg_getstr(soundsec, ITEM_CAST_SOUNDFRAME);
         if((num = E_StateNumForName(name)) < 0)
            num = 0;
         castorder[i].sounds[j].frame = num;
      }
   }

   // initialize the end marker to all zeroes
   memset(&castorder[max_castorder], 0, sizeof(castinfo_t));

   // free the ci_order table
   efree(ci_order);
}