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

📄 npc_console.c

📁 Npc Generator
💻 C
📖 第 1 页 / 共 2 页
字号:
\n\  The -o options are for the stat-block output.  They mean:\n\    a: ability bonuses\n\    c: AC breakdown\n\    i: initiative breakdown\n\    b: attack breakdown\n\    s: saving throw breakdown\n\    k: skill breakdown\n\    l: languages\n\    f: skills and feats\n\    p: posessions\n\    S: spells\n\\n\  The -w option is for determining the output format.  It means:\n\    p: output in PCGen format.\n\    s: output in stat-block format.\n\\n\  <path>, when doing stat-block output (-ws), is the name of a file, in\n\  which case the output is all redirected to that file.  When doing\n\  PCGen output (-wp), <path> is the name of a directory, in which case\n\  each NPC is created in a separate file in the given directory.\n\"static int usage() {  puts( USAGE );  exit(0);}static int getLookup( char* parmName, char* arg, LOOKUP_TBL* list ) {  int i;  int found;  i = lookup( arg, list, &found );  if( !found ) {    printf( "Invalid %s: '%s'\n", parmName, arg );    usage();  }  return i;}static void getHomeDirectory( char* home ) {  uid_t uid;  struct passwd *pwd;  uid = geteuid();  pwd = getpwuid( uid );  strcpy( home, pwd->pw_dir );  if( home[ strlen( home ) - 1 ] != '/' ) {    strcat( home, "/" );  }}static int parseCommandLine( int argc, char* argv[], NPC_OPTS* opts ) {  int c;  int i;  int found;  int class_count;  int level_count;  LOOKUP_TBL* list;  memset( opts, 0, sizeof( *opts ) );  opts->race = raceANY_CORE;  opts->classes[0] = classANY;  opts->classes[1] = classNONE;  opts->classes[2] = classNONE;  opts->levels[0] = levelANY;  opts->levels[1] = levelANY;  opts->levels[2] = levelANY;  opts->score_strategy = 1;  opts->count = 1;  opts->gender = gANY;  opts->wrap = 0;  getHomeDirectory( opts->data_path );  strcat( opts->data_path, ".npc/" );  class_count = 0;  level_count = 0;  srand( time( NULL ) );  while( ( c = getopt( argc, argv, "r:c:l:s:a:S:g:n:h::bo:p:w:W:d:" ) ) != -1 ) {    switch( c ) {      case 'r':        opts->race = getLookup( "race", optarg, racetypes );        break;      case 'c':        opts->classes[ class_count++ ] = getLookup( "class", optarg, classtypes );        break;      case 'l':        opts->levels[ level_count ] = lookup( optarg, levels, &found );        if( !found ) {          opts->levels[ level_count ] = atoi( optarg );          if( opts->levels[ level_count ] < 1 ) {            printf( "Invalid level specification: %s\n", optarg );            usage();          }        }        level_count++;        break;      case 's':        opts->score_strategy = getLookup( "strategy", optarg, strategies_lookup );        break;      case 'a':        opts->alignment = getLookup( "alignment", optarg, alignments );        break;      case 'S':        opts->seed = atoi( optarg );        srand( opts->seed );        break;      case 'g':        opts->gender = getLookup( "gender", optarg, genders );        break;      case 'h':        if( optarg == 0 ) {          usage();        } else {          i = lookup( optarg, help_lists, &found );          switch( i ) {            case HELP_RACES:      list = racetypes; break;            case HELP_CLASSES:    list = classtypes; break;            case HELP_ALIGNMENTS: list = alignments; break;            case HELP_GENDERS:    list = genders; break;            case HELP_STRATEGIES: list = strategies_lookup; break;            default:              usage();          }          for( i = 0; list[ i ].name != 0; i++ ) {            printf( "  %s\n", list[ i ].name );          }          printf( "\n" );        }        exit( 0 );      case 'n':        opts->count = atoi( optarg );        break;      case 'b':        opts->background = !opts->background;        break;      case 'o':        for( i = 0; optarg[i]; i++ ) {          switch( optarg[i] ) {            case 'a': opts->opts.abilityBonuses = !opts->opts.abilityBonuses; break;            case 'c': opts->opts.acBreakdown = !opts->opts.acBreakdown; break;            case 'i': opts->opts.initBreakdown = !opts->opts.initBreakdown; break;            case 'b': opts->opts.attackBreakdown = !opts->opts.attackBreakdown; break;            case 's': opts->opts.saveBreakdown = !opts->opts.saveBreakdown; break;            case 'k': opts->opts.skillBreakdown = !opts->opts.skillBreakdown; break;            case 'l': opts->opts.languages = !opts->opts.languages; break;            case 'f': opts->opts.skillsAndFeats = !opts->opts.skillsAndFeats; break;            case 'p': opts->opts.possessions = !opts->opts.possessions; break;            case 'S': opts->opts.spells = !opts->opts.spells; break;            default:              printf( "Invalid stat-block format specifier: %c\n", optarg[i] );              usage();          }        }        break;      case 'w':        for( i = 0; optarg[i]; i++ ) {          switch( optarg[i] ) {            case 's': opts->mode = MODE_STATBLOCK; break;            case 'p': opts->mode = MODE_PCGEN; break;            default:              printf( "Invalid output mode specifier: %c\n", optarg[i] );              usage();          }        }        break;      case 'p':        strcpy( opts->path, optarg );        break;      case 'W':        opts->wrap = atoi( optarg );        break;      case 'd':        strcpy( opts->data_path, optarg );        if( opts->data_path[ strlen( opts->data_path )-1 ] != '/' ) {          strcat( opts->data_path, "/" );        }        break;      default:        usage();    }  }  return 0;}static void wrapLines( char* string, int width ) {  int     c;  int     count;  int     i;  int     last;  if( width > 0 ) {    count = width+1;    last = 0;    while( count < strlen( string ) ) {      for( i = last; i < count; i++ ) {        if( string[i] == '\n' )          break;      }      if( string[i] != '\n' ) {        for( i = count; i > 0; i-- ) {          c = string[i];          if( isspace( c ) ) {            string[i] = '\n';            break;          }        }      }      last = i+1;      count = i + width+1;    }  }}static int displayNPC_StatBlock( NPC_OPTS* opts, wtSTREAM_t *stream, NPC* npc ) {  char    statBlock[4096];  int     count;  int     i;  int     doBg;  char    motivation1[ 1024 ];  char    motivation2[ 1024 ];  grGRAMMAR* grammar;  if( opts->background ) {    grammar = openNPCMotivationGrammar( opts->data_path );  }  npcBuildStatBlock( npc, &opts->opts, statBlock, sizeof( statBlock ) );  strrepl( statBlock, "~B", "" );  strrepl( statBlock, "~b", "" );  strrepl( statBlock, "~I", "" );  strrepl( statBlock, "~i", "" );  wrapLines( statBlock, opts->wrap );  wtPrint( stream, statBlock );  if( opts->background ) {    grammar->startSymbol = "[motivation]";    getNPCMotivation( grammar, npc, motivation1, sizeof( motivation1 ) );    do {            getNPCMotivation( grammar, npc, motivation2, sizeof( motivation1 ) );    } while( strcmp( motivation1, motivation2 ) == 0 );    strcpy( statBlock, "Primary motivation: " );    strcat( statBlock, motivation1 );    wrapLines( statBlock, opts->wrap );    wtPrintf( stream, "\n\n%s\n", statBlock );    strcpy( statBlock, "Secondary motivation: " );    strcat( statBlock, motivation2 );    wrapLines( statBlock, opts->wrap );    wtPrintf( stream, "\n%s\n", statBlock );    getNPCRecentPast( grammar, npc, motivation1, sizeof( motivation1 ) );    strcpy( statBlock, "Recent Past: " );    strcat( statBlock, motivation1 );    wrapLines( statBlock, opts->wrap );    wtPrintf( stream, "\n%s\n", statBlock );  }  if( opts->background ) {    grDestroyGrammar( grammar );  }  wtPrintf( stream, "\n" );  return 0;}int main( int argc, char* argv[] ) {  char buffer[512];  int i;  wtSTREAM_t* stream;         NPC* npc;  NPCGENERATOROPTS opts;  NPCGENERATOROPTS tempOpts;  NPC_OPTS cmd_opts;  if( parseCommandLine( argc, argv, &cmd_opts ) != 0 ) {    return 0;  }  opts.raceType  = cmd_opts.race;  opts.gender    = cmd_opts.gender;  opts.alignment = cmd_opts.alignment;  opts.level[0]  = cmd_opts.levels[0];  opts.level[1]  = cmd_opts.levels[1];  opts.level[2]  = cmd_opts.levels[2];  opts.classType[0] = cmd_opts.classes[0];  opts.classType[1] = cmd_opts.classes[1];  opts.classType[2] = cmd_opts.classes[2];  opts.abilityScoreStrategy = strategies[ cmd_opts.score_strategy ];  opts.filePath = cmd_opts.data_path;  if( cmd_opts.mode == MODE_STATBLOCK && cmd_opts.path[0] != 0 ) {    stream = wtOpenFileStream( cmd_opts.path, "w" );  } else {    stream = wtOpenFileStreamFromHandle( stdout );  }  for( i = 0; i < cmd_opts.count; i++ ) {    memcpy( &tempOpts, &opts, sizeof( tempOpts ) );    npc = npcGenerateNPC( &tempOpts );    if( cmd_opts.mode == MODE_STATBLOCK ) {      displayNPC_StatBlock( &cmd_opts, stream, npc );      if( i+1 < cmd_opts.count ) {        wtPrint( stream, "---------------------------\n" );      }    } else if( cmd_opts.mode == MODE_PCGEN ) {      if( cmd_opts.path[0] != 0 ) {        wtCloseStream( stream );        strcpy( buffer, cmd_opts.path );        strcat( buffer, "/" );        strcat( buffer, npc->name );        strcat( buffer, ".pcg" );        stream = wtOpenFileStream( buffer, "w" );      }      convertToPCGen( npc, stream );      wtPrint( stream, "\n" );    }    npcDestroyNPC( npc );  }  wtCloseStream( stream );  return 0;}

⌨️ 快捷键说明

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