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

📄 npccgi.c

📁 Npc Generator
💻 C
📖 第 1 页 / 共 3 页
字号:
#include <errno.h>#include <stdio.h>#include <stdlib.h>#include <time.h>#include <string.h>#include <ctype.h>#include "gameutil.h"#include "npcEngine.h"#include "dndconst.h"#include "dndutil.h"#include "grammar.h"#include "npcHistory.h"#include "pcgen_interface.h"#include "writetem.h"#include "wtstream.h"#include "qDecoder.h"#define TEMPATH "tem/"#ifdef WIN32#define CGINAME     "npc.exe"#else#define CGINAME     "npc.cgi"#endifstatic char url[512];static struct {  char* name;  int   id;} racetypes[] = {  { "any",        raceANY },  { "anycore",    raceANY_CORE },  { "anydmg",     raceANY_DMG },  { "anymm",      raceANY_MM },  { "anycc",      raceANY_CC },  { "dwarf",      rcDWARF_HILL },  { "elf",        rcELF_HIGH },  { "gnome",      rcGNOME_ROCK },  { "halfelf",    rcHALFELF },  { "halfling",   rcHALFLING_LIGHTFOOT },  { "halforc",    rcHALFORC },  { "human",      rcHUMAN },  { "aasimar",    rcAASIMAR },  { "aranea",     rcARANEA },  { "azer",       rcAZER },  { "bugbear",    rcBUGBEAR },  { "centaur",    rcCENTAUR },  { "dopple",     rcDOPPLEGANGER },  { "drider",     rcDRIDER },  { "deepdwarf",  rcDWARF_DEEP },  { "derro",      rcDWARF_DERRO },  { "duergar",    rcDWARF_DUERGAR },  { "mtndwarf",   rcDWARF_MOUNTAIN },  { "aqelf",      rcELF_AQUATIC },  { "drow",       rcELF_DROW },  { "grayelf",    rcELF_GRAY },  { "wildelf",    rcELF_WILD },  { "woodelf",    rcELF_WOOD },  { "ettin",      rcETTIN },  { "hillg",      rcGIANT_HILL },  { "stoneg",     rcGIANT_STONE },  { "frostg",     rcGIANT_FROST },  { "fireg",      rcGIANT_FIRE },  { "cloudg",     rcGIANT_CLOUD },  { "stormg",     rcGIANT_STORM },  { "gnoll",      rcGNOLL },  { "frstgnome",  rcGNOME_FOREST },  { "svirf",      rcGNOME_SVIRFNEBLIN },  { "goblin",     rcGOBLIN },  { "grimlock",   rcGRIMLOCK },  { "hags",       rcHAG_SEA },  { "haga",       rcHAG_ANNIS },  { "hagg",       rcHAG_GREEN },  { "deephalf",   rcHALFLING_DEEP },  { "tallflw",    rcHALFLING_TALLFELLOW },  { "harpy",      rcHARPY },  { "hobgob",     rcHOBGOBLIN },  { "kobold",     rcKOBOLD },  { "kuotoa",     rcKUOTOA },  { "lizard",     rcLIZARDFOLK },  { "locathah",   rcLOCATHAH },  { "medusa",     rcMEDUSA },  { "mindflayer", rcMINDFLAYER },  { "minotaur",   rcMINOTAUR },  { "ogre",       rcOGRE },  { "ogremage",   rcOGREMAGE },  { "orc",        rcORC },  { "sahuagin",   rcSAHUAGIN },  { "tiefling",   rcTIEFLING },  { "troglodyte", rcTROGLODYTE },  { "troll",      rcTROLL },  { "yuantip",    rcYUANTI_PUREBLOOD },  { "yuantih",    rcYUANTI_HALFBLOOD },  { "yuantia",    rcYUANTI_ABOMINATION },  { "abandoned",  rcCC_ABANDONED },  { "asaath",     rcCC_ASAATH },  { "batdevil",   rcCC_BATDEVIL },  { "pwretch",    rcCC_PLAGUEWRETCH },  { "charduni",   rcCC_CHARDUNI },  { "cgoblin",    rcCC_COALGOBLIN },  { "fdwarf",     rcCC_DWARF_FORSAKEN },  { "felf",       rcCC_ELF_FORSAKEN },  { "iceghoul",   rcCC_ICE_GHOUL },  { "mcora",      rcCC_MANTICORA },  { "morgaunt",   rcCC_MORGAUNT },  { "proud",      rcCC_PROUD },  { "ratman",     rcCC_RATMAN },  { "bgratman",   rcCC_RATMAN_BROWNGORGER },  { "dratman",    rcCC_RATMAN_DISEASED },  { "fratman",    rcCC_RATMAN_FOAMER },  { "rwratman",   rcCC_RATMAN_REDWITCH },  { "skindev",    rcCC_SKINDEVIL },  { "segoblin",   rcCC_SPIDEREYEGOBLIN },  { "stroll",     rcCC_STEPPETROLL },  { "selement",   rcCC_STRIFEELEMENTAL },  { "tokal",      rcCC_TOKALTRIBESMAN },  { "ubantu",     rcCC_UBANTUTRIBESMAN },  { 0,            0 }};typedef struct __lf__ LOOKANDFEEL;struct __lf__ {  char* name;  char* main;  char* config;  char* printable;  char* longdesc;};LOOKANDFEEL lookAndFeel[] = {  { "standard", TEMPATH "npc_main.tem", TEMPATH "npc_statconfig.tem", TEMPATH "npc_printable.tem", TEMPATH "npc_longdesc.tem" },  { "snipe", TEMPATH "snipe_npc_main.tem", TEMPATH "snipe_npc_config.tem", TEMPATH "npc_printable.tem", TEMPATH "npc_longdesc.tem" },  { 0, 0, 0, 0, 0 }};/* logs access to the CGI */void logAccess( long seed, char* alignment, char* gender, char* race, char* cls, char* level, char* cls2, char* level2, char* cls3, char* level3, int count ) {#ifdef USE_LOG  FILE *f;  char buffer[512];  time_t t;  char *host;  f = fopen( LOGLOCATION, "at" );  if( f == NULL ) {    printf( "content-type: text/html\r\n\r\n" );    printf( "could not open log file: %d (%s)\n", errno, strerror( errno ) );    return;  }  t = time( NULL );  strftime( buffer, sizeof( buffer ), "[%d %b %Y %H:%M:%S]", localtime( &t ) );  host = getenv( "REMOTE_ADDR" );  fprintf( f, "%s %s ", buffer, host );  if( alignment == 0 ) {    fprintf( f, "start\n" );  } else {    fprintf( f, "%s:%s:%s:%s:%s:%s:%s:%s:%s:%d (%d)\n",         alignment, gender, race, cls, level, cls2, level2, cls3, level3, count,        seed );  }  fclose( f );#endif}int getCounter() {#ifdef USE_COUNTER  FILE *f;  char  buffer[32];  int   count;  f = fopen( CTRLOCATION, "r+t" );  if( f == NULL ) {    f = fopen( CTRLOCATION, "w+t" );    if( f == NULL ) {      return 0;    }  }  fgets( buffer, sizeof( buffer ), f );  count = atoi( buffer ) + 1;  rewind( f );  fprintf( f, "%d", count );  fclose( f );  return count;#else  return -1;#endif}LOOKANDFEEL* getLookAndFeel( char* name ) {  int i;  for( i = 0; lookAndFeel[ i ].name != 0; i++ ) {    if( strcmp( name, lookAndFeel[ i ].name ) == 0 ) {      return &(lookAndFeel[i]);    }  }  return &(lookAndFeel[0]);}static int icomp( const void* x, const void* y ) {  int ix = *(int*)x;  int iy = *(int*)y;  if( ix < iy ) return 1;  if( ix > iy ) return -1;  return 0;}void heroicAbilities( int* scores, void* data ) {  int i;  npcAbScoreStrategy_BestOf4d6( scores, data );  scores[0] = 18;  scores[1] = 18;  for( i = 2; i < 6; i++ ) {    if( scores[i] < 12 ) {      scores[ i ] = 12;    }  }}void straight18s( int* scores, void* data ) {  int i;  for( i = 0; i < 6; i++ ) {    scores[ i ] = 18;  }}void averageAbilities( int* scores, void* data ) {  int i;  for( i = 0; i < 6; i++ ) {    scores[i] = 10 + ( rand() % 2 );  }}NPCABSCOREGENFUNC strategies[] = {  0,   npcAbScoreStrategy_BestOf4d6,   npcAbScoreStrategy_Straight3d6,  heroicAbilities,  averageAbilities,  straight18s};static void strrepl( char* buf, char* srch, char* repl ) {  char* p;  int   slen;  int   rlen;  slen = strlen( srch );  rlen = strlen( repl );  p = strstr( buf, srch );  while( p != NULL ) {    memmove( p+rlen, p+slen, strlen( p + slen ) + 1 );    strncpy( p, repl, rlen );    p = strstr( p+rlen, srch );  }}int displayFeats( wtSTREAM_t* stream, wtTAG_t** tags, wtGENERIC_t data, char* other ) {  NPCFEAT*  feat;  char      buffer[100];  NPCFEATWEAPON* nfw;  NPCFEATSKILL* nfs;  NPCFEATSCHOOL* nfsch;  NPCFEATSPELLS* nfsp;  int i;  wtPrint( stream, "<TR><TD CLASS=\"NORMAL\" COLSPAN=2>\n" );  wtPrint( stream, "<UL>\n" );  feat = (NPCFEAT*)data;  while( feat != 0 ) {    strcpy( buffer, dndGetFeatName( feat->type ) );    buffer[0] = toupper( buffer[0] );    if( feat->autoAdd ) {      wtPrintf( stream, "<LI><I>%s", buffer );    } else {      wtPrintf( stream, "<LI>%s", buffer );    }    switch( feat->type ) {      case ftSPELLMASTERY:        nfsp = feat->data;        wtPrint( stream, " (" );        for( i = 0; i < 3; i++ ) {          wtPrintf( stream, "%s%s",                     ( i > 0 ? ", " : "" ),                    dndGetSpellName( nfsp->spells[ i ] ) );        }        wtPrint( stream, ")" );        break;      case ftSPELLFOCUS:        nfsch = feat->data;        wtPrintf( stream, " (%s)", dndGetSchoolOfMagicName( nfsch->school ) );        break;      case ftWEAPONPROFICIENCY_SIMPLE:      case ftWEAPONPROFICIENCY_MARTIAL:      case ftWEAPONPROFICIENCY_EXOTIC:      case ftIMPROVEDCRITICAL:      case ftWEAPONFOCUS:      case ftWEAPONFINESSE:      case ftWEAPONSPECIALIZATION:        nfw = feat->data;        wtPrintf( stream, " (%s)", dndGetWeaponName( nfw->weapon ) );        break;      case ftSKILLFOCUS:        nfs = feat->data;        wtPrintf( stream, " (%s)", dndGetSkillName( nfs->skill ) );        break;    }    if( feat->autoAdd ) {      wtPrintf( stream, "</I>\n" );    } else {      wtPrintf( stream, "\n" );    }    feat = feat->next;  }  wtPrint( stream, "</UL>\n" );  wtPrint( stream, "</TD></TR>\n" );  return 0;}int displayClasses( wtSTREAM_t* stream, wtTAG_t** tags, wtGENERIC_t data, char* other ) {  NPCCLASS* cls;  char      buffer[100];  int       totalLevel;  wtPrint( stream, "<TR><TD CLASS=\"NORMAL\" COLSPAN=2>\n" );  wtPrint( stream, "<UL>\n" );  cls = (NPCCLASS*)data;  while( cls != 0 ) {    strcpy( buffer, dndGetClassName( cls->type ) );    buffer[0] = toupper( buffer[0] );    wtPrintf( stream, "<LI>%s %d\n", buffer, cls->level );    cls = cls->next;  }  wtPrint( stream, "</UL>\n" );  wtPrint( stream, "</TD></TR>\n" );  return 0;}int displaySkills( wtSTREAM_t* stream, wtTAG_t** tags, wtGENERIC_t data, char* other ) {  NPCSKILL* skill;  NPC*      npc;  char      buffer[512];  npc = (NPC*)data;  wtPrint( stream, "<TR><TD CLASS=\"NORMAL\" COLSPAN=2>\n" );  wtPrint( stream, "<TABLE BORDER=0 WIDTH=\"100%\">\n" );  for( skill = npc->skills; skill != 0; skill = skill->next ) {    float total;    NPCCOMPBREAKDOWN* breakdown;    char skillName[100];    strcpy( skillName, dndGetSkillName( skill->type ) );    skillName[0] = toupper( skillName[0] );    total = npcComputeActualSkillBonus( npc, skill->type, &breakdown );    wtPrintf( stream, "<TR><TD CLASS=\"NORMAL\">%s</TD><TD CLASS=\"NORMAL\"><B>%+g</B></TD><TD CLASS=\"NORMAL\">%s</TD></TR>\n",              skillName,              total,              npcBuildComponentBreakdownDescription( breakdown, buffer, sizeof( buffer ) ) );  }  wtPrint( stream, "</TABLE>\n" );  wtPrint( stream, "</TD></TR>\n" );  return 0;}int displaySpells( wtSTREAM_t *stream, wtTAG_t** tags, wtGENERIC_t data, char* other ) {  NPC*    npc;  NPCCLASS* cls;  NPCSPELL** list;  NPCSPELL*  spell;  char buffer[100];  int i;  int count;  int bonus;  int hasPlus;  int relevantAbility;  int total;  int maxLevel;  npc = (NPC*)data;  for( cls = npc->classes; cls != 0; cls = cls->next ) {    list = 0;    hasPlus = 0;    switch( cls->type ) {      case pcBARD:        list = ((NPCBARDDATA*)cls->data)->spells;        relevantAbility = npc->charisma;        break;      case pcCLERIC:        hasPlus = 1;        relevantAbility = npc->wisdom;        wtPrint( stream, "<TR><TD CLASS=\"DIVIDER\" COLSPAN=2><IMG SRC=\"/img/blank.gif\" WIDTH=1 HEIGHT=1></TD></TR>" );        wtPrint( stream, "<TR><TD CLASS=\"HEADER\" COLSPAN=2>Cleric Domains:</TD></TR>\n" );        wtPrint( stream, "<TR><TD CLASS=\"NORMAL\" COLSPAN=2>\n<UL>\n" );        for( i = 0; i < 2; i++ ) {          strcpy( buffer, dndGetDomainName( ((NPCCLERICDATA*)cls->data)->domain[i] ) );          buffer[ 0 ] = toupper( buffer[ 0 ] );          wtPrintf( stream, "<LI>%s\n", buffer );        }        wtPrint( stream, "</UL>\n</TD></TR>\n" );        break;      case pcDRUID:        relevantAbility = npc->wisdom;        break;      case pcPALADIN:        relevantAbility = npc->wisdom;        break;      case pcRANGER:        relevantAbility = npc->wisdom;        break;      case pcSORCERER:        list = ((NPCSORCERERDATA*)cls->data)->spells;        relevantAbility = npc->charisma;        break;      case pcWIZARD:        list = ((NPCWIZARDDATA*)cls->data)->spells;        relevantAbility = npc->intelligence;        break;      case npcADEPT:        relevantAbility = npc->wisdom;        break;      default:        continue;    }

⌨️ 快捷键说明

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