⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcgen_interface.c

📁 Npc Generator
💻 C
字号:
#include <ctype.h>
#include <string.h>

#include "npcEngine.h"#include "dndconst.h"#include "dndutil.h"#include "wtstream.h"#include "pcgen_interface.h"static int writeFeat( wtSTREAM_t* stream, NPCFEAT* feats, int type );static int writeSpells( wtSTREAM_t* stream, NPCCLASS* cls );static int computeMinimumXP( NPC* npc );static int getPCGenAlignmentCode( NPC* npc );static int mixCase( char* to, char* from );static int mixCase( char* to, char* from ) {  int i;  int upit;  strcpy( to, from );  upit = 1;  for( i = 0; to[i] != 0; i++ ) {    if( upit && isalpha( to[i] ) ) {      to[i] = toupper( to[i] );      upit = 0;    }    upit = ( !isalpha( to[i] ) && to[i] != '\'' );  }

  return 0;}static int writeFeat( wtSTREAM_t* stream, NPCFEAT* feats, int type ) {  NPCFEAT*       feat;  NPCFEATWEAPON* nfw;  NPCFEATSKILL*  nfs;  NPCFEATSCHOOL* nfsch;  NPCFEATSPELLS* nfsp;  int            count;  int            i;  char           buffer[ 128 ];  count = 0;  for( feat = feats; feat != 0; feat = feat->next ) {    if( feat->type == type ) {      count++;    }  }  if( count < 1 ) {    return 0;  }  mixCase( buffer, dndGetFeatName( type ) );  wtPrintf( stream, "%s:%d:", buffer, count );  for( feat = feats; feat != 0; feat = feat->next ) {    if( feat->type == type ) {      switch( feat->type ) {        case ftSPELLMASTERY:          nfsp = feat->data;          for( i = 0; i < 3; i++ ) {            mixCase( buffer, dndGetSpellName( nfsp->spells[ i ] ) );            wtPrintf( stream, "%s:", buffer );          }          break;        case ftSPELLFOCUS:          nfsch = feat->data;          mixCase( buffer, dndGetSchoolOfMagicName( nfsch->school ) );          wtPrintf( stream, "%s:", buffer );          break;        case ftWEAPONPROFICIENCY_SIMPLE:        case ftWEAPONPROFICIENCY_MARTIAL:        case ftWEAPONPROFICIENCY_EXOTIC:        case ftIMPROVEDCRITICAL:        case ftWEAPONFOCUS:        case ftWEAPONFINESSE:        case ftWEAPONSPECIALIZATION:          nfw = feat->data;          mixCase( buffer, dndGetWeaponName( nfw->weapon ) );          wtPrintf( stream, "%s:", buffer );          break;        case ftSKILLFOCUS:          nfs = feat->data;          mixCase( buffer, dndGetSkillName( nfs->skill ) );          wtPrintf( stream, "%s:", buffer );          break;      }    }  }  return 0;}static int writeSpells( wtSTREAM_t* stream, NPCCLASS* cls ) {  NPCSPELL** spells;  NPCSPELL*  spell;  int i;  char buffer[ 128 ];  switch( cls->type ) {    case pcWIZARD:   spells = ((NPCWIZARDDATA*)cls->data)->spells; break;    case pcBARD:     spells = ((NPCBARDDATA*)cls->data)->spells; break;    case pcSORCERER: spells = ((NPCSORCERERDATA*)cls->data)->spells; break;    default:      spells = 0;  }  if( spells != 0 ) {    for( i = 0; i < 10; i++ ) {      for( spell = spells[i]; spell != 0; spell = spell->next ) {        mixCase( buffer, dndGetSpellName( spell->spell ) );        wtPrintf( stream, "%s|Known Spells|1:", buffer );      }    }  }  wtPrintf( stream, "\n" );  if( cls->type == pcCLERIC) {    wtPrintf( stream, "\n" ); /* for Domain spells */  }  return 0;}static int computeMinimumXP( NPC* npc ) {  NPCCLASS* cls;  int       i;  int       xp;  xp = 0;  for( cls = npc->classes; cls != 0; cls = cls->next ) {    for( i = 0; i < cls->level; i++ ) {      xp += ( cls->level - 1 ) * 1000;    }  }  return xp;}static int getPCGenAlignmentCode( NPC* npc ) {  int code = 0;  if( npc->alignment & alLCNEUTRAL ) {    code = 3;  } else if( npc->alignment & alCHAOTIC ) {    code = 6;  }  if( npc->alignment & alGENEUTRAL ) {    code++;  } else if( npc->alignment & alEVIL ) {    code += 2;  }  return code;}int convertToPCGen( NPC* npc, wtSTREAM_t* stream ) {  NPCCLASS* cls;  int       i;  int       hp_per_lev;  int       hp_extra;  NPCFEAT*  feat;  NPCSKILL* skill;  NPCLANGUAGE* language;  int       is_literate;  char      buffer[ 128 ];  NPCCLERICDATA* clericData;  /* CAMPAIGNS line */  wtPrintf( stream, "CAMPAIGNS:D&D Dungeon Master's Guide:D&D Player's Handbook:D&D Monster Manual:S&S Relics & Rituals:\n" );  /* PC name */  wtPrintf( stream, "%s:\n", npc->name );  /* ability scores */  wtPrintf( stream, "%d:%d:%d:%d:%d:%d:0:0\n",          npc->strength - dndGetRaceBonus( npc->race, npc->gender, rbtABILITYSCORE, abSTRENGTH ),          npc->dexterity - dndGetRaceBonus( npc->race, npc->gender, rbtABILITYSCORE, abDEXTERITY ),          npc->constitution - dndGetRaceBonus( npc->race, npc->gender, rbtABILITYSCORE, abCONSTITUTION ),          npc->intelligence - dndGetRaceBonus( npc->race, npc->gender, rbtABILITYSCORE, abINTELLIGENCE ),          npc->wisdom - dndGetRaceBonus( npc->race, npc->gender, rbtABILITYSCORE, abWISDOM ),          npc->charisma - dndGetRaceBonus( npc->race, npc->gender, rbtABILITYSCORE, abCHARISMA ) );            /* classes */  for( cls = npc->classes; cls != 0; cls = cls->next ) {    mixCase( buffer, dndGetClassName( cls->type ) );    wtPrintf( stream, "%s:None :None :%d:", buffer, cls->level );    hp_per_lev = cls->hp / cls->level;    hp_extra = cls->hp % cls->level;    for( i = 0; i < cls->level; i++ ) {      wtPrintf( stream, "%d:", hp_per_lev + ( hp_extra > 0 ? 1 : 0 ) );      hp_extra--;    }    wtPrintf( stream, "0:" );    switch( cls->type ) {      case pcWIZARD:   wtPrintf( stream, "INT:" ); break;      case pcBARD:      case pcSORCERER: wtPrintf( stream, "CHA:" ); break;      case npcADEPT:      case pcDRUID:      case pcCLERIC:      case pcRANGER:   wtPrintf( stream, "WIS:" ); break;    }  }  wtPrintf( stream, "\n" );  for( feat = npc->feats; feat != 0; feat = feat->next ) {    switch( feat->type ) {      case ftSPELLMASTERY:      case ftSPELLFOCUS:      case ftWEAPONPROFICIENCY_SIMPLE:      case ftWEAPONPROFICIENCY_MARTIAL:      case ftWEAPONPROFICIENCY_EXOTIC:      case ftIMPROVEDCRITICAL:      case ftWEAPONFOCUS:      case ftWEAPONFINESSE:      case ftWEAPONSPECIALIZATION:      case ftSKILLFOCUS:        continue;    }    mixCase( buffer, dndGetFeatName( feat->type ) );    wtPrintf( stream, "%s:0:", buffer );  }  writeFeat( stream, npc->feats, ftSPELLMASTERY );  writeFeat( stream, npc->feats, ftSPELLFOCUS );  writeFeat( stream, npc->feats, ftWEAPONPROFICIENCY_SIMPLE );  writeFeat( stream, npc->feats, ftWEAPONPROFICIENCY_MARTIAL );  writeFeat( stream, npc->feats, ftWEAPONPROFICIENCY_EXOTIC );  writeFeat( stream, npc->feats, ftIMPROVEDCRITICAL );  writeFeat( stream, npc->feats, ftWEAPONFOCUS );  writeFeat( stream, npc->feats, ftWEAPONFINESSE );  writeFeat( stream, npc->feats, ftWEAPONSPECIALIZATION );  writeFeat( stream, npc->feats, ftSKILLFOCUS );  wtPrintf( stream, "\n" );  for( skill = npc->skills; skill != 0; skill = skill->next ) {    mixCase( buffer, dndGetSkillName( skill->type ) );    wtPrintf( stream, "%s:%g:", buffer, skill->rank );  }  wtPrintf( stream, "\n" );  /* Deity, and domains (for clerics) */  wtPrintf( stream, "None:" );  for( cls = npc->classes; cls != 0; cls = cls->next ) {    if( cls->type == pcCLERIC ) {      clericData = (NPCCLERICDATA*)cls->data;      mixCase( buffer, dndGetDomainName( clericData->domain[0] ) );      wtPrintf( stream, "%s:", buffer );      mixCase( buffer, dndGetDomainName( clericData->domain[1] ) );      wtPrintf( stream, "%s:", buffer );      break;    }  }  wtPrintf( stream, "\n" );  switch( npc->race ) {    case rcELF_HIGH: strcpy( buffer, "Elf" ); break;    case rcDWARF_HILL: strcpy( buffer, "Dwarf" ); break;    case rcGNOME_ROCK: strcpy( buffer, "Gnome" ); break;    case rcHALFLING_LIGHTFOOT: strcpy( buffer, "Halfling" ); break;    default:      mixCase( buffer, dndGetRaceName( npc->race ) );  }  wtPrintf( stream, "%s:%d:%d:%d:%d:%c:Right\n",          buffer, getPCGenAlignmentCode( npc ), npc->height_ft * 12 + npc->height_in,          npc->weight, npc->age, ( npc->gender == gMALE ? 'M' : 'F' ) );  is_literate = 0;  for( cls = npc->classes; cls != 0; cls = cls->next ) {    writeSpells( stream, cls );    is_literate = ( is_literate || ( cls->type != pcBARBARIAN ) );  }  for( language = npc->languages; language != 0; language = language->next ) {    mixCase( buffer, dndGetLanguageName( language->language ) );    wtPrintf( stream, "%s:", buffer );  }  if( is_literate ) wtPrintf( stream, "Literacy:" );  wtPrintf( stream, "\n" );  wtPrintf( stream, "\n" ); /* proficient weapons -- unimplemented */  wtPrintf( stream, "0:0:\n" );  wtPrintf( stream, " : : : : : : : : : : : :\n" );  wtPrintf( stream, "\n" );  wtPrintf( stream, "%d:  :  :\n", npcGearValue( npc ) );  for( cls = npc->classes; cls != 0; cls = cls->next ) {    mixCase( buffer, dndGetClassName( cls->type ) );    wtPrintf( stream, "%s:\n", buffer );    if( cls->type == pcCLERIC ) {      wtPrintf( stream, "Domain:\n" );    }  }  wtPrintf( stream, "%d: : : :0:0:\n", computeMinimumXP( npc ) );  for( cls = npc->classes; cls != 0; cls = cls->next ) {    mixCase( buffer, dndGetClassName( cls->type ) );    wtPrintf( stream, "%s:\n", buffer );    if( cls->type == pcCLERIC ) {      wtPrintf( stream, "Domain:\n" );    }  }  wtPrintf( stream, "TEMPLATE:" );

  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -