#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;
}