#include <stdio.h> #include <ctype.h> #include <string.h> #include "struct.h" /* * Return current player */ tag Me() { return(SysFlags[0]); } /* * Transfer an item between two places, or signal a state shift */ static int ar[MAXU]; void Tree_Unlink(x) tag x; { register tag t; if(LOC(x)==-1) return; if(OBJECT(LOC(x))->ob_Child==x) { OBJECT(LOC(x))->ob_Child= OBJECT(x)->ob_Next; return; } t=OBJECT(LOC(x))->ob_Child; while(t!= -1) { if(OBJECT(t)->ob_Next==x) { OBJECT(t)->ob_Next=OBJECT(x)->ob_Next; return; } t=OBJECT(t)->ob_Next; } fprintf(stderr,"[WARNING]: Item Tree Corruption.\n"); } void Tree_Link(i,c) tag i,c; { if(c!=-1) { OBJECT(i)->ob_Next=OBJECT(c)->ob_Child; OBJECT(c)->ob_Child=i; } else { OBJECT(i)->ob_Next= -1; } } void MoveItem(a,b) tag a,b; { if(TYPE(a)==FL_OBJECT) FLAGS(a)&=~OFL_WORN; if(LOC(a)==b) return; if(b==-2) { /* Special code for State change */ b=LOC(a); return; } /* CheckRedraw(a,LOC(a),ar);*/ Tree_Unlink(a); LOC(a)=b; Tree_Link(a,b); /* CheckRedraw(a,LOC(a),ar);*/ } /* * Check to see if we need to do a redraw */ CheckRedraw(i,a,b) tag i; int a; int *b; { int c=ISOBJ(0); if(a==-1) return(0); while(c<ISOBJ(MAXU)) { if(TYPE(i)==FL_PLAYER&&!CANSEE(c,i)) { c++; continue; } if(LOC(c)==a) b[VAL(c)]=1; c++; } return(1); } /* * Mark it redrawn */ void MarkClean(x) tag x; { if(OBJ(x)<MAXU&&OBJ(x)>=0) ar[VAL(x)]=0; } /* * Do redraw checking stuff */ static int rdip=0; ChkRedraw() { return(rdip); } /* * Actually do the redrawing */ void DoRedraw() { return; /* tag v=Me(); tag c=ISOBJ(0); if(rdip==1) return; rdip=1; while(c<ISOBJ(MAXU)) { if(ar[VAL(c)]) { SysFlags[0]=c; if(UserArray[VAL(c)].us_State=US_CMD) { WriteToHandle(UserArray[OBJ(Me())].us_Handle,PK_UPDT,""); C_Look(); } } ar[VAL(c)]=0; c++; } SysFlags[0]=v; rdip=0; */ } /* * Count currently active users */ UsersActive() { int n=0; tag ct=ISOBJ(0); while(ct<ISOBJ(MAXU)) { if(LOC(ct)!=ISOBJ(-1)) n++; ct++; } return(n); } /* * Weigh up items */ Weight(o) tag o; { return(WeightRec(o,0)); } WeightRec(o,d) tag o; int d; { int ct=OBJECT(o)->ob_Child; int v=(TYPE(o)==FL_OBJECT)?WEIGHT(o):0; if(d>20) return(0); while(ct!=-1) { if(ISITEM(ct)&&TYPE(ct)==FL_OBJECT) { v+=((TYPE(ct)==FL_OBJECT)?WEIGHT(ct):0)+WeightRec(ct,d+1); } ct=OBJECT(ct)->ob_Next; } return(v); } /* * Print up a message */ void PMsg(x) tag x; { extern char **Messages; UPrintf("%s",Messages[MSG(x)]); } /* * Perform an action */ void Does(a,b,c,d) tag a,b,d; int c; { extern char **Messages; DoesT(a,Messages[MSG(b)],c,d); } /* DoesT() ExecTable() Arg(); NextLineMove(); IsDark(); CanPut(); */ /* * Driver for doing actions */ void DoesT(a,b,c,d) tag a,d; int c; char *b; { int ct=ISOBJ(0); if(LOC(a)== ISOBJ(-1)) return; while(ct<ISOBJ(MAXU)) { DoesProcess(a,b,c,d,ct); ct++; } ct=ISOBJ(0); while(ct<ISOBJ(MAXU)) { if(SNOOP(ct)>=ISOBJ(MAXU)) DoesProcess(a,b,c,d,SNOOP(ct)); ct++; } } /* * Capitalised Item Name */ char *MakeCName(x) tag x; { static char bf[128]; if(strlen(NAME(x))>127) return(NAME(x)); /* Bail Out */ strcpy(bf,NAME(x)); if(islower(*bf)) *bf=toupper(*bf); return(bf); } /* * Logic for doing actions */ void DoesProcess(a,b,c,d,ct) tag a,d,ct; int c; char *b; { if(ct==a) { ct++; return; } if(LOC(ct)!=LOC(a)) { ct++; return; } if((TYPE(a)==FL_PLAYER)&&(c&4)&&(FLAGS(ct)&PFL_DEAF)) { ct++; return; } if((TYPE(a)==FL_PLAYER)&&(c&16)&&(FLAGS(ct)&PFL_ASLEEP)) { ct++; return; } if((c&8)&&(FLAGS(ct)&PFL_BLIND)) { ct++; return; } if(TYPE(a)==FL_PLAYER&&CANSEE(ct,a)==0) { if((c&8)&&(FLAGS(ct)&PFL_BLIND)) { ct++; return; } if(c&1) { ct++; return; } if(c&2) { TellUser(ct,"Someone"); } else TellUser(ct,"%s",MakeCName(a)); } else TellUser(ct,"%s",MakeCName(a)); TellUser(ct," %s ",b); if(d!= ISOBJ(-1)) { if(d==ct) TellUser(ct,"you.\n"); else { if(TYPE(d)==FL_PLAYER&&(!CANSEE(ct,d))) { TellUser(ct,"someone.\n"); } else TellUser(ct,"%s.\n",NAME(d)); } } else TellUser(ct,"\n"); if(FLAGS(ct)&PFL_ASLEEP) { FLAGS(ct)&=~PFL_ASLEEP; TellUser(ct,"You wake up.\n"); } ct++; } /* * See if can move an item around */ CanPut(a,b) tag a,b; { tag ct=OBJECT(b)->ob_Child; int v=0; if(TYPE(b)==FL_PLAYER) { return(PCanPut(a,b)); } while(ct!=-1) { if(ISITEM(ct)&&TYPE(ct)==FL_OBJECT) v+=SIZE(ct); ct=OBJECT(ct)->ob_Next; } if(v+SIZE(a)>SIZE(b)) return(0); return(1); } PCanPut(a,b) ITEM a,b; { int v=Weight(a); ITEM i=a; int ct=0; while(ct<NObs()) { if(LOC(i)==-1) break; if(LOC(i)==b) { v=0; break; } i=LOC(i); ct++; } /* printf("Weight=%d, ContWait=%d, Str=%d.\n",v,Weight(b),STRENGTH(b));*/ if(v+Weight(b)>10*STRENGTH(b)) return(0); return(1); } /* * Darkness analyser */ IsDarkFor(x) tag x; { return(IsDark(LOC(x),x)); } IsDark(x,y) tag x; tag y; { int ct; if(x==ISOBJ(-1)) return(0); if(y==ISOBJ(-1)) return(0); ct=OBJECT(x)->ob_Child; if(TYPE(y)==FL_PLAYER) { if(FLAGS(y)&PFL_BLIND) return(1); if(FLAGS(y)&PFL_ASLEEP) return(1); } if(TYPE(y)==FL_PLAYER&&(FLAGS(y)&PFL_SEEDARK)) return(0); if((TYPE(x)==FL_ROOM)&&((FLAGS(x)&RFL_DARK)==0)) return(0); while(ct != -1) { if(ISITEM(ct)&&TYPE(ct)==FL_OBJECT) { if(((FLAGS(ct)&OFL_LIT0)&&STATE(ct)==0)|| ((FLAGS(ct)&OFL_LITALL))) { if(LOC(ct)==x) return(0); } } if(TYPE(ct)==FL_PLAYER&&IsDark(ct,y)==0) return(0); ct=OBJECT(ct)->ob_Next; } return(1); } /* * Remove someone from the game */ void Exit_Player(n) tag n; { extern struct Word *FindNumWord(); struct Word *wd; tag ct=ISOBJ(0); tag v=SysFlags[0]; SysFlags[0]=n; if(n>=ISOBJ(MAXU)) { MoveItem(n,ISOBJ(-1)); } else { if(UserArray[VAL(n)].us_State==US_CMD) ExecTable(7); UserArray[n].us_State=US_IDLE; MoveItem(n,ISOBJ(-1)); } /* printf("DESNOOPING");*/ SETSNOOP(n,ISOBJ(-1)); while(ct<ISOBJ(MAXU)) { if(SNOOP(ct)==n) { SETSNOOP(ct,-1); SendIO(ct,"You can no longer snoop on %s\n",NAME(n)); } ct++; } if(n>=ISOBJ(MAXU)) { SysFlags[0]=v; return; } /* printf("EXITING");*/ wd=FindNumWord(28000+VAL(n),3); if(!wd) { /* printf("Erk! - User without name\n")*/; } else DelWord(wd); SetName(n,"[FREE SLOT]"); SysFlags[0]=v; }