#include <stdio.h> #include <string.h> #include <stdlib.h> #include "struct.h" #include <ctype.h> char *stpblk(x) char *x; { while(*x==' '||*x=='\t') x++; if(*x) return(x); return(""); } char *GetName(x,b) char *x; char *b; { int ct=0; x=stpblk(x); if(x==NULL) return(NULL); while(*x) { if(!isspace(*x)) { ct++; if(ct==32) { log_error("[ERROR]: Name Too Long '%s'.\n",LineBuf); return(NULL); } *b++= *x++; } else break; } *b=0; return(x); } char *GetToken(x,b) char *x; char *b; { x=stpblk(x); if(x==NULL) return(NULL); if(strlen(x)==0) return(NULL); while(*x) { if(!isspace(*x)) *b++= *x++; else break; if(x[-1]=='{') break; } *b=0; return(x); } char *Get_Block(x,buf) char *x; char *buf; { while(*x) { if(*x=='}') break; else *buf++= *x++; } *buf=0; if(!*x) return(NULL); return(x+1); } extern int LineNumber; char *ReadLongString(f) FILE *f; { extern char *estralloc(); char bigbuffer[2048]; int c; int bp=0; f=GetFP(); while((c=fgetc(f))!=EOF) { if(bp==2047) { bigbuffer[bp]=0; ELine(); log_error("[ERROR]: Over long, or unterminated string.\n%s\n",bigbuffer); panic(); } if(c=='^') break; if(c=='\n') LineNumber++; bigbuffer[bp++]=c; } bigbuffer[bp]=0; while(!feof(f)&&fgetc(f)!='\n'); LineNumber++; return(estralloc(bigbuffer)); } int GetFlagLine(l) char *l[]; { char a[256]; int ct=0; int v=0; char *p=LineBuf; while(1) { p=GetToken(p,a); if(p==NULL) return(v); ct=2; while(ct<16&&l[ct]) { if(strcmp(l[ct],a)==0) { v|=(1<<ct); goto next; } ct++; } ELine(); log_error("[ERROR]:Unknown Flag '%s'.\n",a); return(-1); next:; } } LoadOneRoom(f,d) FILE *f; int d; { char wdbf[256]; char namebuf[32]; char name2buf[32]; tag r; short v; int ct; tag flagarray[128]; int ad,no; char *p=GetName(LineBuf,namebuf); if(!p) { ELine(); log_error("[ERROR]: Invalid Name '%s'.\n",LineBuf); return(1); } if(d) { printf("Processing Room '%s'\n",namebuf); } p=stpblk(p); if(p==NULL) { ELine(); log_error("[ERROR]: Room '%s' has no description.\n",namebuf); return(1); } r=AddRoom(); SetName(r,p); p=ReadLongString(f); if(p==NULL) return(1); free(ROOM(r)->rm_Long); ROOM(r)->rm_Long=p; if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } p=GetToken(LineBuf,wdbf); if(p==NULL) { ELine(); log_error("[ERROR]: Adjective missing in room '%s'.\n",namebuf); return(1); } if(strcmp(wdbf,"$ANY")==0) { ADJ(r)= -1; } else { ad=FindCWord(wdbf,2); if(ad==-1) { AddWord(wdbf,(ad=AllocWC()),2); } ADJ(r)=ad; } p=GetToken(p,wdbf); if(!p) { ELine(); log_error("[ERROR]: Noun missing in room '%s'.\n",namebuf); return(1); } if(strcmp(wdbf,"$ANY")==0) { NOUN(r)= -1; } else { no=FindCWord(wdbf,3); if(no==-1) { AddWord(wdbf,(no=AllocWC()),3); } NOUN(r)=no; } if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } v=GetFlagLine(RFlagList); if(v==-1) return(1); FLAGS(r)=v|FL_ROOM; if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } BuildFlagImage(f,flagarray,r,14); ct=0; while(ct<16-14) { RUSER(r,ct)=flagarray[ct]; ct++; } LOC(r)= ISOBJ(-1); OBJECT(r)->ob_Child= -1; OBJECT(r)->ob_Next= -1; if(v==11&&strlen(name2buf)) { struct Word *dr=FindName(name2buf,1); if(!dr) { ELine(); log_error("[ERROR]: Unknown room '%s'.\n",name2buf); return(1); } DROPTO(r)=dr->wd_Code; /* obsolete */ } else DROPTO(r)= -1; AddName(namebuf,r,1); return(0); } LoadRoom(f,d) FILE *f; int d; { int v=0; do { if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } if(*LineBuf!='@') v=LoadOneRoom(f,d); } while(v==0&&*LineBuf!='@'); return(v); } LoadOneObject(f,d) FILE *f; int d; { char wdbf[256]; char namebuf[32]; char name2buf[32]; int ad,no; int ct=0; tag flagarray[128]; tag r; short v; int st,mst,sz,wt; char *p=GetName(LineBuf,namebuf); struct Word *dr; if(!p) { ELine(); log_error("[ERROR]: Invalid Name '%s'.\n",LineBuf); return(1); } if(d) { printf("Processing Object '%s'\n",namebuf); } p=stpblk(p); if(p==NULL) { ELine(); log_error("[ERROR]: Object '%s' has no description.\n",namebuf); return(1); } r=AddObject(); SetName(r,p); if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } p=GetToken(LineBuf,wdbf); if(p==NULL) { ELine(); log_error("[ERROR]: Adjective missing in object '%s'.\n",namebuf); return(1); } if(strcmp(wdbf,"$ANY")==0) { ADJ(r)= -1; } else { ad=FindCWord(wdbf,2); if(ad==-1) { AddWord(wdbf,(ad=AllocWC()),2); } ADJ(r)=ad; } p=GetToken(p,wdbf); if(!p) { ELine(); log_error("[ERROR]: Noun missing in object '%s'.\n",namebuf); return(1); } if(strcmp(wdbf,"$ANY")==0) { NOUN(r)= -1; } else { no=FindCWord(wdbf,3); if(no==-1) { AddWord(wdbf,(no=AllocWC()),3); } NOUN(r)=no; } if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } v=GetFlagLine(OFlagList); if(v==-1) return(1); FLAGS(r)=v|FL_OBJECT; /* * Now read LOC STATE MAXSTATE SIZE WEIGHT users.... */ if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } if(sscanf(LineBuf,"%31s %d %d %d %d", name2buf,&st,&mst,&sz,&wt)!= 5) { ELine(); log_error("[ERROR]: Incomplete definition line in object '%s'.\n", namebuf); return(1); } if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } BuildFlagImage(f,flagarray,r,6); while(ct<16-6) { OUSER(r,ct)=flagarray[ct]; ct++; } SetMaxState(r,mst); SetState(r,st); SETWEIGHT(r,wt); SETSIZE(r,sz); v=0; /* * State texts */ while(v<mst) { p=ReadLongString(f); if(p==NULL) return(1); free(OBJECT(r)->ob_Desc[v]); OBJECT(r)->ob_Desc[v]=p; v++; } dr=FindName(name2buf,1); OBJECT(r)->ob_Child= -1; OBJECT(r)->ob_Next= -1; if(!dr) { Push_Resolution(r,1,name2buf); } else { LOC(r)=dr->wd_Code; Tree_Link(r,LOC(r)); } AddName(namebuf,r,1); return(0); } LoadObject(f,d) FILE *f; int d; { int v=0; do { if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } if(*LineBuf!='@') v=LoadOneObject(f,d); } while(v==0&&*LineBuf!='@'); return(v); } LoadOnePlayer(f,d) FILE *f; int d; { char wdbf[256]; char namebuf[32]; char name2buf[32]; int ad,no; tag r; int v; int lv,sc,st; int ct; tag flagarray[128]; char *p=GetName(LineBuf,namebuf); struct Word *dr; if(!p) { ELine(); log_error("[ERROR]: Invalid Name '%s'.\n",LineBuf); return(1); } if(d) { printf("Processing Player '%s'\n",namebuf); } p=stpblk(p); if(p==NULL) { ELine(); log_error("[ERROR]: Player '%s' has no description.\n",namebuf); return(1); } r=AddPlayer(); SetName(r,p); if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } p=GetToken(LineBuf,wdbf); if(p==NULL) { ELine(); log_error("[ERROR]: Adjective missing in player '%s'.\n",namebuf); return(1); } if(strcmp(wdbf,"$ANY")==0) { ADJ(r)= -1; } else { ad=FindCWord(wdbf,2); if(ad==-1) { AddWord(wdbf,(ad=AllocWC()),2); } ADJ(r)=ad; } p=GetToken(p,wdbf); if(!p) { ELine(); log_error("[ERROR]: Noun missing in player '%s'.\n",namebuf); return(1); } if(strcmp(wdbf,"$ANY")==0) { NOUN(r)= -1; } else { no=FindCWord(wdbf,3); if(no==-1) { AddWord(wdbf,(no=AllocWC()),3); } NOUN(r)=no; } if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } v=GetFlagLine(PFlagList); if(v==-1) return(1); FLAGS(r)=v|FL_PLAYER; /* * Now read LEVEL SCORE STRENGTH VIS u1-u10 */ if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } if(sscanf(LineBuf,"%31s %d %d %d %d",name2buf,&lv,&sc,&st,&v) != 5) { ELine(); log_error("[ERROR]: Incomplete definition line in player '%s'.\n", namebuf); return(1); } if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } BuildFlagImage(f,flagarray,r,7); SETLEVEL(r,lv); SETSCORE(r,sc); SETSTRENGTH(r,st); SETSNOOP(r,-1); SETVIS(r,v); ct=0; while(ct<32-7) { PUSER(r,ct)=flagarray[ct]; ct++; } v=0; dr=FindName(name2buf,1); OBJECT(r)->ob_Child= -1; OBJECT(r)->ob_Next= -1; if(!dr) { Push_Resolution(r,1,name2buf); } else { LOC(r)=dr->wd_Code; Tree_Link(r,LOC(r)); } free(PLAYER(r)->pl_IOH[0]); p=ReadLongString(f); if(!p) { ELine(); log_error("[ERROR]: No Here string for player '%s'.\n",namebuf); return(1); } PLAYER(r)->pl_IOH[0]=p; free(PLAYER(r)->pl_IOH[1]); p=ReadLongString(f); if(!p) { ELine(); log_error("[ERROR]: No Arrives string for player '%s'.\n",namebuf); return(1); } PLAYER(r)->pl_IOH[1]=p; free(PLAYER(r)->pl_IOH[2]); p=ReadLongString(f); if(!p) { ELine(); log_error("[ERROR]: No Leaves string for player '%s'.\n",namebuf); return(1); } PLAYER(r)->pl_IOH[2]=p; AddName(namebuf,r,1); return(0); } LoadPlayer(f,d) FILE *f; int d; { int v=0; do { if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } if(*LineBuf!='@') v=LoadOnePlayer(f,d); } while(v==0&&*LineBuf!='@'); return(v); } LoadExit(f,d) FILE *f; int d; { char nb1[32],nb2[32],xb[256]; tag fr,tr; int v; char *p; struct Word *wd; while(1) { if(GetLine(f)==NULL) { ELine(); log_error("[ERROR]: Unexpected EOF.\n"); return(1); } if(*LineBuf=='@') return(0); p=GetName(LineBuf,nb1); if(p==NULL) { ELine(); log_error("[ERROR]: Bad exit '%s'.\n",LineBuf); return(1); } p=GetToken(p,xb); if(p==NULL) { ELine(); printf("[ERROR]: Bad exit '%s'.\n",LineBuf); return(1); } p=GetName(p,nb2); if(p==NULL) { ELine(); log_error("[ERROR]: Bad exit '%s'.\n",LineBuf); return(1); } if(strcmp(xb,"NE")==0) v=6; else if(strcmp(xb,"NW")==0) v=7; else if(strcmp(xb,"SE")==0) v=8; else if(strcmp(xb,"SW")==0) v=9; else if(strcmp(xb,"IN")==0) v=10; else if(strcmp(xb,"OUT")==0) v=11; else switch(*xb) { case 'N':v=0;break; case 'E':v=1;break; case 'S':v=2;break; case 'W':v=3;break; case 'U':v=4;break; case 'D':v=5;break; default:ELine();log_error("[ERROR] Bad exit name '%s'.\n",LineBuf); return(1); } if(strcmp(nb2,"$NONE")==0) { tr=0; } else { wd=FindName(nb2,0); if(!wd) { ELine(); log_error("[ERROR]: Unknown item '%s'.\n",nb2); return(1); } tr=wd->wd_Code; } tr=ISOBJ(tr); wd=FindName(nb1,0); if(wd==NULL) { ELine(); log_error("[ERROR]: Unknown item '%s'.\n",nb1); return(1); } fr=ISOBJ(wd->wd_Code); if(EXIT(fr,v)) { ELine(); log_error("[ERROR]: Exit multiply defined '%s' - goes to %s.\n",LineBuf,NAME(EXIT(fr,v))); return(1); } SETEXIT(fr,v,tr); } } void BuildFlagImage(f,x,i,o) FILE *f; tag x[]; ITEM i; int o; { int ct=0; char *t=LineBuf; char bf[256]; while(ct<128) x[ct++]=0; ct=0; while(ct<128) { t=GetToken(t,bf); if(!t) return; if(strcmp(bf,"\\")==0) { if(GetLine(f)==NULL) { ELine(); printf("Unexpected EOF.\n"); exit(0); } t=LineBuf; continue; } if(index(bf,'=')) { char *bp=index(bf,'='); *bp++=0; ct=ResolveConstant(bf); if(ct<0||ct>127) { ELine(); log_error("[ERROR]: '=' element specifier too large.\n"); exit(0); } x[ct]=ResolveOConstant(bp,i,o+ct); } else x[ct]=ResolveOConstant(bf,i,o+ct); ct++; } } static tag ConstVal[400]; static char *Constants[400]; LoadConstants(f) FILE *f; { char *bp; int n=0; while(1) { if(GetLine(f)==NULL) { ELine(); log_error("Unexpected EOF.\n"); panic(); } if(*LineBuf=='@') return; bp=index(LineBuf,'='); if(!bp) { ELine(); log_error("Missing '='.\n"); panic(); } *bp++=0; /* * Crude... should be a list really */ if(n==400) { ELine(); log_error("Too many constants.\n"); panic(); } Constants[n]=estralloc(LineBuf); ConstVal[n]=ResolveConstant(bp); n++; } } tag ResolveOConstant(x,i,o) char *x; tag i; int o; { if(*x=='@') { struct Word *dr=FindName(x+1,0); if(!dr) { Push_Resolution(i,o,x+1); return(-1); } else return(ISOBJ(dr->wd_Code)); } return(ResolveConstant(x)); } tag ResolveConstant(x) char *x; { int v; if(isdigit(*x)||*x=='-') { if(sscanf(x,"%d",&v)!=1) { ELine(); log_error("Bad number '%s'.\n",x); panic(); } return(v); } v=0; while(Constants[v]) { if(strcmp(Constants[v],x)==0) return(ConstVal[v]); v++; } ELine(); log_error("Unknown constant '%s'\n",x); panic(); return(0); /* Just to keep compiler happy */ }