#include <stdio.h> #include <string.h> #include <stdlib.h> #include "struct.h" /* * Bootstrap Loader Routine * */ extern char LineBuf[]; /* Holds input lines */ Load_Database(name,d) char *name; int d; { FILE *f=fopen(name,"r"); int er; if(!f) { printf("[ERROR]: Database not found.\n"); exit(1); } er=Load_From_File(f,d); fclose(f); SysFlags[15]=ISOBJ(NObs()); SysFlags[16]=ISOBJ(MAXU); return(er); } /* * Perform the actual buisiness and load the thing */ Load_From_File(f,d) FILE *f; int d; { extern char *GetLine(); int er; tag ct=0; while(ct<MAXU) { fflush(stdout); AddPlayer(); fflush(stdout); LOC(ISOBJ(ct))= -1; fflush(stdout); SETSNOOP(ISOBJ(ct),ISOBJ(-1)); fflush(stdout); SETVIS(ISOBJ(ct),1000); fflush(stdout); FLAGS(ISOBJ(ct))|=FL_PLAYER; fflush(stdout); ct++; } er=Load_GameName(f,d); if(er) return(er); if(GetLine(f)==NULL) { ELine(); printf("[ERROR]: Unexpected EOF.\n"); return(1); } if(strcmp(LineBuf,"@ARCHID")) { ELine(); printf("[ERROR]: ARCHID block expected.\n"); return(1); } er=Load_ArchID(f,d); if(er) return(er); if(strcmp(LineBuf,"@ARCHNAME")) { ELine(); printf("[ERROR]: ARCHNAME block expected.\n"); return(1); } er=Load_ArchName(f,d); if(er) return(er); if(strcmp(LineBuf,"@RFLAG")) { ELine(); printf("[ERROR]: RFLAG block expected.\n"); return(1); } er=LoadRFlag(f,d); if(er) return(er); if(strcmp(LineBuf,"@OFLAG")) { ELine(); printf("[ERROR]: OFLAG block expected.\n"); return(1); } er=LoadOFlag(f,d); if(er) return(er); if(strcmp(LineBuf,"@PFLAG")) { ELine(); printf("[ERROR]: PFLAG block expected.\n"); return(1); } er=LoadPFlag(f,d); if(er) return(er); /* * Any of the routines from this point on can legitimately be called * by users within the game system, by other means */ if(strcmp(LineBuf,"@CONSTANTS")==0) { LoadConstants(f); } if(strcmp(LineBuf,"@VOCAB")) { ELine(); printf("[ERROR]: VOCAB block expected.\n"); return(1); } er=LoadVocab(f,d); if(er) return(er); while(1) { if(strcmp(LineBuf,"@ROOM")==0) { er=LoadRoom(f,d); if(er) return(er); } else if(strcmp(LineBuf,"@PLAYER")==0) { er=LoadPlayer(f,d); if(er) return(er); } else if(strcmp(LineBuf,"@OBJECT")==0) { er=LoadObject(f,d); if(er) return(er); } else break; } ResolveReferences(); /* sort out forward item references */ if(strcmp(LineBuf,"@EXIT")) { ELine(); printf("[ERROR]: EXIT block expected.\n"); return(1); } er=LoadExit(f,d); if(er) return(er); if(strcmp(LineBuf,"@MESSAGE")) { ELine(); printf("[ERROR]: MESSAGE block expected.\n"); return(1); } er=LoadMessage(f,d); if(er) return(er); if(strcmp(LineBuf,"@ITEMTABLES")==0) er=LoadItemTables(f,d); if(er) return(er); if(strcmp(LineBuf,"@TABLES")) { ELine(); printf("[ERROR]: TABLES block expected.\n"); return(1); } er=LoadTables(f,d); if(er) return(er); if(GetLine(f)==NULL) { ELine(); printf("[ERROR]: Unexpected EOF.\n"); return(1); } if(strcmp(LineBuf,"@TABLE")) { ELine(); printf("[ERROR]: TABLE block expected.\n"); return(1); } er=LoadEachTable(f,d); if(er) return(er); return(0); } char LineBuf[256]; /* Input buffer */ int LineNumber=0; /* Line reference */ void ELine() /* Error formatting */ { log_error("%d:",LineNumber); } static int line_stack[32]; /* Include control */ static FILE *file_stack[32]; static int file_sp=0; /* * Do an include */ void Push_File(f) FILE *f; { if(file_sp==32) { log_error("Too many levels of include.\n",NULL); panic(); } line_stack[file_sp]=LineNumber; LineNumber=0; file_stack[file_sp++]=f; } /* * End an include */ FILE *act_f=NULL; FILE *Pop_File() { if(file_sp==0) return(NULL); if(act_f) fclose(act_f); LineNumber=line_stack[--file_sp]; return(file_stack[file_sp]); } FILE *GetFP() { return(act_f); } /* * Line input routine, conceals comments, and includes from rest of game * compilation system */ char *GetLine(f) FILE *f; { if(act_f==NULL) act_f=f; loop: do { if(fgets(LineBuf,255,act_f)==NULL) { if((act_f=Pop_File())==NULL) return(NULL); else { printf("end of include..\n"); *LineBuf=';'; continue; } } LineNumber++; } while(*LineBuf==';'); if(*LineBuf=='<') { *index(LineBuf,'\n')=0; Push_File(act_f); act_f=fopen(LineBuf+1,"r"); if(!act_f) { perror(LineBuf+1); exit(1); } printf("Including '%s'..\n",LineBuf+1); goto loop; } if(LineBuf[strlen(LineBuf)-1]=='\n') LineBuf[strlen(LineBuf)-1]=0; else printf("[WARNING]: Line too long.\n"); /* printf(">>%s\n",LineBuf); */ return(LineBuf); } int ArchID[16]; /* ArchID's (unused) */ char *ArchName[16]; /* Archwiz names */ char GameName[32]; /* The game name */ char *RFlagList[16]= { "{res0}", "{res1}", "fall", /* UNIMPLEMENTED */ "dark", "small", /* UNIMPLEMENTED */ "death", /* UNIMPLEMENTED */ NULL }; char *OFlagList[16]= { "{res0}", "{res1}", "flannel", "lit0", "litall", "worn", NULL }; char *PFlagList[16]= { "{res0}", "{res1}", "brief", "male", "blind", "deaf", "asleep", "seedark", NULL }; /* * Look up %name stuff */ FindFlagListEntry(x) char *x; { int ct=0; while(ct<16&&PFlagList[ct]) { if(strcmp(PFlagList[ct],x)==0) return(ct); ct++; } ct=0; while(ct<16&&RFlagList[ct]) { if(strcmp(RFlagList[ct],x)==0) return(ct); ct++; } ct=0; while(ct<16&&OFlagList[ct]) { if(strcmp(OFlagList[ct],x)==0) return(ct); ct++; } return(-1); } /* * Read in archwizard identities */ Load_ArchID(f,d) FILE *f; int d; { int ct=0; while(ct<16) { if(GetLine(f)==NULL) return(-1); if(*LineBuf=='@') return(0); if(d) printf("ArchID %d=%s\n",ct,LineBuf); if(sscanf(LineBuf,"%d",&ArchID[ct])==0) { ELine(); printf("[ERROR]: Invalid ArchID\n"); return(-1); } ct++; } ELine(); printf("[ERROR]: Max ArchID is 16.\n"); return(-1); } Load_ArchName(f,d) FILE *f; int d; { int ct=0; while(ct<16) { if(GetLine(f)==NULL) return(-1); if(*LineBuf=='@') return(0); if(d) printf("ArchName %d=%s\n",ct,LineBuf); ArchName[ct]=(char *)estralloc(LineBuf); ct++; } ELine(); printf("[ERROR]: Max ArchName is 16.\n"); return(-1); } /* * Obtain game name */ Load_GameName(f,d) FILE *f; int d; { char *t; if(GetLine(f)==NULL) { ELine(); printf("[ERROR]: No GameName field.\n"); return(-1); } t=LineBuf; while(*t) { if(*t==':') break; else t++; } if(!*t) { ELine(); printf("[ERROR]: GameName not specified.\n"); return(-1); } t++; if(!*t) { ELine(); printf("[ERROR]: Null GameName.\n"); return(-1); } if(strlen(t)>31) { ELine(); printf("[ERROR]: GameName too long.\n"); return(-1); } strcpy(GameName,t); return(0); } /* * Get room/object/player flags */ LoadRFlag(f,d) FILE *f; int d; { return(LoadFlagSet(RFlagList,f,d,"Room")); } LoadOFlag(f,d) FILE *f; int d; { return(LoadFlagSet(OFlagList,f,d,"Object")); } LoadPFlag(f,d) FILE *f; int d; { return(LoadFlagSet(PFlagList,f,d,"Player")); } /* * Load a bitflag set */ LoadFlagSet(list,f,d,n) char **list; FILE *f; int d; char *n; { int ct=0; while(list[ct]) ct++; while(ct<16) { if(GetLine(f)==NULL) { ELine(); printf("[ERROR]: Unexpected EOF\n"); return(-1); } if(*LineBuf=='@') return(0); list[ct]=(char *)estralloc(LineBuf); if(d) { printf("%s]%d) %s\n",n,ct,LineBuf); } ct++; } ELine(); printf("[ERROR] %s flag list too long.\n",n); return(-1); } static int wv=0; /* Word allocator */ AllocWC() { return(++wv); } /* * Load up the vocabulary, adds system .words but only first time! */ LoadVocab(f,d) FILE *f; int d; { char *ep,*op; char wbuf[256]; char wt='$'; int lwv; char lwt; int wcode; static int dotdone=0; /* uccky hack */ int ticktick=0; if(!dotdone) { AddWord(".exit",RVC_EXIT,1); AddWord(".weight",RVC_WEIGHT,1); AddWord(".size",RVC_SIZE,1); AddWord(".level",RVC_LEVEL,1); AddWord(".score",RVC_SCORE,1); AddWord(".strength",RVC_STRENGTH,1); AddWord(".snoop",RVC_SNOOP,1); AddWord(".vis",RVC_VIS,1); AddWord(".ldesc",RVC_LDESC,1); AddWord(".name",RVC_NAME,1); AddWord(".odesc",RVC_ODESC,1); dotdone=1; } while(1) { if(ticktick%20==0) { printf("\r%c\r","|/-\\"[(ticktick/20)%4]); } ticktick++; if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(-1); } if(*LineBuf=='@') return(0); lwv=wv; lwt=wt; ep=LineBuf; op=wbuf; while(*ep&&!isspace(*ep)) *op++=*ep++; *op=0; if(!*ep) { ELine(); log_error("[ERROR]: Malformed word '%s'.\n",LineBuf); return(-1); } ep=stpblk(ep); wt=*ep; if(wt=='S') { wt=lwt; wv=lwv; } else wv++; switch(wt) { case 'V':wcode=1;break; case 'A':wcode=2;break; case 'N':wcode=3;break; case 'P':wcode=4;break; default:ELine(); log_error("[ERROR]: Unknown word type '%c':'%s'.\n",wt,LineBuf); return(-1); } if(FindWord(wbuf,wcode)!=NULL) { ELine(); log_error("[ERROR]: Duplicate word '%s'.\n",LineBuf); return(-1); } AddWord(wbuf,wv,wcode); } }