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

📄 npccgi.c

📁 Npc Generator
💻 C
📖 第 1 页 / 共 3 页
字号:
    strcpy( buffer, dndGetClassName( cls->type ) );    buffer[0] = toupper( buffer[0] );    wtPrint( stream, "<TR><TD CLASS=\"DIVIDER\" COLSPAN=2><IMG SRC=\"/img/blank.gif\" WIDTH=1 HEIGHT=1></TD></TR>" );    wtPrintf( stream, "<TR><TD CLASS=\"HEADER\" COLSPAN=2>%s Spells Per Day:</TD></TR>\n", buffer );    if( relevantAbility < 11 ) {      wtPrintf( stream, "<TR><TD CLASS=\"NORMAL\" COLSPAN=2>This character is unable to cast any %s spells, due to an unfortunately low relevant ability score.</TD></TR>\n",                dndGetClassName( cls->type ) );      continue;    }    total = 0;    maxLevel = relevantAbility - 10;    if( maxLevel > 9 ) {      maxLevel = 9;    }    if( maxLevel < 0 ) {      maxLevel = 0;    }    for( i = 0; i <= maxLevel; i++ ) {      count = dndGetSpellsPerDay( cls->type, cls->level, i );      if( count < 0 ) {        continue;      }      count += dndGetBonusSpellsPerDay( relevantAbility, i );      if( count < 1 ) {        continue;      }      total += count;      wtPrintf( stream, "<TR><TD CLASS=\"NORMAL\" ALIGN=\"RIGHT\"><B>%d</B>%s-level:</TD><TD CLASS=\"NORMAL\"><B>%d%s</B> (DC %d where applicable)</TD></TR>\n",                i,                 getOrdinalSuffix( i ),                count,                 ( ( hasPlus && i > 0 ) ? "+1" : "" ),                10 + i + dndGetAbilityBonus( relevantAbility ) );      if( ( hasPlus ) && ( i > 0 ) ) {        total++;      }      if( list != 0 ) {        wtPrint( stream, "<TR><TD CLASS=\"NORMAL\">&nbsp;</TD><TD CLASS=\"NORMAL\">\n<UL>\n" );        for( spell = list[ i ]; spell != 0; spell = spell->next ) {          wtPrintf( stream, "<LI>%s\n", dndGetSpellName( spell->spell ) );        }        wtPrint( stream, "</UL>\n</TD></TR>\n" );      }    }    if( total > 0 ) {      wtPrintf( stream, "<TR><TD CLASS=\"DATA\" ALIGN=\"RIGHT\">Total:</TD><TD CLASS=\"DATA\">%d</TD></TR>\n", total );    } else {      wtPrintf( stream, "<TR><TD CLASS=\"NORMAL\" COLSPAN=2>This character is unable to cast any %s spells until they attain a higher level.</TD></TR>\n",                dndGetClassName( cls->type ) );    }  }  return 0;}int displayAttacks( wtSTREAM_t* stream, wtTAG_t** tags, wtGENERIC_t data, char* other ) {  NPC* npc;  int  baseAttack;  int  attackCount;  int  attack;  int  i;  int  bonus;  NPCCOMPBREAKDOWN* breakdown;  char buffer[512];  npc = (NPC*)data;  baseAttack = npcGetBaseAttack( npc );  /* multiple attacks are based on the unmodified base attack */  attackCount = dndGetClassAttacksPerRound( baseAttack );    /* get the modified attack bonus */  attack = npcComputeActualAttack( npc, attMELEE, &breakdown );   wtPrint( stream, "<TR><TD CLASS=\"NORMAL\">Melee:</TD><TD CLASS=\"DATA\">" );  for( i = 1; i <= attackCount; i++ ) {    if( i > 1 ) {      wtPrint( stream, "/" );    }    bonus = dndGetClassMultipleAttackBonus( attack, i );    wtPrintf( stream, "%+d", bonus );  }  wtPrintf( stream, " %s</TD></TR>\n",            npcBuildComponentBreakdownDescription( breakdown, buffer, sizeof( buffer ) ) );  npcDestroyComponentBreakdown( breakdown );  if( npcHasClass( npc, pcMONK ) ) {    int monkAttackCount;    int monkBaseAttack;    NPCCLASS* cls;    cls = npcGetClass( npc, pcMONK );    monkBaseAttack = dndGetClassAttackBonus( pcMONK, cls->level ) +                     dndGetRaceBonus( npc->race, npc->gender, rbtATTACK, 0 );    monkAttackCount = dndGetMonkAttacksPerRound( monkBaseAttack );    attack = npcComputeActualAttack( npc, attMELEE, &breakdown );     wtPrint( stream, "<TR><TD CLASS=\"NORMAL\">Monk:</TD><TD CLASS=\"DATA\">" );    for( i = 1; i <= monkAttackCount; i++ ) {      if( i > 1 ) {        wtPrint( stream, "/" );      }      bonus = dndGetMonkMultipleAttackBonus( attack, i );      wtPrintf( stream, "%+d", bonus );    }    wtPrintf( stream, " %s</TD></TR>\n",              npcBuildComponentBreakdownDescription( breakdown, buffer, sizeof( buffer ) ) );    npcDestroyComponentBreakdown( breakdown );  }  attack = npcComputeActualAttack( npc, attRANGED, &breakdown );   wtPrint( stream, "<TR><TD CLASS=\"NORMAL\">Ranged:</TD><TD CLASS=\"DATA\">" );  for( i = 1; i <= attackCount; i++ ) {    if( i > 1 ) {      wtPrint( stream, "/" );    }    bonus = dndGetClassMultipleAttackBonus( attack, i );    wtPrintf( stream, "%+d", bonus );  }  wtPrintf( stream, " %s</TD></TR>\n",            npcBuildComponentBreakdownDescription( breakdown, buffer, sizeof( buffer ) ) );  npcDestroyComponentBreakdown( breakdown );  return 0;}int displayNPC_StatBlock( wtSTREAM_t *stream, NPC** npc ) {  char    statBlock[4096];  int     count;  int     i;  int     doBg;  NPCSTATBLOCKOPTS opts;  char    motivation1[ 1024 ];  char    motivation2[ 1024 ];  grGRAMMAR* grammar;  doBg = ( *qValueDefault( "", "background" ) == 'Y' );  if( doBg ) {    grammar = openNPCMotivationGrammar( TEMPATH );  }  count = qiValue( "count" );  if( count < 1 ) {    count = 1;  }  if( count > 100 ) {    count = 100;  }  wtPrint( stream, "<DIV CLASS=\"NORMAL\">\n" );  if( !qiValue( "printable" ) ) {    wtPrintf( stream, "<A HREF=\"%s&printable=1\" TARGET=\"PRINT\">Open printable version</A>\n<P>", url );  }  memset( &opts, 0, sizeof( opts ) );  opts.abilityBonuses = qiValue( "stats_ability_bonuses" );  opts.acBreakdown = qiValue( "stats_ac_breakdown" );  opts.initBreakdown = qiValue( "stats_init_breakdown" );  opts.attackBreakdown = qiValue( "stats_attack_breakdown" );  opts.saveBreakdown = qiValue( "stats_save_breakdown" );  opts.skillBreakdown = qiValue( "stats_skill_breakdown" );  opts.languages = qiValue( "stats_languages" );  opts.skillsAndFeats = qiValue( "stats_skillsfeats" );  opts.possessions = qiValue( "stats_possessions" );  opts.spells = qiValue( "stats_spells" );  opts.richFormatting = qiValue( "stats_formatting" );  for( i = 0; i < count; i++ ) {    npcBuildStatBlock( npc[i], &opts, statBlock, sizeof( statBlock ) );    strrepl( statBlock, "~B", "<B>" );    strrepl( statBlock, "~b", "</B>" );    strrepl( statBlock, "\n", "<BR>\n" );    strrepl( statBlock, "~I", "<I>" );    strrepl( statBlock, "~i", "</I>" );    wtPrint( stream, statBlock );    if( doBg ) {      grammar->startSymbol = "[motivation]";      getNPCMotivation( grammar, npc[i], motivation1, sizeof( motivation1 ) );      do {              getNPCMotivation( grammar, npc[i], motivation2, sizeof( motivation1 ) );      } while( strcmp( motivation1, motivation2 ) == 0 );      wtPrintf( stream, "<P><I>Primary motivation:</I> %s\n", motivation1 );      wtPrintf( stream, "<P><I>Secondary motivation:</I> %s\n", motivation2 );      getNPCRecentPast( grammar, npc[i], motivation1, sizeof( motivation1 ) );      wtPrintf( stream, "<P><I>Recent Past:</I> %s\n", motivation1 );    }    if( i+1 < count ) {      wtPrint( stream, "\n<HR SIZE=1>\n" );    }  }  wtPrint( stream, "</DIV>\n<P>\n" );  if( doBg ) {    grDestroyGrammar( grammar );  }  return 0;}int displayLanguages( wtSTREAM_t* stream, wtTAG_t** tags, wtGENERIC_t data, char* other ) {  NPC* npc;  NPCLANGUAGE* lang;  char text[128];  npc = (NPC*)data;  wtPrint( stream, "<TR><TD CLASS=\"NORMAL\" COLSPAN=2>\n" );  wtPrint( stream, "<UL>\n" );  for( lang = npc->languages; lang != 0; lang = lang->next ) {    strcpy( text, dndGetLanguageName( lang->language ) );    text[0] = toupper( text[0] );    wtPrintf( stream, "<LI>%s\n", text );  }  wtPrint( stream, "</UL>\n" );  wtPrint( stream, "</TD></TR>\n" );  return 0;}int displayNPCBackground( wtSTREAM_t* stream, wtTAG_t** tags, wtGENERIC_t data, char* other ) {  grGRAMMAR* grammar;  NPC*       npc;  char       m1[1024];  char       m2[1024];  npc = (NPC*)data;  if( *qValueDefault( "", "background" ) == 'Y' ) {    grammar = openNPCMotivationGrammar( TEMPATH );    grammar->startSymbol = "[motivation]";    getNPCMotivation( grammar, npc, m1, sizeof( m1 ) );    do {      getNPCMotivation( grammar, npc, m2, sizeof( m2 ) );    } while( strcmp( m1, m2 ) == 0 );    wtPrint( stream, "<TR><TD CLASS=\"DIVIDER\" COLSPAN=2><IMG SRC=\"/img/blank.gif\" WIDTH=1 HEIGHT=1></TD></TR>\n" );    wtPrint( stream, "<TR><TD CLASS=\"NORMAL\" COLSPAN=2>\n" );    wtPrintf( stream, "<B>Primary Motivation:</B> %s\n<P>\n", m1 );    wtPrintf( stream, "<B>Secondary Motivation:</B> %s\n<P>\n", m2 );    getNPCRecentPast( grammar, npc, m1, sizeof( m1 ) );    wtPrintf( stream, "<B>Recent Past:</B> %s\n", m1 );    wtPrint( stream, "</TD></TR>" );    grDestroyGrammar( grammar );  }  return 0;}int displayNPC_Full( wtSTREAM_t* stream, NPC* npc ) {  wtTAG_t *tags[37];  char    alignment[20];  char    race[40];  char    gender[20];  wtDELEGATE_t d_skill;  wtDELEGATE_t d_feat;  wtDELEGATE_t d_class;  wtDELEGATE_t d_spells;  wtDELEGATE_t d_attack;  wtDELEGATE_t d_languages;  wtDELEGATE_t d_background;  char    strbonus[5];  char    dexbonus[5];  char    conbonus[5];  char    intbonus[5];  char    wisbonus[5];  char    chabonus[5];  char    height[100];  char    weight[100];  int     armorClass;  char    armorClassTxt[ 256 ];  int     useWisdom;  int     initiative;  char    initiativeTxt[ 256 ];  int     save;  int     cr;  int     speed;  char    fortSave[100];  char    refSave[100];  char    willSave[100];  char    gearValue[100];  char    buffer[ 512 ];  char    pcgen[ 1024 ];  char    hpDesc[ 512 ];  NPCCOMPBREAKDOWN* breakdown;  NPCCLASS* cls;  char* tem;  strcpy( alignment, dndGetAlignmentText( npc->alignment ) );  alignment[0] = toupper( alignment[0] );  strcpy( race, (char*)dndGetRaceName( npc->race ) );  race[0] = toupper( race[0] );  strcpy( gender, ( npc->gender == gMALE ? "Male" : "Female" ) );  /* compute the armor class, and build the text describing how we arrived   * at this number */  armorClass = npcComputeActualAC( npc, &breakdown );  sprintf( armorClassTxt, "%d %s", armorClass,           npcBuildComponentBreakdownDescription( breakdown, buffer, sizeof( buffer ) ) );  npcDestroyComponentBreakdown( breakdown );  /* compute the initiative score, and build the text describing how we   * arrived at this number */  initiative = npcComputeActualInitiative( npc, &breakdown );  sprintf( initiativeTxt, "%+d %s", initiative,           npcBuildComponentBreakdownDescription( breakdown, buffer, sizeof( buffer ) ) );  npcDestroyComponentBreakdown( breakdown );  /* calculate the ability bonuses */  sprintf( strbonus, "%+d", dndGetAbilityBonus( npc->strength ) );  sprintf( dexbonus, "%+d", dndGetAbilityBonus( npc->dexterity ) );  sprintf( conbonus, "%+d", dndGetAbilityBonus( npc->constitution ) );  sprintf( intbonus, "%+d", dndGetAbilityBonus( npc->intelligence ) );  sprintf( wisbonus, "%+d", dndGetAbilityBonus( npc->wisdom ) );  sprintf( chabonus, "%+d", dndGetAbilityBonus( npc->charisma ) );  npcBuildHitDiceBreakdown( npc, hpDesc, sizeof( hpDesc ) );  sprintf( &(hpDesc[strlen(hpDesc)]), " (%d)", npc->hp );  cr = npcComputeCR( npc );  speed = dndGetRaceSpeed( npc->race );  if( npcHasClass( npc, pcBARBARIAN ) ) {    speed += 10;  }  cls = npcGetClass( npc, pcMONK );  if( cls != 0 ) {    save = dndGetMonkSpeedForRace( npc->race, cls->level );    if( save > speed ) {      speed = save;    }  }  /* set up the tags that will be written out */  tags[0] = wtTagReplace( "ALIGNMENT", alignment );  tags[1] = wtTagReplace( "RACE", race );  tags[2] = wtTagReplace( "GENDER", gender );  tags[3] = wtTagReplaceI( "STRENGTH", npc->strength );  tags[4] = wtTagReplaceI( "DEXTERITY", npc->dexterity );  tags[5] = wtTagReplaceI( "CONSTITUTION", npc->constitution );  tags[6] = wtTagReplaceI( "INTELLIGENCE", npc->intelligence );  tags[7] = wtTagReplaceI( "WISDOM", npc->wisdom );  tags[8] = wtTagReplaceI( "CHARISMA", npc->charisma );  tags[9] = wtTagReplace( "STRBONUS", strbonus );  tags[10] = wtTagReplace( "DEXBONUS", dexbonus );  tags[11] = wtTagReplace( "CONBONUS", conbonus );  tags[12] = wtTagReplace( "INTBONUS", intbonus );  tags[13] = wtTagReplace( "WISBONUS", wisbonus );  tags[14] = wtTagReplace( "CHABONUS", chabonus );  tags[15] = wtTagReplace( "HP", hpDesc );  d_skill.handler = displaySkills;  d_skill.userData = npc;    d_feat.handler = displayFeats;  d_feat.userData = npc->feats;  d_class.handler = displayClasses;  d_class.userData = npc->classes;  d_spells.handler = displaySpells;  d_spells.userData = npc;  d_attack.handler = displayAttacks;  d_attack.userData = npc;  d_languages.handler = displayLanguages;  d_languages.userData = npc;  d_background.handler = displayNPCBackground;  d_background.userData = npc;  tags[16] = wtTagDelegate( "SKILLS", &d_skill );  tags[17] = wtTagDelegate( "FEATS", &d_feat );  tags[18] = wtTagDelegate( "CLASSES", &d_class );  tags[19] = wtTagReplace( "AC", armorClassTxt );  tags[20] = wtTagReplace( "INIT", initiativeTxt );  tags[21] = wtTagDelegate( "SPELLS", &d_spells );  tags[22] = wtTagDelegate( "ATTACK", &d_attack );  /* compute and format the saving throws */  save = npcComputeActualSave( npc, svFORTITUDE, &breakdown );  sprintf( fortSave, "%+d %s", save,           npcBuildComponentBreakdownDescription( breakdown, buffer, sizeof( buffer ) ) );  npcDestroyComponentBreakdown( breakdown );  save = npcComputeActualSave( npc, svREFLEX, &breakdown );  sprintf( refSave, "%+d %s", save,           npcBuildComponentBreakdownDescription( breakdown, buffer, sizeof( buffer ) ) );  npcDestroyComponentBreakdown( breakdown );  save = npcComputeActualSave( npc, svWILL, &breakdown );  sprintf( willSave, "%+d %s", save,           npcBuildComponentBreakdownDescription( breakdown, buffer, sizeof( buffer ) ) );  npcDestroyComponentBreakdown( breakdown );  /* compute and format the gp value of the NPC's gear */  commify( gearValue, npcGearValue( npc ) );  strcat( gearValue, " gp" );  /* if we are not displaying the "printable" version, put up a link to   * allow a printable version to be displayed. */  if( !qiValue( "printable" ) ) {    sprintf( buffer, "<A HREF=\"%s&printable=1\" TARGET=\"PRINT\">Open printable version</A>", url );    sprintf( pcgen, "<A HREF=\"%s&action=pcgen\" TARGET=\"PCGEN\">Download in PCGen Format</a><br>"                    "(<span style=\"color: red\">EXPERIMENTAL</span>) "                    "[ <a href=\"javascript:pcgenHelp()\">What is this</a>? ]", url );  } else {    buffer[0] = 0;    pcgen[0] = 0;  }  /* format the height and weight */  if( npc->height_in > 0 ) {    sprintf( height, "%d' %d\" ", npc->height_ft, npc->height_in );  } else {    sprintf( height, "%d'", npc->height_ft );  }  commify( weight, npc->weight );  strcat( weight, " lbs" );  tags[23] = wtTagReplace( "FORTSAVE", fortSave );  tags[24] = wtTagReplace( "REFSAVE", refSave );  tags[25] = wtTagReplace( "WILLSAVE", willSave );  tags[26] = wtTagReplace( "GEARVALUE", gearValue );  tags[27] = wtTagReplace( "DOPRINTABLE", buffer );  tags[28] = wtTagReplace( "HEIGHT", height );  tags[29] = wtTagReplace( "WEIGHT", weight );  tags[30] = wtTagReplaceI( "CR", cr );  tags[31] = wtTagReplace( "NAME", npc->name );  tags[32] = wtTagDelegate( "LANGUAGES", &d_languages );  tags[33] = wtTagReplaceI( "SPEED", speed );  tags[34] = wtTagDelegate( "BACKGROUND", &d_background );

⌨️ 快捷键说明

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