aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Simpson <jjsimpso@gmail.com>2016-11-20 21:33:47 -0500
committerJonathan Simpson <jjsimpso@gmail.com>2016-11-20 21:33:47 -0500
commit20388795ce8fcf1accf177be98dbd1e83fe67ed4 (patch)
tree904573f9ef0f43826c22eeeab6c79afd09a00628
downloadAberMUD-master.tar.gz
AberMUD-master.tar.bz2
AberMUD-master.zip
initial commit of AberMUD 5.30 sourceHEADmaster
-rw-r--r--AberRwho.c55
-rw-r--r--ActionCode.c2255
-rw-r--r--Amiga.c45
-rw-r--r--AnsiBits.c87
-rw-r--r--BSX.c401
-rw-r--r--BootDaemon.c97
-rw-r--r--Class.c193
-rw-r--r--ComDriver.c997
-rw-r--r--ComServer.c358
-rw-r--r--Comms.h55
-rw-r--r--CompileTable.c928
-rw-r--r--CondCode.c646
-rw-r--r--ContCommand.c151
-rw-r--r--Container.c171
-rw-r--r--Daemons.c159
-rw-r--r--DarkLight.c100
-rw-r--r--Duplicator.c350
-rw-r--r--Editing.c1453
-rw-r--r--ExitLogic.c32
-rw-r--r--FindPW.c37
-rw-r--r--FlagControl.c181
-rw-r--r--FlagName.c190
-rw-r--r--GenCommand.c96
-rw-r--r--IPC.h40
-rw-r--r--IPCDirect.c810
-rw-r--r--InsAndOuts.c499
-rw-r--r--LibRwho.c195
-rw-r--r--LibSocket.c114
-rw-r--r--LookFor.c135
-rw-r--r--Main.c148
-rw-r--r--Makefile75
-rw-r--r--NewCmd.c423
-rw-r--r--NoMalloc.c7
-rw-r--r--NoProto.h855
-rw-r--r--ObjCommand.c341
-rw-r--r--ObjectEdit.c305
-rw-r--r--Parser.c536
-rw-r--r--PlyCommand.c334
-rw-r--r--Properties.c194
-rw-r--r--Prototype.h1001
-rw-r--r--README-5.30129
-rw-r--r--README.md1
-rw-r--r--Reg.c41
-rw-r--r--RoomCommands.c413
-rw-r--r--Run_Aber.c56
-rw-r--r--SaveLoad.c1270
-rw-r--r--Snoop.c119
-rw-r--r--Socket.c48
-rw-r--r--SubHandler.c614
-rw-r--r--SysSupport.c904
-rw-r--r--System.c867
-rw-r--r--System.h606
-rw-r--r--TabCommand.c206
-rw-r--r--TableDriver.c969
-rw-r--r--TableEditing.c647
-rw-r--r--TimeSched.c198
-rw-r--r--User.h48
-rw-r--r--UserFile.c181
-rw-r--r--UserVector.c16
-rw-r--r--UtilCommand.c301
-rw-r--r--ValidLogin.c26
61 files changed, 22709 insertions, 0 deletions
diff --git a/AberRwho.c b/AberRwho.c
new file mode 100644
index 0000000..30ddb4e
--- /dev/null
+++ b/AberRwho.c
@@ -0,0 +1,55 @@
+#include "System.h"
+#include "User.h"
+
+extern USER UserList[];
+
+/******************************************************************************
+
+
+ AberMUD 5.20
+
+ This module provides the interface between the database language
+ and the LibRwho.c file provided by the author of the RWHO
+
+ 1.00 AGC Created
+ 1.01 AGC ANSIfication
+
+******************************************************************************/
+
+Module "Rwho Interface Library";
+Author "Alan Cox";
+Version "1.00";
+
+void Act_RwhoDeclareUp(void)
+{
+ char *mudname=TextOf(ArgText());
+ char *mudident=TextOf(ArgText());
+ char *server=TextOf(ArgText());
+ char *serverpw=TextOf(ArgText());
+ rwhocli_setup(server,serverpw,mudname,mudident);
+}
+
+void Act_RwhoDeclareDown(void)
+{
+ rwhocli_shutdown();
+}
+
+void Act_RwhoDeclareAlive(void)
+{
+ rwhocli_pingalive();
+}
+
+void Act_RwhoLogin(void)
+{
+ char *id=TextOf(ArgText());
+ char *name=TextOf(ArgText());
+ int u=UserOf(Me());
+ if(u!=-1)
+ rwhocli_userlogin(id,name,UserList[u].us_Login);
+}
+
+void Act_RwhoLogout(void)
+{
+ char *name=TextOf(ArgText());
+ rwhocli_userlogout(name);
+}
diff --git a/ActionCode.c b/ActionCode.c
new file mode 100644
index 0000000..1dc29b5
--- /dev/null
+++ b/ActionCode.c
@@ -0,0 +1,2255 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+#include "User.h"
+
+extern USER UserList[];
+
+Module "Action Drivers";
+Version "1.20";
+Author "Alan Cox";
+
+/*
+ * 1.10 Current Command Functions
+ * 1.11 SetIn SetOut SetHere fixed along with AutoVerb
+ * 1.12 GetUT SetUT Cat added
+ * 1.13 Added SetClass/UnSetClass/BitClear/BitSet/BitTest etc.
+ * 1.14 Fixed bug with DOCLASS and TAKEOUT, made all saves use
+ * real name field only.
+ * 1.15 Added Ordinates to WHATO/GETO
+ * 1.16 Fixed HURT killing on an attached item
+ * 1.17 INC and GETNEXT
+ * 1.18 Fixed IT setting by POBJ.
+ * 1.19 Merged in Amiga support
+ * 1.20 ANSIfication cleanup
+ */
+
+short ClassMask;
+LINE *ClassLine;
+short ClassMode1,ClassMode2;
+
+void Act_Get(void)
+{
+ ITEM *i=ArgItem();
+ ITEM *s=O_PARENT(Me());
+ OBJECT *o=ObjectOf(i);
+ if(o==NULL)
+ {
+ if(!(ClassMode1||ClassMode2))
+ SendItem(Me(),"You can't take that!\n");
+ return;
+ }
+ if(O_PARENT(i)==Me())
+ {
+ SendItem(Me(),"You are already carrying %s.\n",NameOf(i));
+ return;
+ }
+ if((o->ob_Flags&OB_CANGET)==0)
+ {
+ if(!(ClassMode1||ClassMode2))
+ SendItem(Me(),"You can't take that.\n");
+ return;
+ }
+ else
+ {
+ switch(CanPlace(i,Me()))
+ {
+ case -1:SendItem(Me(),"%s is too large to handle.\n",
+ CNameOf(i));
+ return;
+ case -2:SendItem(Me(),"%s is too heavy for you to carry.\n",
+ CNameOf(i));
+ return;
+ case -3:if(!(ClassMode1||ClassMode2))
+ SendItem(Me(),"You can't carry any more individual items.\n");
+ return;
+ }
+ SendItem(Me(),"You take %s.\n",NameOf(i));
+ DoesTo(Me(),5,i,"takes");
+ s=O_PARENT(Me());
+ Place(Me(),i);
+ DoesTo(Me(),5,i,"picks up");
+ Place(Me(),s);
+ Place(i,Me());
+ return;
+ }
+}
+
+void Act_Drop(void)
+{
+ ITEM *i=ArgItem();
+ ITEM *s;
+ if(O_PARENT(i)!=Me())
+ {
+ SendItem(Me(),"You are not carrying %s.\n",NameOf(i));
+ return;
+ }
+ Place(i,O_PARENT(Me()));
+ DoesTo(Me(),5,i,"drops");
+ s=O_PARENT(Me());
+ Place(Me(),i);
+ DoesTo(Me(),5,i,"puts down");
+ Place(Me(),s);
+ SendItem(Me(),"You drop %s.\n",NameOf(i));
+}
+
+void Act_Wear(void)
+{
+ ITEM *i=ArgItem();
+ OBJECT *o=ObjectOf(i);
+ if(O_PARENT(i)!=Me())
+ {
+ SendItem(Me(),"You are not carrying %s.\n",NameOf(i));
+ return;
+ }
+ if((o==NULL)||((o->ob_Flags&OB_CANWEAR)==0))
+ {
+ if(!(ClassMode1||ClassMode2))
+ SendItem(Me(),"You can't wear %s.\n",NameOf(i));
+ return;
+ }
+ if(o->ob_Flags&OB_WORN)
+ {
+ if(!(ClassMode1||ClassMode2))
+ SendItem(Me(),"You are already wearing %s.\n",NameOf(i));
+ return;
+ }
+ o->ob_Flags|=OB_WORN;
+ DoesTo(Me(),5,i,"wears");
+ SendItem(Me(),"You wear %s.\n",NameOf(i));
+}
+
+void Act_Remove(void)
+{
+ ITEM *i=ArgItem();
+ OBJECT *o=ObjectOf(i);
+ if(O_PARENT(i)!=Me())
+ {
+ SendItem(Me(),"You are not carrying %s.\n",NameOf(i));
+ return;
+ }
+ if((o==NULL)||((o->ob_Flags&OB_WORN)==0))
+ {
+ if(!(ClassMode1||ClassMode2))
+ SendItem(Me(),"You are not wearing %s.\n",NameOf(i));
+ return;
+ }
+ o->ob_Flags&=~OB_WORN;
+ DoesTo(Me(),5,i,"takes off");
+ SendItem(Me(),"You take off %s.\n",NameOf(i));
+}
+
+void Act_Create(void)
+{
+ ITEM *i=ArgItem();
+ OBJECT *o=ObjectOf(i);
+ Place(i,O_PARENT(Me()));
+ if(o)
+ o->ob_Flags&=~OB_DESTROYED;
+}
+
+void Act_Destroy(void)
+{
+ ITEM *i=ArgItem();
+ OBJECT *o=ObjectOf(i);
+ Place(i,NULL);
+ if(o)
+ o->ob_Flags|=OB_DESTROYED;
+ Disintegrate(i); /* if its a clone its a dead clone */
+}
+
+void Act_Swap(void)
+{
+ ITEM *a,*b,*c;
+ a=ArgItem();
+ b=ArgItem();
+ c=O_PARENT(a);
+ Place(a,O_PARENT(b));
+ Place(b,c);
+}
+
+void Act_Place(void)
+{
+ ITEM *a=ArgItem();
+ ITEM *b=ArgItem();
+ Place(a,b);
+}
+
+void Act_PutIn(void)
+{
+ ITEM *a=ArgItem();
+ ITEM *b=ArgItem();
+ ITEM *s;
+ CONTAINER *c=ContainerOf(b);
+ if((c==NULL)||((c->co_Flags&CO_CANPUTIN)==0))
+ {
+ SendItem(Me(),"You can't put things in %s.\n",NameOf(b));
+ ClassMode1=0;ClassMode2=0;
+ return;
+ }
+ if(O_PARENT(a)!=Me())
+ {
+ SendItem(Me(),"You are not carrying %s.\n",NameOf(a));
+ return;
+ }
+ if((c->co_Flags&CO_CLOSES)&&(O_STATE(b)!=0))
+ {
+ SendItem(Me(),"%s is closed.\n",CNameOf(b));
+ ClassMode1=0;ClassMode2=0; /* Cut off ALL */
+ return;
+ }
+ if(CanPlace(a,b)<0)
+ {
+ SendItem(Me(),"%s will not fit in %s.\n",CNameOf(a),NameOf(b));
+ return;
+ }
+ Place(a,b);
+ SendItem(Me(),"You put %s in %s.\n",NameOf(a),NameOf(b));
+ DoesTo(Me(),4,b,"puts %s in",NameOf(a));
+ s=O_PARENT(Me());
+ Place(Me(),a);
+ DoesTo(Me(),5,b,"puts %s in",NameOf(a));
+ Place(Me(),b);
+ DoesTo(Me(),5,b,"puts %s in",NameOf(a));
+ Place(Me(),s);
+}
+
+void Act_TakeOut(void)
+{
+ ITEM *a=ArgItem();
+ ITEM *s;
+ ITEM *b=ArgItem();
+ CONTAINER *c=ContainerOf(b);
+ if((c==NULL)||((c->co_Flags&CO_CANGETOUT)==0))
+ {
+ SendItem(Me(),"You can't take things from %s.\n",NameOf(b));
+ ClassMode1=0;ClassMode2=0;
+ return;
+ }
+ if((c->co_Flags&CO_CLOSES)&&(O_STATE(b)!=0))
+ {
+ SendItem(Me(),"%s is closed.\n",CNameOf(b));
+ ClassMode1=0;ClassMode2=0;
+ return;
+ }
+ if(!IsObject(a))
+ {
+ if(!(ClassMode1||ClassMode2))
+ SendItem(Me(),"You can't take %s.\n",CNameOf(a));
+ return;
+ }
+ if((ObjectOf(a)->ob_Flags&OB_CANGET)==0)
+ {
+ if(!(ClassMode1||ClassMode2))
+ SendItem(Me(),"You can't take %s.\n",CNameOf(a));
+ return;
+ }
+ switch(CanPlace(a,Me()))
+ {
+ case -1:SendItem(Me(),"%s is too large for you to manage.\n",
+ CNameOf(a));
+ return;
+ case -2:SendItem(Me(),"%s is too heavy for you to manage.\n",
+ CNameOf(a));
+ case -3:if(!(ClassMode1||ClassMode2))
+ SendItem(Me(),"You can't carry any more individual items.\n");
+ return;
+ }
+ Place(a,Me());
+ SendItem(Me(),"You take %s from %s.\n",NameOf(a),NameOf(b));
+ DoesTo(Me(),4,b,"takes %s from",NameOf(a));
+ s=O_PARENT(Me());
+ Place(Me(),a);
+ DoesTo(Me(),5,b,"takes %s from",NameOf(a));
+ Place(Me(),b);
+ DoesTo(Me(),5,b,"takes %s from",NameOf(a));
+ Place(Me(),s);
+}
+
+void Act_CopyOF(void)
+{
+ ITEM *i=ArgItem();
+ int n=ArgNum();
+ SetFlag(ArgNum(),GetUserFlag(i,n));
+}
+
+void Act_CopyFO(void)
+{
+ int n=ArgNum();
+ ITEM *i=ArgItem();
+ SetUserFlag(i,ArgNum(),GetFlag(n));
+}
+
+void Act_CopyFF(void)
+{
+ int a=ArgNum();
+ int b=ArgNum();
+ SetFlag(b,GetFlag(a));
+}
+
+void Act_WhatO(void)
+{
+ extern ITEM *Item1,*Item2;
+ int a=ArgNum();
+ int o=Ord1;
+ if(a==1)
+ {
+ Item1=FindMaster(LevelOf(Me()),(short)Adj1,(short)Noun1);
+ if(!Item1)
+ return;
+ while(--o)
+ {
+ Item1=NextMaster(LevelOf(Me()),Item1,(short)Adj1,
+ (short)Noun1);
+ if(!Item1)
+ return;
+ }
+ return;
+ }
+ else
+ {
+ o=Ord2;
+ Item2=FindMaster(LevelOf(Me()),(short)Adj2,(short)Noun2);
+ if(!Item2)
+ return;
+ while(--o)
+ {
+ Item2=NextMaster(LevelOf(Me()),Item2,(short)Adj2,
+ (short)Noun2);
+ if(!Item2)
+ return;
+ }
+ return;
+ }
+}
+
+void Act_GetO(void)
+{
+ extern ITEM *Item1,*Item2;
+ int o=Ord1;
+ int a=ArgNum();
+ ITEM *b=ArgItem();
+ if(a==1)
+ {
+ Item1=FindIn(LevelOf(Me()),b,(short)Adj1,(short)Noun1);
+ if(!Item1)
+ return;
+ while(--o)
+ {
+ Item1=NextIn(LevelOf(Me()),Item1,(short)Adj1,
+ (short)Noun1);
+ if(!Item1)
+ return;
+ }
+ return;
+ }
+ else
+ {
+ Item2=FindIn(LevelOf(Me()),b,(short)Adj2,(short)Noun2);
+ if(!Item2)
+ return;
+ o=Ord2;
+ while(--o)
+ {
+ Item2=NextIn(LevelOf(Me()),Item1,(short)Adj2,
+ (short)Noun2);
+ if(!Item2)
+ return;
+ }
+ return;
+ }
+
+}
+
+void Act_Weigh(void)
+{
+ ITEM *i=ArgItem();
+ int n=ArgNum();
+ SetFlag(n,WeighUp(i));
+}
+
+void Act_Set(void)
+{
+ SetFlag(ArgNum(),255);
+}
+
+void Act_Clear(void)
+{
+ SetFlag(ArgNum(),0);
+}
+
+void Act_PSet(void)
+{
+ PLAYER *p=PlayerOf(ArgItem());
+ int n=ArgNum();
+ if(p)
+ p->pl_Flags|=(1<<n);
+}
+
+void Act_PClear(void)
+{
+ PLAYER *p=PlayerOf(ArgItem());
+ int n=ArgNum();
+ if(p)
+ p->pl_Flags&=~(1<<n);
+}
+
+void Act_Let(void)
+{
+ int a=ArgNum();
+ SetFlag(a,ArgNum());
+}
+
+void Act_Add(void)
+{
+ int a=ArgNum();
+ SetFlag(a,GetFlag(a)+ArgNum());
+}
+
+void Act_Sub(void)
+{
+ int a=ArgNum();
+ SetFlag(a,GetFlag(a)-ArgNum());
+}
+
+void Act_AddF(void)
+{
+ int a=ArgNum();
+ SetFlag(a,GetFlag(a)+GetFlag(ArgNum()));
+}
+
+void Act_SubF(void)
+{
+ int a=ArgNum();
+ SetFlag(a,GetFlag(a)-GetFlag(ArgNum()));
+}
+
+void Act_Mul(void)
+{
+ int a=ArgNum();
+ SetFlag(a,GetFlag(a)*ArgNum());
+}
+
+void Act_Div(void)
+{
+ int a=ArgNum();
+ int b=ArgNum();
+ if(b==0)
+ {
+ Log("Division By Zero");
+ SendItem(Me(),"Division By Zero!\n");
+ return;
+ }
+ SetFlag(a,GetFlag(a)/b);
+}
+
+void Act_MulF(void)
+{
+ int a=ArgNum();
+ SetFlag(a,GetFlag(a)*GetFlag(ArgNum()));
+}
+
+void Act_DivF(void)
+{
+ int a=ArgNum();
+ int b=GetFlag(ArgNum());
+ if(b==0)
+ {
+ Log("Division By Zero");
+ SendItem(Me(),"Division By Zero.\n");
+ return;
+ }
+ SetFlag(a,GetFlag(a)/b);
+}
+
+void Act_Mod(void)
+{
+ int a=ArgNum();
+ int b=ArgNum();
+ if(b==0)
+ {
+ SendItem(Me(),"Division By Zero In MOD.\n");
+ Log("Division By 0 In MOD.\n");
+ return;
+ }
+ SetFlag(a,GetFlag(a)%b);
+}
+
+void Act_ModF(void)
+{
+ int a=ArgNum();
+ int b=GetFlag(ArgNum());
+ if(b==0)
+ {
+ SendItem(Me(),"Division By Zero In MODF.\n");
+ Log("Division By 0 In MODF.\n");
+ return;
+ }
+ SetFlag(a,GetFlag(a)%b);
+}
+
+void Act_Random(void)
+{
+ int a=ArgNum();
+ unsigned int b=ArgNum();
+ unsigned int b2;
+ unsigned short v;
+regen: b2=b;
+ v=rand()%32768;
+ if(b==0)
+ {
+ SendItem(Me(),"Invalid Random Range.\n");
+ Log("Invalid Random Range.\n");
+ return;
+ }
+ b=32768/b;
+ if(b==0)
+ {
+ SendItem(Me(),"Invalid Random Range.\n");
+ Log("Random Too Large.\n");
+ return;
+ }
+ if(v/b==b2)
+ {
+ b=b2;
+ goto regen;
+ }
+ SetFlag(a,(v/b));
+}
+
+void Act_Move(void)
+{
+ Cmd_MoveDirn(Me(),GetFlag(ArgNum()));
+}
+
+void Act_Goto(void)
+{
+ ITEM *i=ArgItem();
+ DoesAction(Me(),4,"has left.\n");
+ Place(Me(),i);
+ DoesAction(Me(),4,"arrives.\n");
+}
+
+void Act_Weight(void)
+{
+ ITEM *i=ArgItem();
+ OBJECT *o=ObjectOf(i);
+ PLAYER *p=PlayerOf(i);
+ int n=ArgNum();
+ if(o)
+ o->ob_Weight=n;
+ if(p)
+ p->pl_Weight=n;
+}
+
+void Act_Size(void)
+{
+ ITEM *i=ArgItem();
+ OBJECT *o=ObjectOf(i);
+ PLAYER *p=PlayerOf(i);
+ int n=ArgNum();
+ if(o)
+ o->ob_Size=n;
+ if(p)
+ p->pl_Size=n;
+
+}
+
+void Act_OSet(void)
+{
+ OBJECT *o=ObjectOf(ArgItem());
+ int n=ArgNum();
+ if(o)
+ o->ob_Flags|=(1<<n);
+}
+
+void Act_OClear(void)
+{
+ OBJECT *o=ObjectOf(ArgItem());
+ int n=ArgNum();
+ if(o)
+ o->ob_Flags&=~(1<<n);
+}
+
+void Act_RSet(void)
+{
+ ROOM *r=RoomOf(ArgItem());
+ int n=ArgNum();
+ if(r)
+ r->rm_Flags|=(1<<n);
+}
+
+void Act_RClear(void)
+{
+ ROOM *r=RoomOf(ArgItem());
+ int n=ArgNum();
+ if(r)
+ r->rm_Flags&=~(1<<n);
+}
+
+void Act_CSet(void)
+{
+ CONTAINER *c=ContainerOf(ArgItem());
+ int n=ArgNum();
+ if(c)
+ c->co_Flags|=(1<<n);
+}
+
+void Act_CClear(void)
+{
+ CONTAINER *c=ContainerOf(ArgItem());
+ int n=ArgNum();
+ if(c)
+ c->co_Flags&=~(1<<n);
+}
+
+void Act_PutBy(void)
+{
+ ITEM *a=ArgItem();
+ Place(a,O_PARENT(ArgItem()));
+}
+
+void Act_Inc(void)
+{
+ ITEM *i=ArgItem();
+ if(O_STATE(i)>2)
+ return;
+ SetState(i,(short)(O_STATE(i)+1));
+ SynchChain(i);
+}
+
+void Act_Dec(void)
+{
+ ITEM *i=ArgItem();
+ if(O_STATE(i)<1)
+ return;
+ SetState(i,(short)(O_STATE(i)-1));
+ SynchChain(i);
+}
+
+void Act_SetState(void)
+{
+ ITEM *i=ArgItem();
+ int n=ArgNum();
+ if(n<0) n=0;
+ if(n>3) n=3;
+ SetState(i,(short)(n));
+ SynchChain(i);
+}
+
+void Act_Prompt(void)
+{
+ char *a=TextOf(ArgText());
+ SetPrompt(Me(),a);
+}
+
+void Act_Print(void)
+{
+ SendItem(Me(),"%d",GetFlag(ArgNum()));
+}
+
+void Act_Score(void)
+{
+ PLAYER *p=PlayerOf(Me());
+ SendItem(Me(),"Your score is %ld.\n",p->pl_Score);
+}
+
+void Act_Message(void)
+{
+ SendItem(Me(),"%s\n",TextOf(ArgText()));
+}
+
+void Act_Msg(void)
+{
+ SendItem(Me(),"%s",TextOf(ArgText()));
+}
+
+void Act_MessageTo(void)
+{
+ ITEM *i=ArgItem();
+ SendItem(i,"%s\n",TextOf(ArgText()));
+}
+
+void Act_MsgTo(void)
+{
+ ITEM *i=ArgItem();
+ SendItem(i,"%s",TextOf(ArgText()));
+}
+
+static ITEM *NextVisible(ITEM *i)
+{
+ i=O_NEXT(i);
+ if(i==NULL)
+ return(NULL);
+ while(i!=NULL && !CanSee(LevelOf(Me()),i))
+ i=O_NEXT(i);
+ return(i);
+}
+
+void Act_ListObj(void)
+{
+ ITEM *i=O_CHILDREN(ArgItem());
+ int n=0;
+ while(i!=NULL && !CanSee(LevelOf(Me()),i))
+ i=O_NEXT(i);
+ if(i==NULL)
+ {
+ SendItem(Me(),"nothing");
+ }
+ else
+ {
+ while(i)
+ {
+ if(n==0)
+ n=1;
+ else
+ {
+ if(NextVisible(i))
+ SendItem(Me(),", ");
+ else
+ SendItem(Me()," and ");
+ }
+ SendItem(Me(),"%s",NameOf(i));
+ if(IsObject(i)&&ObjectOf(i)->ob_Flags&OB_WORN)
+ SendItem(Me(),"(worn)");
+ i=NextVisible(i);
+ }
+ }
+}
+
+void Act_ListAt(void)
+{
+ ITEM *i=ArgItem();
+ i=O_CHILDREN(i);
+ while(i)
+ {
+ if(CanSee(LevelOf(Me()),i))
+ DescribeItem(Me(),i);
+ i=O_NEXT(i);
+ }
+}
+
+void Act_Inven(void)
+{
+ ITEM *i=O_CHILDREN(Me());
+ int n=0;
+ SendItem(Me(),"You are carrying ");
+ while(i!=NULL && !CanSee(LevelOf(Me()),i))
+ i=O_NEXT(i);
+ if(i==NULL)
+ {
+ SendItem(Me(),"nothing.\n");
+ }
+ else
+ {
+ while(i)
+ {
+ if(n==0)
+ n=1;
+ else
+ {
+ if(NextVisible(i))
+ SendItem(Me(),", ");
+ else
+ SendItem(Me()," and ");
+ }
+ SendItem(Me(),"%s",NameOf(i));
+ if(IsObject(i)&&ObjectOf(i)->ob_Flags&OB_WORN)
+ SendItem(Me(),"(worn)");
+ i=NextVisible(i);
+ }
+ SendItem(Me(),".\n");
+ }
+}
+
+void Act_Desc(void)
+{
+ Cmd_Look(Me());
+}
+
+void Act_End(void)
+{
+ int u;
+ if((u=UserOf(Me()))==-1)
+ return;
+ SendItem(Me(),"%s\n",TextOf(ArgText()));
+#ifdef ATTACH
+ if(UserList[u].us_RealPerson)
+ {
+ Act_UnAlias();
+ return;
+ }
+#endif
+ SendTPacket(UserList[u].us_Port,PACKET_CLEAR,
+ "\nBye Bye....\n");
+ RemoveUser(u);
+ SetMe(NULL);
+}
+
+void Act_Done(void){;}
+void Act_NotDone(void){;}
+
+void Act_Ok(void)
+{
+ SendItem(Me(),"Ok.\n");
+ Act_Done();
+}
+
+void Act_Abort(void)
+{
+ exit(0);
+}
+
+void Act_Save(void)
+{
+ static UFF SaveUFF;
+ PLAYER *p=PlayerOf(Me());
+ int n=UserOf(Me());
+ if(n==-1)
+ return;
+#ifdef ATTACH
+ if(UserList[n].us_RealPerson)
+ return;
+#endif
+ UserList[n].us_Record=LoadPersona(UserList[n].us_Name,&SaveUFF);
+ strcpy(SaveUFF.uff_Name,UserList[n].us_Name);
+ SaveUFF.uff_Perception=Me()->it_Perception;
+ SaveUFF.uff_ActorTable=Me()->it_ActorTable;
+ SaveUFF.uff_ActionTable=Me()->it_ActionTable;
+ SaveUFF.uff_Size=p->pl_Size;
+ SaveUFF.uff_Weight=p->pl_Weight;
+ SaveUFF.uff_Strength=p->pl_Strength;
+ SaveUFF.uff_Flags=p->pl_Flags;
+ SaveUFF.uff_Level=p->pl_Level;
+ SaveUFF.uff_Score=p->pl_Score;
+ SaveUFF.uff_Flag[0]=GetUserFlag(Me(),0);
+ SaveUFF.uff_Flag[1]=GetUserFlag(Me(),1);
+ SaveUFF.uff_Flag[2]=GetUserFlag(Me(),2);
+ SaveUFF.uff_Flag[3]=GetUserFlag(Me(),3);
+ SaveUFF.uff_Flag[4]=GetUserFlag(Me(),4);
+ SaveUFF.uff_Flag[5]=GetUserFlag(Me(),5);
+ SaveUFF.uff_Flag[6]=GetUserFlag(Me(),6);
+ SaveUFF.uff_Flag[7]=GetUserFlag(Me(),7);
+ SaveUFF.uff_Flag[8]=GetUserFlag(Me(),14);
+ SaveUFF.uff_Flag[9]=GetUserFlag(Me(),15);
+ strncpy(SaveUFF.uff_Password,UserList[n].us_Password,8);
+ if(UserList[n].us_Record==-1)
+ {
+ UserList[n].us_Record=SaveNewPersona(&SaveUFF);
+ }
+ else
+ SavePersona(&SaveUFF,UserList[n].us_Record);
+}
+
+
+void Act_NewText(void)
+{
+ WordPtr=NULL;
+ if(UserOf(Me())>=0)
+ {
+ PCONTEXT *p=GetContext((short)UserOf(Me()));
+ p->pa_It[0]=-1;
+ p->pa_It[1]=-1;
+ p->pa_Them[0]=-1;
+ p->pa_Them[1]=-1;
+ p->pa_Him[0]=-1;
+ p->pa_Him[1]=-1;
+ p->pa_Her[0]=-1;
+ p->pa_Her[1]=-1;
+ p->pa_There[0]=-1;
+ p->pa_There[1]=-1;
+ }
+}
+
+void Act_Process(void)
+{
+ TABLE *t=FindTable(ArgNum());
+ if(t)
+ ExecTable(t);
+}
+
+void Act_DoClass(void)
+{
+ ITEM *i=ArgItem();
+ short cm=ArgNum();
+ short num=ArgNum();
+ ClassMask=(cm!=-1)?1<<cm:0;
+ ClassLine=CurrentLine->li_Next; /* Line to doclass from */
+ if(num==1)
+ {
+ Item1=FindInByClass(LevelOf(Me()),i,(short)(1<<cm));
+ if(Item1)
+ ClassMode1=1;
+ else
+ ClassMode1=0;
+ }
+ else
+ {
+ Item2=FindInByClass(LevelOf(Me()),i,(short)(1<<cm));
+ if(Item2)
+ ClassMode2=1;
+ else
+ ClassMode2=0;
+ }
+}
+
+void Act_Give(void)
+{
+ ITEM *a=ArgItem();
+ ITEM *b=ArgItem();
+ if(O_PARENT(a)!=Me())
+ {
+ SendItem(Me(),"You are not carrying %s.\n",NameOf(a));
+ return;
+ }
+ if(CanPlace(a,b)<0)
+ {
+ SendItem(Me(),"%s can't carry %s.\n",CNameOf(b),NameOf(a));
+ return;
+ }
+ Place(a,b);
+ SendItem(b,"%s gives you %s.\n",CNameOf(Me()),NameOf(a));
+}
+
+
+void Act_DoesAction(void)
+{
+ ITEM *i=ArgItem();
+ TPTR t=ArgText();
+ int n=ArgNum();
+ DoesAction(i,(short)n,"%s",TextOf(t));
+}
+
+void Act_DoesTo(void)
+{
+ ITEM *i=ArgItem();
+ TPTR t=ArgText();
+ ITEM *j=ArgItem();
+ int n=ArgNum();
+ DoesTo(i,(short)n,j,"%s",TextOf(t));
+}
+
+void Act_DoesToPlayer(void)
+{
+ ITEM *i=ArgItem();
+ TPTR t=ArgText();
+ ITEM *j=ArgItem();
+ int n=ArgNum();
+ DoesToPlayer(i,(short)n,j,"%s",TextOf(t));
+}
+
+void Act_PObj(void)
+{
+ ITEM *i=ArgItem();
+ OBJECT *o=ObjectOf(i);
+ int n=ArgNum();
+ if((n<0)||(n>3))
+ return;
+ if(o)
+ {
+ SendItem(Me(),"%s",TextOf(o->ob_Text[n]));
+ if(UserOf(Me())!=-1)
+ SetItData((short)UserOf(Me()),i,i->it_Adjective,i->it_Noun);
+ }
+}
+
+void Act_PLoc(void)
+{
+ ITEM *i=ArgItem();
+ ROOM *r=RoomOf(i);
+ int n=ArgNum();
+ if(r)
+ {
+ if(UserOf(Me())!=-1)
+ SetItData((short)UserOf(Me()),i,i->it_Adjective,i->it_Noun);
+ if(!n)
+ SendItem(Me(),"%s",r->rm_Short);
+ else
+ SendItem(Me(),"%s",r->rm_Long);
+ }
+}
+
+void Act_PName(void)
+{
+ ITEM *i=ArgItem();
+ PLAYER *p=PlayerOf(i);
+ if(CanSee(LevelOf(Me()),i)==0)
+ {
+ if(p)
+ SendItem(Me(),"someone");
+ else
+ SendItem(Me(),"something");
+ }
+ else
+ {
+ SendItem(Me(),NameOf(i));
+ SetItData(-1,i,i->it_Adjective,i->it_Noun);
+ }
+}
+
+void Act_PCName(void)
+{
+ ITEM *i=ArgItem();
+ PLAYER *p=PlayerOf(i);
+ if(CanSee(LevelOf(Me()),i)==0)
+ {
+ if(p)
+ SendItem(Me(),"Someone");
+ else
+ SendItem(Me(),"Something");
+ }
+ else
+ {
+ SendItem(Me(),CNameOf(i));
+ SetItData(-1,i,i->it_Adjective,i->it_Noun);
+ }
+}
+
+void Act_Daemon(void)
+{
+ ITEM *i=ArgItem();
+ int v=ArgWord();
+ int n1=ArgWord();
+ RunDaemon(i,v,n1,ArgWord());
+}
+
+void Act_AllDaemon(void)
+{
+ int v=ArgWord();
+ int n=ArgWord();
+ AllDaemon(v,n,ArgWord());
+}
+
+void Act_HDaemon(void)
+{
+ ITEM *i=ArgItem();
+ int v=ArgWord();
+ int n1=ArgWord();
+ HDaemon(i,v,n1,ArgWord());
+}
+
+void Act_When(void)
+{
+ int time=ArgNum();
+ int table=ArgNum();
+ AddEvent((unsigned long)time,(short)table);
+}
+
+void Act_SetName(void)
+{
+ ITEM *i=ArgItem();
+ TPTR t=ArgText();
+ SetName(i,TextOf(t));
+}
+
+void Act_Dup(void)
+{
+ ITEM *i=ArgItem(); /* source item */
+ short f=ArgNum(); /* 1 = true dup */
+ short g=ArgNum(); /* $(x)=new item */
+ ITEM *n;
+ n=Clone_Item(i,f);
+ if(g==1)
+ Item1=n;
+ else
+ Item2=n;
+}
+
+
+void Act_Points(void)
+{
+ PLAYER *p=PlayerOf(Me());
+ if(p)
+ p->pl_Score+=ArgNum();
+}
+
+void Act_Hurt(void)
+{
+ PLAYER *p=PlayerOf(Me());
+ if(p==NULL)
+ {
+ ArgNum();
+ return;
+ }
+ p->pl_Strength-=ArgNum();
+ if(p->pl_Strength<0)
+ {
+ int u=UserOf(Me());
+ if(u==-1)
+ Place(Me(),NULL);
+ else
+ {
+#ifdef ATTACH
+ if(UserList[u].us_RealPerson==NULL)
+ {
+#endif
+
+ if(UserList[u].us_Record!=-1)
+ {
+ UFF SaveUFF;
+ UserList[u].us_Record=LoadPersona(
+ UserList[u].us_Name,&SaveUFF);
+#ifdef PANSY_MODE
+ p->pl_Score/=2;
+ p->pl_Strength=10;
+#else
+#ifdef REGISTER
+ p->pl_Score=-1L;
+#else
+ strcpy(SaveUFF.uff_Name," ");
+#endif
+#endif
+ SaveUFF.uff_Perception=Me()->it_Perception;
+ SaveUFF.uff_ActorTable=Me()->it_ActorTable;
+ SaveUFF.uff_ActionTable=Me()->it_ActionTable;
+ SaveUFF.uff_Size=p->pl_Size;
+ SaveUFF.uff_Weight=p->pl_Weight;
+ SaveUFF.uff_Strength=p->pl_Strength;
+ SaveUFF.uff_Flags=p->pl_Flags;
+ SaveUFF.uff_Level=p->pl_Level;
+ SaveUFF.uff_Score=p->pl_Score;
+ SaveUFF.uff_Flag[9]=GetUserFlag(Me(),15);
+ strncpy(SaveUFF.uff_Password,UserList[u].us_Password,8);
+ UserList[u].us_Record=SavePersona(&SaveUFF,
+ UserList[u].us_Record);
+ }
+ SendItem(Me(),
+ "You seem to have died from your injuries...");
+ SendTPacket(UserList[u].us_Port,PACKET_CLEAR,
+ "\nBye Bye....\n");
+ RemoveUser(u);
+#ifdef ATTACH
+ }
+ else
+ Place(Me(),NULL);
+#endif
+ }
+ SetMe(NULL);
+ }
+}
+
+
+void Act_Cured(void)
+{
+ PLAYER *p=PlayerOf(Me());
+ p->pl_Strength+=ArgNum();
+}
+
+void Act_KillOff(void)
+{
+ PLAYER *p=PlayerOf(Me());
+ int n=UserOf(Me());
+ if(n==-1)
+ return;
+#ifdef ATTACH
+ if(UserList[n].us_RealPerson) /* Attached */
+ {
+ Place(Me(),NULL);
+ SendItem(Me(),"%s\n",ArgText());
+ Act_UnAlias();
+ return;
+ }
+#endif
+ if(UserList[n].us_Record!=-1)
+ {
+ UFF SaveUFF;
+ UserList[n].us_Record=LoadPersona(UserList[n].us_Name,&SaveUFF);
+ strcpy(SaveUFF.uff_Name," ");
+ SaveUFF.uff_Perception=Me()->it_Perception;
+ SaveUFF.uff_ActorTable=Me()->it_ActorTable;
+ SaveUFF.uff_ActionTable=Me()->it_ActionTable;
+ SaveUFF.uff_Size=p->pl_Size;
+ SaveUFF.uff_Weight=p->pl_Weight;
+ SaveUFF.uff_Strength=p->pl_Strength;
+ SaveUFF.uff_Flags=p->pl_Flags;
+ SaveUFF.uff_Level=p->pl_Level;
+ SaveUFF.uff_Score=p->pl_Score;
+ strncpy(SaveUFF.uff_Password,UserList[n].us_Password,8);
+ UserList[n].us_Record=SavePersona(&SaveUFF,
+ UserList[n].us_Record);
+ }
+ Act_End();
+}
+
+
+int Act_If1(void)
+{
+ return(Item1!=NULL);
+}
+
+int Act_If2(void)
+{
+ return(Item2!=NULL);
+}
+
+void Act_Bug(void)
+{
+ Log("Bug Entry: %s - %s\n",CNameOf(Me()),TextOf(ArgText()));
+}
+
+void Act_Typo(void)
+{
+ Log("Typo: %s - %s\n",CNameOf(Me()),TextOf(ArgText()));
+}
+
+
+int Act_IsMe(void)
+{
+ return(ArgItem()==Me());
+}
+
+void Act_Broadcast(void)
+{
+ char *t=TextOf(ArgText());
+ Broadcast(t,ArgNum());
+}
+
+int Cnd_IsCalled(void)
+{
+ ITEM *i=ArgItem();
+ char *t=TextOf(ArgText());
+ if(stricmp(NameOf(i),t)==0)
+ {
+ return(1);
+ }
+ return(0);
+}
+
+void Act_SetMe(void)
+{
+ SetMe(ArgItem());
+}
+
+static void Pitem(short a, short n)
+{
+ ITEM *i=FindIn(LevelOf(Me()),Me(),a,n);
+ if(!i)
+ i=FindIn(LevelOf(Me()),O_PARENT(Me()),a,n);
+ if(i)
+ SendItem(Me(),CNameOf(i));
+ else
+ {
+ i=FindMaster(LevelOf(Me()),a,n);
+ if((i)&&(UserOf(i)!=-1))
+ SendItem(Me(),CNameOf(i));
+ }
+}
+
+static void Pglobal(short a, short n)
+{
+ ITEM *i=FindMaster(LevelOf(Me()),a,n);
+ if(i)
+ SendItem(Me(),CNameOf(i));
+}
+
+void Act_Pronouns(void)
+{
+ PCONTEXT *p;
+ if(UserOf(Me())<0)
+ return;
+ SendItem(Me(),"Me : %s\n",CNameOf(Me()));
+ SendItem(Me(),"It : ");
+ p=GetContext((short)UserOf(Me()));
+ Pitem(p->pa_It[0],p->pa_It[1]);
+ SendItem(Me(),"\nThem : ");
+ Pitem(p->pa_Them[0],p->pa_Them[1]);
+ SendItem(Me(),"\nHim : ");
+ Pitem(p->pa_Him[0],p->pa_Him[1]);
+ SendItem(Me(),"\nHer : ");
+ Pitem(p->pa_Her[0],p->pa_Her[1]);
+ SendItem(Me(),"\nThere : ");
+ Pglobal(p->pa_There[0],p->pa_There[1]);
+ SendItem(Me(),"\n\n");
+}
+
+void Act_Exits(void)
+{
+ Cmd_Exits(Me(),ArgItem());
+}
+
+void Act_PWChange(void)
+{
+ short s=UserOf(Me());
+ if(s==-1)
+ return;
+ SendUser(s,"What is your current password ?\n");
+ SendNPacket(UserList[s].us_Port,PACKET_ECHO,1,0,0,0);
+ UserList[s].us_State=AWAIT_PWVERIFY;
+}
+
+void PWVerify(short u,char *v)
+{
+ if(strncmp(UserList[u].us_Password,v,8))
+ {
+ SendUser(u,"Sorry. no.\n");
+ UserList[u].us_State=AWAIT_COMMAND;
+ SendNPacket(UserList[u].us_Port,PACKET_ECHO,0,0,0,0);
+ PermitInput(u);
+ return;
+ }
+ SendUser(u,"New Password ?\n");
+ UserList[u].us_State=AWAIT_PWNEW;
+ PermitInput((int)u);
+}
+
+void PWNew(short u,char *v)
+{
+ UserList[u].us_UserPtr=malloc(9);
+ strncpy(UserList[u].us_UserPtr,v,8);
+ SendUser(u,"Again to make sure it is correct\n");
+ UserList[u].us_State=AWAIT_PWVERNEW;
+ PermitInput((int)u);
+}
+
+void PWNewVerify(short u,char *v)
+{
+ if(strcmp(v,UserList[u].us_UserPtr))
+ {
+ SendUser(u,"Incorrect\n");
+ }
+ else
+ {
+ SendUser(u,"Password Changed\n");
+ strncpy(UserList[u].us_Password,UserList[u].us_UserPtr,8);
+ }
+ free(UserList[u].us_UserPtr);
+ UserList[u].us_State=AWAIT_COMMAND;
+ SendNPacket(UserList[u].us_Port,PACKET_ECHO,0,0,0,0);
+ PermitInput((int)u);
+}
+
+void Act_Snoop(void)
+{
+ StartSnoop(Me(),ArgItem(),SN_PLAYER);
+}
+
+void Act_UnSnoop(void)
+{
+ short v=ArgNum();
+ ITEM *i=ArgItem();
+ if(v)
+ StopAllSnoops(Me());
+ else
+ StopSnoopOn(Me(),i);
+}
+
+void Act_Debug(void)
+{
+ System_Debug=ArgNum();
+}
+
+void Act_GetScore(void)
+{
+ PLAYER *p=PlayerOf(ArgItem());
+ SetFlag(ArgNum(),p?p->pl_Score:0);
+}
+
+void Act_GetStr(void)
+{
+ PLAYER *p=PlayerOf(ArgItem());
+ SetFlag(ArgNum(),p?p->pl_Strength:0);
+}
+
+void Act_GetLev(void)
+{
+ PLAYER *p=PlayerOf(ArgItem());
+ SetFlag(ArgNum(),p?p->pl_Level:0);
+}
+
+void Act_SetScore(void)
+{
+ PLAYER *p=PlayerOf(ArgItem());
+ int n=ArgNum();
+ if(p)
+ p->pl_Score=GetFlag(n);
+}
+
+void Act_SetStr(void)
+{
+ PLAYER *p=PlayerOf(ArgItem());
+ int n=ArgNum();
+ if(p)
+ p->pl_Strength=GetFlag(n);
+}
+
+void Act_SetLev(void)
+{
+ PLAYER *p=PlayerOf(ArgItem());
+ int n=ArgNum();
+ if(p)
+ p->pl_Level=GetFlag(n);
+}
+
+void Act_Shell(void)
+{
+/***
+ *
+ * WARNING: THIS BIT IS VERY MACHINE SPECIFIC!!!!!
+ *
+ ***/
+ int u;
+#ifdef SECURE
+ return;
+#else
+/* Low security setting provides basic facilities of cat file
+ and date - just those which the supplied db uses - to all
+ The theory is arches cant do much damage with it. For linking
+ to user services either add them here or see the USER action
+ */
+ char *a=TextOf(ArgText());
+ if(strncmp(a,"cat",3)==0||strncmp(a,"/bin/cat",8)==0)
+ {
+ char *b=strchr(a,' ');
+ char x[256];
+ FILE *f;
+ if(b)
+ {
+ if((f=fopen(b+1,"r"))!=NULL)
+ {
+ while(fgets(x,255,f)!=NULL)
+ SendItem(Me(),x);
+ fclose(f);
+ }
+ }
+ return;
+ }
+ if(strcmp(a,"date")==0||strcmp(a,"/bin/date")==0)
+ {
+ long t;
+ time(&t);
+ SendItem(Me(),ctime(&t));
+ return;
+ }
+ u=UserOf(Me());
+ if(u==-1)
+ {
+ SendItem(Me(),"Refused: Not User\n");
+ return;
+ }
+ if(strchr(UserList[u].us_UserName,':')!=NULL)
+ { /* Login as Internet: or Janet: or similar (not a local) */
+ SendItem(Me(),"Refused:Security\n");
+ return;
+ }
+#ifdef UNIX
+/* Optionally put limits on local names allowed to use it here */
+ {
+ char x[128];
+ FILE *p=popen(a,"r");
+ while(fgets(x,127,p))
+ SendItem(Me(),"%s",x);
+ pclose(p);
+ }
+#endif
+#endif
+}
+
+void Act_TreeDaemon(void)
+{
+ ITEM *i=ArgItem();
+ int v=ArgWord();
+ int n1=ArgWord();
+ TreeDaemon(i,v,n1,ArgWord());
+}
+
+void Act_ChainDaemon(void)
+{
+ ITEM *i=ArgItem();
+ int v=ArgWord();
+ int n1=ArgWord();
+ ChainDaemon(i,v,n1,ArgWord());
+}
+
+void Act_Means(void)
+{
+ Verb=ArgWord();
+ Noun1=ArgWord();
+ Noun2=ArgWord();
+ if(ArgNum())
+ {
+ short Noun3=Noun1; /* Selected SWAPword */
+ Noun1=Noun2;
+ Noun2=Noun3;
+ }
+}
+
+void Act_CanGoto(void)
+{
+ ITEM *i=ArgItem();
+ int n=ArgNum();
+ SetFlag(n,CanGoto(Me(),i));
+}
+
+void Act_CanGoBy(void)
+{
+ ITEM *i=ArgItem();
+ int n=ArgNum();
+ SetFlag(n,CanGoto(Me(),O_PARENT(i)));
+}
+
+
+void Act_GetIFlag(void)
+{
+ extern ITEM *Item1,*Item2;
+ ITEM *i=ArgItem();
+ int n=ArgNum();
+ if(ArgNum()!=1)
+ Item2=GetUserItem(i,n);
+ else
+ Item1=GetUserItem(i,n);
+}
+
+void Act_SetIFlag(void)
+{
+ ITEM *i=ArgItem();
+ int x=ArgNum();
+ ITEM *n=ArgItem();
+ SetUserItem(i,x,n);
+}
+
+void Act_ClearIFlag(void)
+{
+ ITEM *i=ArgItem();
+ int x=ArgNum();
+ SetUserItem(i,x,NULL);
+}
+
+void Act_Parse(void)
+{
+ char *a=TextOf(ArgText());
+ char *ow=WordPtr;
+ int v;
+ short oa1=Adj1,oa2=Adj2,on1=Noun1,on2=Noun2,ov=Verb,op=Prep;
+ ITEM *oi1=Item1,*oi2=Item2;
+ TXT *t=AllocText(a);
+ WordPtr=TextOf(t);
+ v=GetVerb();
+ UserAction(Me(),v);
+ Adj1=oa1;Adj2=oa2;Noun1=on1;Noun2=on2;Verb=ov;Prep=op;
+ Item1=oi1;Item2=oi2;
+ WordPtr=ow;
+ FreeText(t);
+}
+
+void Act_Comment(void)
+{
+ ArgText();
+}
+
+void Act_ComVocab(void)
+{
+ char *ow=WordPtr;
+ TABLE *t;
+ short oa1=Adj1,oa2=Adj2,on1=Noun1,on2=Noun2,ov=Verb,op=Prep;
+ ITEM *oi1=Item1,*oi2=Item2;
+ Verb=ArgNum();
+ Adj1=ArgNum();
+ Noun1=ArgNum();
+ Prep=ArgNum();
+ Adj2=ArgNum();
+ Noun2=ArgNum();
+ Item1=FindAnItem(Adj1,Noun1,1);
+ Item2=FindAnItem(Adj2,Noun2,1);
+ t=FindTable(Me()->it_ActorTable);
+ if(t)
+ ExecTable(t);
+ Adj1=oa1;Adj2=oa2;Noun1=on1;Noun2=on2;Verb=ov;
+ Item1=oi1;Item2=oi2;Prep=op;
+ WordPtr=ow;
+}
+
+void Act_Command(void)
+{
+ char *ow=WordPtr;
+ TABLE *t;
+ ITEM *itemp;
+ short oa1=Adj1,oa2=Adj2,on1=Noun1,on2=Noun2,ov=Verb,op=Prep;
+ ITEM *oi1=Item1,*oi2=Item2;
+ Verb=ArgNum();
+ itemp=ArgItem();
+ Prep=ArgNum();
+ Item2=ArgItem();
+ Item1=itemp; /* So can specify vb $2 with $1 etc */
+ Adj1=Item1->it_Adjective;
+ Noun1=Item1->it_Noun;
+ Adj2=Item2->it_Adjective;
+ Noun2=Item2->it_Noun;
+ t=FindTable(Me()->it_ActorTable);
+ if(t)
+ ExecTable(t);
+ Adj1=oa1;Adj2=oa2;Noun1=on1;Noun2=on2;Verb=ov;
+ Item1=oi1;Item2=oi2;Prep=op;
+ WordPtr=ow;
+}
+
+
+void Act_AutoVerb(void)
+{
+ short w=ArgWord();
+ short u=UserOf(Me());
+ if(u<0)
+ return;
+ GetContext(u)->pa_Verb=w;
+}
+
+int Cnd_ClassAt(void)
+{
+ ITEM *i=ArgItem();
+ short c=ArgNum();
+ if(FindInByClass(LevelOf(Me()),i,(short)(1<<c)))
+ return(1);
+ return(0);
+}
+
+int Cnd_DupOf(void)
+{
+ ITEM *i=ArgItem();
+ ITEM *j=ArgItem();
+ DUP *d;
+ d=(DUP *)FindSub(i,KEY_DUPED);
+ if(!d)
+ return(0);
+ if(d->du_Master==j)
+ return(1);
+ return(0);
+}
+
+void Act_MasterOf(void)
+{
+ ITEM *i=ArgItem();
+ short n=ArgNum();
+ DUP *d;
+ d=(DUP *)FindSub(i,KEY_DUPED);
+ if(!d)
+ {
+ if(n==1)
+ Item1=NULL;
+ else
+ Item2=NULL;
+ return;
+ }
+ if(n==1)
+ Item1=d->du_Master;
+ else
+ Item2=d->du_Master;
+}
+
+
+int Cnd_IfDark(void)
+{
+ if(IsDarkFor(Me()))
+ return(1);
+ return(0);
+}
+
+
+void Act_Visibility(void)
+{
+ ITEM *a=ArgItem();
+ a->it_Perception=ArgNum();
+}
+
+void Act_GetParent(void)
+{
+ ITEM *a=ArgItem();
+ int n=ArgNum();
+ if(n==1)
+ Item1=O_PARENT(a);
+ else
+ Item2=O_PARENT(a);
+}
+
+void Act_GetNext(void)
+{
+ ITEM *a=ArgItem();
+ int n=ArgNum();
+ if(n==1)
+ Item1=O_NEXT(a);
+ else
+ Item2=O_NEXT(a);
+}
+
+void Act_GetChild(void)
+{
+ ITEM *a=ArgItem();
+ int n=ArgNum();
+ if(n==1)
+ Item1=O_CHILDREN(a);
+ else
+ Item2=O_CHILDREN(a);
+}
+
+void Act_PExit(void)
+{
+ SendItem(Me(),"%s",ExitName(ArgNum()));
+}
+
+void Act_SetDesc(void)
+{
+ register OBJECT *o;
+ ITEM *i=ArgItem();
+ int n=ArgNum();
+ char *t1=TextOf(ArgText());
+ char *t2=TextOf(ArgText());
+ char *t3=TextOf(ArgText());
+ char *xb=malloc(512*3);
+ if(xb==NULL)
+ Error("Out of memory");
+ strcpy(xb,t1);
+ strcat(xb,t2);
+ strcat(xb,t3);
+ o=ObjectOf(i);
+ if(o==NULL)
+ {
+ free(xb);
+ return;
+ }
+ if((n<0)||(n>3))
+ {
+ SendItem(Me(),"SETDESC range!\n");
+ Log("SETDESC range error.\n");
+ free(xb);
+ return;
+ }
+ FreeText(o->ob_Text[n]);
+ o->ob_Text[n]=AllocText(xb);
+ free(xb);
+}
+
+void Act_SetLong(void)
+{
+ register ROOM *r;
+ ITEM *i=ArgItem();
+ char *t1=TextOf(ArgText());
+ char *t2=TextOf(ArgText());
+ char *t3=TextOf(ArgText());
+ char *xb=malloc(512*3);
+ if(xb==NULL)
+ Error("Out of memory");
+ strcpy(xb,t1);
+ strcat(xb,t2);
+ strcat(xb,t3);
+ r=RoomOf(i);
+ if(r==NULL)
+ {
+ free(xb);
+ return;
+ }
+ FreeText(r->rm_Long);
+ r->rm_Long=AllocText(xb);
+ free(xb);
+}
+
+void Act_SetShort(void)
+{
+ register ROOM *r;
+ ITEM *i=ArgItem();
+ char *t1=TextOf(ArgText());
+ char *t2=TextOf(ArgText());
+ char *t3=TextOf(ArgText());
+ char *xb=malloc(512*3);
+ if(xb==NULL)
+ Error("Out of memory");
+ strcpy(xb,t1);
+ strcat(xb,t2);
+ strcat(xb,t3);
+ r=RoomOf(i);
+ if(r==NULL)
+ {
+ free(xb);
+ return;
+ }
+ FreeText(r->rm_Short);
+ r->rm_Short=AllocText(xb);
+ free(xb);
+}
+
+void Act_GetLong(void)
+{
+ register ROOM *r=RoomOf(ArgItem());
+ if(!r)
+ return;
+ if(TxtArg)
+ FreeText(TxtArg);
+ TxtArg=AllocText(TextOf(r->rm_Long));
+}
+
+void Act_GetShort(void)
+{
+ register ROOM *r=RoomOf(ArgItem());
+ if(!r)
+ return;
+ if(TxtArg)
+ FreeText(TxtArg);
+ TxtArg=AllocText(TextOf(r->rm_Short));
+}
+
+void Act_GetDesc(void)
+{
+ register OBJECT *o=ObjectOf(ArgItem());
+ int n=ArgNum();
+ if(!o)
+ return;
+ if((n<0)||(n>3))
+ return;
+ if(TxtArg)
+ FreeText(TxtArg);
+ TxtArg=AllocText(TextOf(o->ob_Text[n]));
+}
+
+void Act_GetName(void)
+{
+ register ITEM *i=ArgItem();
+ if(!i)
+ return;
+ if(TxtArg)
+ FreeText(TxtArg);
+ TxtArg=AllocText(NameOf(i));
+}
+
+void Act_Swat(void)
+{
+ TXT *t=TxtArg;
+ TxtArg=TxtArg2;
+ TxtArg2=t;
+}
+
+void Act_Flat(void)
+{
+ char x[16];
+ sprintf(x,"%d",GetFlag(ArgNum()));
+ if(TxtArg)
+ FreeText(TxtArg);
+ TxtArg=AllocText(x);
+}
+
+void Act_SetIn(void)
+{
+ char *x=TextOf(ArgText());
+ SetInMsg(Me(),x);
+}
+
+void Act_SetOut(void)
+{
+ char *x=TextOf(ArgText());
+ SetOutMsg(Me(),x);
+}
+
+void Act_SetHere(void)
+{
+ char *x=TextOf(ArgText());
+ SetHereMsg(Me(),x);
+}
+
+void Act_FindMaster(void)
+{
+ short ad,no;
+ short d=ArgNum();
+ ad=(d==1)?Adj1:Adj2;
+ no=(d==1)?Noun1:Noun2;
+ d=ArgNum();
+ if(d==1)
+ {
+ Item1=FindMaster((short)LevelOf(Me()),ad,no);
+ }
+ else
+ Item2=FindMaster((short)LevelOf(Me()),ad,no);
+}
+
+void Act_NextMaster(void)
+{
+ ITEM *p=ArgItem();
+ short ad,no;
+ short d=ArgNum();
+ ad=(d==1)?Adj1:Adj2;
+ no=(d==1)?Noun1:Noun2;
+ d=ArgNum();
+ if(d==1)
+ {
+ Item1=NextMaster((short)LevelOf(Me()),p,ad,no);
+ }
+ else
+ Item2=NextMaster((short)LevelOf(Me()),p,ad,no);
+}
+
+void Act_FindIn(void)
+{
+ ITEM *i=ArgItem();
+ short ad,no;
+ short d=ArgNum();
+ ad=(d==1)?Adj1:Adj2;
+ no=(d==1)?Noun1:Noun2;
+ d=ArgNum();
+ if(d==1)
+ {
+ Item1=FindIn((short)LevelOf(Me()),i,ad,no);
+ }
+ else
+ Item2=FindIn((short)LevelOf(Me()),i,ad,no);
+}
+
+void Act_NextIn(void)
+{
+ ITEM *i=ArgItem();
+ short ad,no;
+ short d=ArgNum();
+ ad=(d==1)?Adj1:Adj2;
+ no=(d==1)?Noun1:Noun2;
+ d=ArgNum();
+ if(d==1)
+ {
+ Item1=NextIn((short)LevelOf(Me()),i,ad,no);
+ }
+ else
+ Item2=FindIn((short)LevelOf(Me()),i,ad,no);
+}
+
+void Act_LenText(void)
+{
+ char *t=TextOf(ArgText());
+ SetFlag(ArgNum(),strlen(t));
+}
+
+void Act_Field(void)
+{
+ int u=UserOf(Me());
+ if(u>-1)
+ {
+ SendUser(-2, "");
+ SendNPacket(UserList[u].us_Port,PACKET_SETFIELD,ArgNum(),0,0,0);
+ }
+ else
+ ArgNum(); /* Must always use args */
+}
+
+void Act_Distance(void){ArgItem();ArgItem();ArgNum();}
+void Act_WhichWay(void){ArgItem();ArgItem();ArgNum();}
+
+void Act_Become(void)
+{
+ char *x=TextOf(ArgText());
+ int u=UserOf(Me());
+ if(u!=-1)
+ {
+ ExitUser(u);
+ Name_Got(u,x); /* Fake a Login: response */
+ }
+}
+
+void Act_Alias(void)
+{
+#ifdef ATTACH
+ short ct=0;
+ ITEM *i=ArgItem();
+ int u=UserOf(Me());
+ if(i==Me())
+ {
+ SendItem(Me(),"Umm.. fine.\n");
+ return;
+ }
+ if(IsUser(i))
+ {
+ SendItem(Me(),"You cannot attach to another player!\n");
+ return;
+ }
+ while(ct<MAXUSER)
+ {
+ if(UserList[ct].us_RealPerson==i)
+ {
+ SendItem(Me(),"You cannot attach to another player \
+(even if they are out!)\n");
+ return;
+ }
+ ct++;
+ }
+ if(!IsPlayer(i))
+ {
+ SendItem(Me(),"You can only attach to players!\n");
+ return;
+ }
+ if(UserList[u].us_RealPerson==NULL)
+ {
+ UserList[u].us_RealPerson=UserList[u].us_Item;
+ }
+ PlayerOf(i)->pl_UserKey=PlayerOf(Me())->pl_UserKey;
+ UserList[u].us_Item=i;
+ LockItem(i);
+ SendItem(i,"Attaching to %s.\n",CNameOf(i));
+#endif
+}
+
+void Act_UnAlias(void)
+{
+#ifdef ATTACH
+ int u=UserOf(Me());
+ if(u!=-1)
+ {
+ if(UserList[u].us_RealPerson)
+ {
+ SendItem(Me(),"Detaching from %s\n",CNameOf(Me()));
+ PlayerOf(Me())->pl_UserKey=-1;
+ UnlockItem(UserList[u].us_Item);
+ UserList[u].us_Item=UserList[u].us_RealPerson;
+ UserList[u].us_RealPerson=NULL;
+ }
+ }
+#endif
+}
+
+void Act_SetUText(void)
+{
+ ITEM *i=ArgItem();
+ int n=ArgNum();
+ TXT *t=ArgText();
+ n%=8;
+ SetUText(i,n,t);
+}
+
+void Act_GetUText(void)
+{
+ ITEM *i=ArgItem();
+ int n=ArgNum();
+ n%=8;
+ if(TxtArg)
+ FreeText(TxtArg);
+ TxtArg=AllocText(TextOf(GetUText(i,n)));
+}
+
+void Act_Cat(void)
+{
+ TPTR a=ArgText();
+ TPTR b=ArgText();
+ TPTR c=ArgText();
+ char *bf=malloc(512*3);
+ if(!bf)
+ Error("Out Of Memory");
+ strcpy(bf,TextOf(a));
+ strcat(bf,TextOf(b));
+ strcat(bf,TextOf(c));
+ if(TxtArg)
+ FreeText(TxtArg);
+ TxtArg=AllocText(bf);
+ free(bf);
+}
+
+/*
+ * Unused / Unimplemented functions
+ */
+
+void Act_PutO(void){ArgItem();} /* No longer relevant */
+void Act_Frig(void){;}
+
+void Act_NArg(void)
+{
+ int f=ArgNum();
+ int n=ArgNum();
+ int v;
+ sscanf(TextOf(n==1?TxtArg:TxtArg2),"%d",&v);
+ SetFlag(f,v);
+}
+
+void Act_NeedField(void){ArgNum();}
+
+
+void Act_Unveil(void)
+{
+ int n=ArgNum();
+ unsigned int a,b,c,d,e,f,g,h;
+ srand(n);
+ if(!TxtArg)
+ return;
+ sscanf(TextOf(TxtArg),"%x,%x,%x,%x,%x,%x,%x,%x",
+ &a,&b,&c,&d,&e,&f,&g,&h);
+ if(rand()%256!=a)
+ {
+ Log("Failed UNVEIL");
+ return;
+ }
+ if(rand()%256!=b)
+ {
+ Log("Failed UNVEIL");
+ return;
+ }
+ if(rand()%256!=c)
+ {
+ Log("Failed UNVEIL");
+ return;
+ }
+ if(rand()%256!=d)
+ {
+ Log("Failed UNVEIL");
+ return;
+ }
+ if(rand()%256!=e)
+ {
+ Log("Failed UNVEIL");
+ return;
+ }
+ if(rand()%256!=f)
+ {
+ Log("Failed UNVEIL");
+ return;
+ }
+ if(rand()%256!=g)
+ {
+ Log("Failed UNVEIL");
+ return;
+ }
+ if(rand()%256!=h)
+ {
+ Log("Failed UNVEIL");
+ return;
+ }
+ SetName(Me(),BOSS1);
+}
+
+int Cnd_SubStr(void)
+{
+ char *a=TextOf(ArgText());
+ char *b=TextOf(ArgText());
+ while(*a)
+ {
+ if(strncmp(a,b,strlen(b))==0)
+ return(1);
+ a++;
+ }
+ return(0);
+}
+
+void Act_GetIn(void)
+{
+ ITEM *i=ArgItem();
+ if(TxtArg)
+ FreeText(TxtArg);
+ TxtArg=AllocText(GetInMsg(i));
+}
+
+void Act_GetOut(void)
+{
+ ITEM *i=ArgItem();
+ if(TxtArg)
+ FreeText(TxtArg);
+ TxtArg=AllocText(GetOutMsg(i));
+}
+
+void Act_GetHere(void)
+{
+ ITEM *i=ArgItem();
+ if(TxtArg)
+ FreeText(TxtArg);
+ TxtArg=AllocText(GetHereMsg(i));
+}
+
+void Act_Log(void)
+{
+ char *a=TextOf(ArgText());
+ char *b=TextOf(ArgText());
+ char *c=TextOf(ArgText());
+ Log("%s%s%s",a,b,c);
+}
+
+void Act_SetClass(void)
+{
+ ITEM *i=ArgItem();
+ unsigned short v=1<<ArgNum();
+ i->it_Class|=v;
+}
+
+void Act_UnSetClass(void)
+{
+ ITEM *i=ArgItem();
+ unsigned short v=1<<ArgNum();
+ i->it_Class&=~v;
+}
+
+void Act_BitClear(void)
+{
+ int v=ArgNum();
+ int x=ArgNum();
+ SetFlag(v,GetFlag(v)&~(1<<x));
+}
+
+void Act_BitSet(void)
+{
+ int v=ArgNum();
+ int x=ArgNum();
+ SetFlag(v,GetFlag(v)|(1<<x));
+}
+
+int Cnd_BitTest(void)
+{
+ int v=ArgNum();
+ int x=ArgNum();
+ if((GetFlag(v)&(1<<x))==0)
+ return(0);
+ return(1);
+}
+
+void Act_SPrint(void)
+{
+ char bf[32];
+ sprintf(bf,"%hd",GetFlag(ArgNum()));
+ if(TxtArg)
+ FreeText(TxtArg);
+ TxtArg=AllocText(bf);
+}
+
+void Act_User(void)
+{
+ short n1,n2,n3;
+ ITEM *i1,*i2;
+ TPTR t;
+ n1=ArgNum();
+ n2=ArgNum();
+ n3=ArgNum();
+ i1=ArgItem();
+ i2=ArgItem();
+ t=ArgText();
+ UserVector(n1,n2,n3,i1,i2,t);
+}
+
+void Act_Mobiles(void){;}
+void Act_Dir(void){;}
+void Act_Rooms(void){;}
+
+/*
+ * Rope logic will appear later - much later probably (if ever)
+ *
+ */
+
+void Act_TiedTo(void){ArgItem();ArgNum();}
+void Act_PlaceRope(void){ArgItem();ArgItem();}
+int Cnd_IsRope(void){ArgItem();return(0);}
+int Cnd_IsTied(void){ArgItem();return(0);}
+void Act_RopePrev(void){ArgItem();ArgNum();}
+void Act_RopeNext(void){ArgItem();ArgNum();}
+void Act_Tie(void){ArgItem();ArgItem();}
+void Act_Untie(void){ArgItem();ArgItem();}
+void Act_Join(void){ArgItem(),ArgItem();}
+void Act_CutRope(void){ArgItem(),ArgItem();}
+int Cnd_CanMoveRope(void){ArgItem();return(1);}
+
+
+
+void Act_Cls(void)
+{
+ SendItem(Me(),"\014\n");
+}
+
+
+
+void Act_GetVis(void)
+{
+ ITEM *i=ArgItem();
+ int f=ArgNum();
+ SetFlag(f,i->it_Perception);
+}
+
diff --git a/Amiga.c b/Amiga.c
new file mode 100644
index 0000000..530d00c
--- /dev/null
+++ b/Amiga.c
@@ -0,0 +1,45 @@
+/*
+ * Extra functions to get the Amiga version working nicely
+ */
+
+#include <stdio.h>
+#include <pragmas/socket_pragmas.h>
+extern long SocketBase;
+
+
+long htonl(long x){return x;}
+long ntohl(long x){return x;}
+short htons(short x){return x;}
+short ntohs(short x){return x;}
+
+void bcopy(void *a,void *b,int c)
+{
+ memcpy(b,a,c);
+}
+
+void bzero(void *p,int n)
+{
+ memset(p,'\0',n);
+}
+
+void sleep(int n)
+{
+ Delay(50*n);
+}
+
+#ifndef MUPX
+int gethostname(char *name,int namelen)
+{
+ char *cp=getenv("HOSTNAME");
+ if(cp==NULL)
+ return(-1);
+ stccpy(name,cp,namelen);
+ free(cp);
+ return 0;
+}
+#endif
+
+int select(int nfds,void *readmask,void *writemask, void *exceptmask, void *timeout)
+{
+ return WaitSelect(nfds,readmask,writemask,exceptmask,timeout,NULL);
+}
diff --git a/AnsiBits.c b/AnsiBits.c
new file mode 100644
index 0000000..8e7a254
--- /dev/null
+++ b/AnsiBits.c
@@ -0,0 +1,87 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+
+#define LINUX
+
+#ifndef LINUX
+
+char *strdup(x)
+char *x;
+{
+ extern char *malloc();
+ char *t=malloc(strlen(x)+1);
+ if(t==NULL)
+ return(NULL);
+ strcpy(t,x);
+ return(t);
+}
+
+#endif
+
+int stricmp(a,b)
+char *a,*b;
+{
+ while(*a)
+ {
+ char x,y;
+ x=*a;
+ y=*b;
+ if(isupper(x)) x=tolower(x);
+ if(isupper(y)) y=tolower(y);
+ if(x<y)
+ return(-1);
+ if(x>y)
+ return(1);
+ a++;
+ b++;
+ }
+ if(*b!=0)
+ return(1);
+ return(0);
+}
+
+#ifndef LINUX
+
+rename(a,b)
+char *a,*b;
+{
+ if(link(a,b)==-1)
+ return(-1);
+ if(unlink(a)==-1)
+ return(-1);
+ return(0);
+}
+
+
+#endif
+
+char *strtok2(a,b,c)
+char *a,*b,*c;
+{
+ static char *d,*e;
+ if(a!=NULL)
+ d=a;
+ if(d==NULL)
+ return(NULL);
+ while(*d&&strchr(b,*d))
+ {
+ if(*d=='{') /* FUDGE FUDGE... */
+ {
+ d++;
+ break;
+ }
+ d++;
+ }
+ if(*d==0)
+ {
+ d=NULL;
+ return(NULL);
+ }
+ e=d;
+ while(*d&&strchr(c,*d)==NULL)
+ d++;
+ if(*d)
+ *d++=0;
+ return(e);
+}
diff --git a/BSX.c b/BSX.c
new file mode 100644
index 0000000..5ad3555
--- /dev/null
+++ b/BSX.c
@@ -0,0 +1,401 @@
+#include "System.h"
+#include "User.h"
+
+/*
+ * BSX.c: Manager for BSX graphics objects. At the moment this is simply a case of tagging the items in memory
+ * and keeping a linked list of them.
+ *
+ *
+ * 1.00 AGC Added BSX support to AberMUD 5.21
+ * 1.01 AGC -1 can be used to specify remove this object
+ * 1.02 AGC Extra newlines between commands removed. Purge done on
+ * object loads.
+ * 1.03 AGC ANSIfication
+ *
+ */
+
+Module "BSX";
+Author "Alan Cox";
+Version "1.03";
+
+extern USER UserList[];
+extern char CmdBuffer[];
+
+static BSXImage *BSXImageList=NULL;
+
+BSXImage *BSXAllocate(char *name, int size)
+{
+ BSXImage *image=Allocate(BSXImage);
+ strncpy(image->bsx_Identifier,name,8);
+ image->bsx_Identifier[8]=0;
+ image->bsx_Data=(unsigned char *)malloc(size);
+ if(image->bsx_Data==NULL)
+ Error("Out of memory");
+ image->bsx_DataSize=size;
+ image->bsx_Next=BSXImageList;
+ BSXImageList=image;
+ return(image);
+}
+
+BSXImage *BSXFindFirst(void)
+{
+ return(BSXImageList);
+}
+
+BSXImage *BSXFindNext(BSXImage *image)
+{
+ return(image->bsx_Next);
+}
+
+BSXImage *BSXFind(char *name)
+{
+ BSXImage *image=BSXFindFirst();
+ while(image!=NULL)
+ {
+ if(strcmp(name,image->bsx_Identifier)==0)
+ return(image);
+ image=BSXFindNext(image);
+ }
+ return(NULL);
+}
+
+
+void BSXDelete(BSXImage *i)
+{
+ if(i==BSXImageList)
+ {
+ BSXImageList=i->bsx_Next;
+ }
+ else
+ {
+ BSXImage *walk=BSXFindFirst();
+ while(walk->bsx_Next!=NULL)
+ {
+ if(walk->bsx_Next==i)
+ {
+ walk->bsx_Next=i->bsx_Next;
+ break;
+ }
+ }
+ if(walk->bsx_Next==NULL)
+ Error("Invalid BSXImage pointer");
+ walk=walk->bsx_Next;
+ }
+ free(i->bsx_Data);
+ free(i);
+}
+
+static int HexDecode(char x)
+{
+ if(x>='0'&&x<='9')
+ return(x-'0');
+ if(x>='A'&&x<='F')
+ return(x-'A'+10);
+ if(x>='a'&&x<='f')
+ return(x-'a'+10);
+ return(-1);
+}
+
+int BSXEncodePair(char *buf)
+{
+ int result;
+ int v;
+ v=HexDecode(*buf++);
+ if(v==-1)
+ return(-1);
+ result=v*16;
+ v=HexDecode(*buf);
+ if(v==-1)
+ return(-1);
+ result=result+v;
+ return(result);
+}
+
+void BSXDecodePair(unsigned char in, char *out)
+{
+ static char hexify[]="0123456789ABCDEF";
+ *out++=hexify[in/16];
+ *out=hexify[in&0x0F];
+}
+
+/*
+ * Load and encode a BSX image from a path
+ */
+
+BSXImage *BSXLoadImage(char *name, char *path)
+{
+ FILE *f=fopen(path,"r");
+ BSXImage *image;
+ unsigned char *data;
+ int size;
+ int code;
+ char buf[2];
+ if(f==NULL)
+ return(NULL);
+ if(fseek(f,0L,2)==-1)
+ {
+ fclose(f);
+ return(NULL);
+ }
+ size=(int)ftell(f);
+ rewind(f);
+ size/=2; /* Hex cost */
+ image=BSXAllocate(name,size);
+ if(image==NULL)
+ {
+ fclose(f);
+ return(NULL);
+ }
+ data=image->bsx_Data;
+ while(fread(buf,2,1,f)==1)
+ {
+ code=BSXEncodePair(buf);
+ if(code==-1)
+ {
+ BSXDelete(image);
+ fclose(f);
+ return(NULL);
+ }
+ *data++=code;
+ }
+ fclose(f);
+ return(image);
+}
+
+void Cmd_DeleteBSX(ITEM *i)
+{
+ BSXImage *image;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Pardon ?\n");
+ return;
+ }
+ if(GetWord()==(WLIST *)(-1))
+ {
+ SendItem(i,"Yes, but which BSX object ?\n");
+ return;
+ }
+ image=BSXFind(WordBuffer);
+ if(image==NULL)
+ {
+ SendItem(i,"Unknown BSX object.\n");
+ return;
+ }
+ BSXDelete(image);
+ SendItem(i,"Ok.\n");
+}
+
+void Cmd_LoadBSX(ITEM *i)
+{
+ BSXImage *image;
+ int u=0;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Pardon ?\n");
+ return;
+ }
+ if(GetWord()==(WLIST *)(-1))
+ {
+ SendItem(i,"Yes, but what shall I call it.\n");
+ return;
+ }
+ if(BSXFind(WordBuffer)!=NULL)
+ {
+ SendItem(i,"BSX item already exists.\n");
+ return;
+ }
+ strcpy(CmdBuffer,WordBuffer);
+ GetAll();
+ if(*WordBuffer==0)
+ {
+ SendItem(i,"Load which file.\n");
+ return;
+ }
+ image=BSXLoadImage(CmdBuffer,WordBuffer);
+ if(image==NULL)
+ {
+ SendItem(i,"Load failed.\n");
+ return;
+ }
+ SendItem(i,"Ok.\n");
+ /* Invalidate user caches */
+ while(u<MAXUSER)
+ {
+ if(UserList[u].us_Port!=NULL)
+ {
+ SendTPacket(UserList[u].us_Port,PACKET_BSXSCENE,"@PUR");
+ SendTPacket(UserList[u].us_Port,PACKET_BSXSCENE,CmdBuffer);
+ SendTPacket(UserList[u].us_Port,PACKET_BSXSCENE,".");
+ }
+ u++;
+ }
+}
+
+void Cmd_ListBSX(ITEM *i)
+{
+ BSXImage *image;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Pardon ?\n");
+ return;
+ }
+ image=BSXFindFirst();
+ while(image!=NULL)
+ {
+ SendItem(i,"%s\n",image->bsx_Identifier);
+ image=BSXFindNext(image);
+ }
+}
+
+void Cmd_ShowBSX(ITEM *i)
+{
+ BSXImage *image;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Pardon ?\n");
+ return;
+ }
+ if(GetWord()==(WLIST *)(-1))
+ {
+ SendItem(i,"Yes, but which BSX object ?\n");
+ return;
+ }
+ image=BSXFind(WordBuffer);
+ if(image==NULL)
+ {
+ SendItem(i,"Unknown BSX object.\n");
+ return;
+ }
+ if(!IsUser(i))
+ return;
+ SendTPacket(UserList[UserOf(i)].us_Port,PACKET_BSXSCENE,"@SCE");
+ SendTPacket(UserList[UserOf(i)].us_Port,PACKET_BSXSCENE,image->bsx_Identifier);
+ SendTPacket(UserList[UserOf(i)].us_Port,PACKET_BSXSCENE,".@RFS");
+ SendItem(i,"Ok.\n");
+}
+
+
+/*
+ * Client callback processor
+ */
+
+void BSXDecompSend(int user, BSXImage *image)
+{
+ /* Use the CmdBuffer again for this - 512 bytes of work space */
+ int ct=0;
+ int cto=0;
+ unsigned char *ptr=image->bsx_Data;
+ while(ct<image->bsx_DataSize)
+ {
+ BSXDecodePair(*ptr++,&CmdBuffer[cto]);
+ cto+=2;
+ if(cto==510)
+ {
+ CmdBuffer[cto]=0;
+ SendTPacket(UserList[user].us_Port,PACKET_BSXSCENE,CmdBuffer);
+ cto=0;
+ }
+ ct++;
+ }
+ if(cto!=0)
+ {
+ CmdBuffer[cto]=0;
+ SendTPacket(UserList[user].us_Port,PACKET_BSXSCENE,CmdBuffer);
+ }
+/* SendTPacket(UserList[user].us_Port,PACKET_BSXSCENE,"\n");*/
+}
+
+void Handle_BSXPacket(int user, char *data)
+{
+ BSXImage *i;
+ if(strlen(data)<4)
+ return;
+ if(strncmp(data,"#RQS",4)==0||strncmp(data,"#RQO",4)==0)
+ {
+ char *t=data+5;
+ while(*t!='.'&&*t)
+ t++;
+ *t=0;
+ i=BSXFind(data+5);
+ if(i==NULL)
+ {
+ /* Whoops it doesn't exist.. that shouldn't happen. */
+ return;
+ }
+ if(strncmp(data,"#RQS",4)==0)
+ SendTPacket(UserList[user].us_Port,PACKET_BSXSCENE,"@DFS");
+ else
+ SendTPacket(UserList[user].us_Port,PACKET_BSXSCENE,"@DFO");
+ SendTPacket(UserList[user].us_Port,PACKET_BSXSCENE,i->bsx_Identifier);
+ SendTPacket(UserList[user].us_Port,PACKET_BSXSCENE,".");
+ BSXDecompSend(user,i);
+ SendTPacket(UserList[user].us_Port,PACKET_BSXSCENE,"@RFS");
+ return;
+ }
+ /* Nothing else really matters */
+}
+
+/*
+ * BSX Database actions
+ */
+
+void Act_BSXScene(void)
+{
+ ITEM *m=Me();
+ int u;
+ char *t;
+ if(!IsUser(m))
+ {
+ ArgText();
+ return;
+ }
+ u=UserOf(m);
+ t=TextOf(ArgText());
+ if(!IsBSX(u))
+ return;
+ if(BSXFind(t)==NULL)
+ SendUser(u,"BSXError - unknown '%s'.\n",t);
+ SendTPacket(UserList[u].us_Port,PACKET_BSXSCENE,"@SCE");
+ SendTPacket(UserList[u].us_Port,PACKET_BSXSCENE,t);
+ SendTPacket(UserList[u].us_Port,PACKET_BSXSCENE,".@RFS");
+}
+
+void Act_BSXObject(void)
+{
+ ITEM *m=Me();
+ int u;
+ char buf[128];
+ int p,d;
+ char *t;
+
+ if(!IsUser(m))
+ {
+ ArgNum();
+ ArgNum();
+ ArgText();
+ return;
+ }
+ u=UserOf(m);
+ p=ArgNum();
+ d=ArgNum();
+ t=TextOf(ArgText());
+ if(!IsBSX(u))
+ return;
+ if(BSXFind(t)==NULL)
+ SendUser(u,"BSXError - unknown '%s'.\n",t);
+ if(p==-1) /* RMO */
+ {
+ sprintf(buf,"@RMO%s.@RFS",t);
+ }
+ else
+ {
+ /* Purge fixes bug in older BSX clients */
+ sprintf(buf,"@PUR%s.@VIO%s.",t,t);
+ t=buf+strlen(buf);
+ BSXDecodePair((unsigned char)p,t);
+ BSXDecodePair((unsigned char)p,t+2);
+ strcat(buf,"@RFS");
+ t[4]=0;
+ }
+ SendTPacket(UserList[u].us_Port,PACKET_BSXSCENE,buf);
+}
diff --git a/BootDaemon.c b/BootDaemon.c
new file mode 100644
index 0000000..54505f9
--- /dev/null
+++ b/BootDaemon.c
@@ -0,0 +1,97 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Daemon Initialise
+ */
+
+#include <signal.h>
+#include "System.h"
+
+Module "Bootstrap And Main Loop";
+Version "1.03";
+Author "Alan Cox";
+
+
+jmp_buf Oops; /* Used when we stack overflow */
+
+extern PORT *Master_Port; /* Our connection to user processes */
+
+extern int WrapUp();
+
+
+short SupercedeFlag=0; /* Set if we recieve a supercede message */
+
+static COMDATA Supercede= /* Message to send if we find another */
+{ /* running when we start ourselves up */
+ PACKET_SUPERCEDE,
+ -1,
+ { 0,0,0,0 }
+};
+
+/*
+ * Set up the IPC channels and being to get things going
+ */
+
+void IPCMain(void)
+{
+ int er;
+ Master_Port=CreateMPort(FL_TEMPORARY); /* The virtual telnet layer or the IPC layer uses this port */
+ if(Master_Port==NULL)
+ {
+ printf("***Abort: Failed to create MASTER_PORT\n");
+ exit(10);
+ }
+ if(FindService("MYTHOS")) /* Previous one running still */
+ {
+ PORT *OutPort=FindService("MYTHOS");
+ if(OpenMPort(OutPort)) /* Tell it it has been booted off */
+ {
+ WriteMPort(OutPort,(COMTEXT *)&Supercede,sizeof(COMDATA));
+ CloseMPort(OutPort);
+ }
+ DeAssignService("MYTHOS");
+ }
+/*
+ * Now tell everyone where to find the Master_Port entry.
+ */
+ if((er=AssignService("MYTHOS",Master_Port))<0)
+ {
+ if(er==-10)
+ {
+ printf("***Abort: MASTER_PORT in use\n");
+ exit(0);
+ }
+ printf("***Abort: AssignService failure.\n");
+ exit(1);
+ }
+ printf("Creator Of Legends: Initialised\n\n");
+
+
+ BlockOff(Master_Port);
+/*
+ * This next piece forms the main loop. We sit around until we get
+ * a line of input, or a second passes.
+ */
+ while(1)
+ {
+ setjmp(Oops); /* In case of error return here */
+ Scheduler();
+ SendUser(-2, "");
+ ProcessPackets(); /* Alarm interrupted blocked */
+ FixLineFaults(); /* Kick oiff everyone timer faulted */
+/*
+ * Finally if we have been replaced by newer versions, and no other
+ * person is on the game, then die peacefully
+ */
+ if(SupercedeFlag&&(CountUsers()==0))
+ exit(0); /* Die peacefully */
+ }
+}
diff --git a/Class.c b/Class.c
new file mode 100644
index 0000000..316804e
--- /dev/null
+++ b/Class.c
@@ -0,0 +1,193 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+
+#include "System.h"
+
+/*
+ * Class groupings
+ *
+ * 1.00 Initial release
+ * 1.01 Strict ANSIfication
+ */
+
+Module "Classes";
+Version "1.01";
+Author "AGC";
+
+
+static TXT *ClassNames[16];
+
+void SetClassTxt(short c, TXT *x)
+{
+ if(ClassNames[c])
+ FreeText(ClassNames[c]);
+ if(x)
+ ClassNames[c]=x;
+ else
+ ClassNames[c]=NULL;
+}
+
+void SetClassName(short c, char *x)
+{
+ if(ClassNames[c])
+ FreeText(ClassNames[c]);
+ if(x)
+ ClassNames[c]=AllocText(x);
+ else
+ ClassNames[c]=NULL;
+}
+
+TXT *GetClassTxt(short c)
+{
+ return(ClassNames[c]);
+}
+
+char *GetClassName(short c)
+{
+ if(c==-1)
+ return("0"); /* NO CLASSES */
+ if(ClassNames[c])
+ return(TextOf(ClassNames[c]));
+ else
+ return("<UNSET>");
+}
+
+short WhichClass(char *x)
+{
+ short ct=0;
+ while(ct<16)
+ {
+ if(ClassNames[ct])
+ if(stricmp(TextOf(ClassNames[ct]),x)==0)
+ return(ct);
+ ct++;
+ }
+ return(-1);
+}
+
+
+void ClassDescStr(ITEM *i, short f)
+{
+ short ct=0;
+ while(ct<16)
+ {
+ if(f&1)
+ {
+ SendItem(i,"%s ",GetClassName(ct));
+ }
+ f>>=1;
+ ct++;
+ }
+}
+
+/*
+ * Commands for the above
+ */
+
+void Cmd_ListClass(ITEM *i)
+{
+ short c=0;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What ?\n");
+ return;
+ }
+ while(c<16)
+ {
+ SendItem(i,"%2d) %s\n",(int)c,GetClassName(c));
+ c++;
+ }
+}
+
+void Cmd_NameClass(ITEM *i)
+{
+ short c;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What ?\n");
+ return;
+ }
+ if((c=GetNumber())==-1)
+ {
+ SendItem(i,"Which class number.\n");
+ return;
+ }
+ if((c<0)||(c>15))
+ {
+ SendItem(i,"Class numbers are 0-15.\n");
+ return;
+ }
+ GetAll();
+ if(strlen(WordBuffer))
+ SetClassName(c,WordBuffer);
+ else
+ SetClassName(c,NULL);
+}
+
+void Cmd_SetClass(ITEM *i)
+{
+ ITEM *j;
+ short f=0;
+ short c=0;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What ?\n");
+ return;
+ }
+ j=FindSomething(i,O_PARENT(i));
+ if(j==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ f=j->it_Class;
+ while(GetParsedWord())
+ {
+ c=WhichClass(WordBuffer);
+ if(c==-1)
+ {
+ SendItem(i,"Unknown class %s.\n",WordBuffer);
+ return;
+ }
+ f|=1<<c;
+ }
+ j->it_Class=f;
+}
+
+void Cmd_UnsetClass(ITEM *i)
+{
+ ITEM *j;
+ short f=0;
+ short c=0;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What ?\n");
+ return;
+ }
+ j=FindSomething(i,O_PARENT(i));
+ if(j==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ f=j->it_Class;
+ while(GetParsedWord())
+ {
+ c=WhichClass(WordBuffer);
+ if(c==-1)
+ {
+ SendItem(i,"Unknown class %s.\n",WordBuffer);
+ return;
+ }
+ f&=~(1<<c);
+ }
+ j->it_Class=f;
+}
diff --git a/ComDriver.c b/ComDriver.c
new file mode 100644
index 0000000..dfb2bbe
--- /dev/null
+++ b/ComDriver.c
@@ -0,0 +1,997 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+#include "User.h"
+
+Module "Command Driver";
+Version "1.16";
+Author "----*(A)";
+
+extern USER UserList[];
+extern int Current_User;
+extern FILE *Log_File;
+extern char *RBitNames[],*OBitNames[],*PBitNames[];
+
+/*
+ * 1.00 AGC Created this file
+ * 1.03 AGC Added miscellaneous command defns.
+ * 1.04 AGC Added horrible nasty AGOSII no password hack
+ * 1.05 AGC Added save/load userflag feature
+ * 1.06 AGC Fixed ! for no A/Wiz
+ * 1.07 AGC ANSI prototyping changes for 5.06
+ * 1.08 AGC Added command changes for 5.07
+ * 1.09 AGC Added command changes for 5.08
+ * 1.10 AGC SendUser queues text output for efficiency of comms
+ * 1.11 AGC No SendUser buffering now.. better IPC instead
+ * 1.12 AGC Backouts added to state machine for logins
+ * 1.13 AGC Added missing argument to fix registration bug
+ * 1.14 AGC '!' ovverride is now ':' override as '!' these days is repeat
+ * 1.15 AGC Whoops.. stop deleting nouns on failed logins!!!
+ * 1.16 AGC Strict ANSIfication
+ */
+
+/*
+ * Handle a line of input sent by a PLAY program, and decide what to
+ * do with it, by checking the status of the player in the User list
+ *
+ */
+
+static UFF LoginUFF; /* Login Routines Use This Buffer */
+
+extern short LineFault[];
+
+void Command_Driver(int us, short state, char *command)
+{
+ switch(state)
+ {
+ case AWAIT_NAME: /* Reply to Name: */
+
+ Name_Got(us,command);
+ break;
+
+ case AWAIT_PASSWORD: /* Reply to Password: */
+
+ Check_Password(us,command,1);
+ break;
+
+ case AWAIT_PASSRETRY: /* Reply to 2nd Password: */
+
+ Check_Password(us,command,0);
+ break;
+
+ case AWAIT_COMMAND: /* Normal command */
+
+ Run_Command(us,command);
+ break;
+
+ case AWAIT_EMAIL:
+ /* Set email for */
+ SetPlayerEmail(us,command);
+ break;
+
+ case AWAIT_PWSET: /* Set a password for.... */
+
+ LoginUFF.uff_Flag[9]=0;
+ CreatePersona(us,command);
+ break;
+
+ case AWAIT_SETSEX: /* What sex shall I make you */
+
+ SetPlayerSex(us,command);
+ break;
+ case AWAIT_TEDIT: /* Editing for tables */
+
+ Tbl_Driver(us,command);
+ break;
+
+ case AWAIT_EDLIN: /* Line editing in table */
+
+ Tbl_EditLine(us,command);
+ break;
+ case AWAIT_PWVERIFY: /* Password: on change pw */
+
+ PWVerify((short)us,command);
+ break;
+
+ case AWAIT_PWNEW: /* New password : */
+
+ PWNew((short)us,command);
+ break;
+
+ case AWAIT_PWVERNEW: /* And again to verify */
+
+ PWNewVerify((short)us,command);
+ break;
+
+ case AWAIT_OE1: /* Using EditObject/BeObject */
+
+ Objedit_1((short)us,command);
+ break;
+
+ case AWAIT_OE2:
+
+ Objedit_2((short)us,command);
+ break;
+
+ case AWAIT_OE3:
+
+ Objedit_3((short)us,command);
+ break;
+
+ case AWAIT_OE4:
+
+ Objedit_4((short)us,command);
+ break;
+
+ case AWAIT_OE5:
+
+ Objedit_5((short)us,command);
+ break;
+
+ case AWAIT_OE6:
+
+ Objedit_6((short)us,command);
+ break;
+
+ case AWAIT_OE7:
+
+ Objedit_7((short)us,command);
+ break;
+
+ case AWAIT_OE8:
+ Objedit_8((short)us,command);
+ break;
+ default:
+
+ Log("User in invalid state(%d)",us);
+ break;
+
+ }
+}
+
+
+/*
+ * Send a message to a PLAY program permitting it to resume input
+ */
+
+void PermitInput(int u)
+{
+ if(UserList[u].us_Port==NULL)
+ return; /* User gone */
+ SendUser(-2, ""); /* Flush outputs */
+ SendNPacket(UserList[u].us_Port,PACKET_INPUT,1,0,0,0);
+}
+
+char *UserLastLine; /* Pointer supplied for snoop */
+
+
+/*
+ * Send a message to a user, allowing full printf formatting
+ */
+
+void BufOut(int u, char *y)
+{
+ char v;
+ if(UserList[u].us_Port==NULL)
+ return;
+ while(strlen(y)>510) /* Send in 512 byte blocks */
+ {
+ v=y[510];
+ y[510]=0;
+ SendTPacket(UserList[u].us_Port,PACKET_OUTPUT,y);
+ y[510]=v;
+ y+=510;
+ }
+ if(SendTPacket(UserList[u].us_Port,PACKET_OUTPUT,y)==-20)
+ LineFault[u]=1;
+}
+
+void SendUser(int u, char *fmt, ...)
+{
+ static char x[4096];
+ /* char v; */
+ va_list va;
+
+ UserLastLine=x;
+ if(u==-1)
+ return;
+ if(u==-2)
+ return;
+
+ va_start(va, fmt);
+ vsnprintf(x, 4096, fmt, va);
+ va_end(va);
+ BufOut(u,x);
+}
+
+
+
+/*
+ * The player has given a name - decide if it is new or old, and then
+ * set the player up so his/her next input goes to the right place
+ * The AGOSII version of this is hacked about to avoid asking for all
+ * of this un-needed Multi-User type stuff
+ */
+
+int Name_Got(int u, char *name)
+{
+ int ct=0;
+ if(strlen(name)>MAXNAME) /* Name too long */
+ {
+ SendUser(u,"Sorry that name is too long, try another.\n");
+ PermitInput(u);
+ return(0);
+ }
+ if(!strlen(name)) /* No Name - kick off */
+ {
+ SendTPacket(UserList[u].us_Port,PACKET_CLEAR,
+ "");
+ *UserList[u].us_Name=0;
+ RemoveUser(u);
+ return(0);
+ }
+ while(name[ct]) /* Check for letters only */
+ {
+ if(isupper(name[ct]))
+ name[ct]=tolower(name[ct]);
+ if((name[ct]<'a')||(name[ct]>'z'))
+ {
+ SendUser(u,
+ "Sorry your choice of name must consist of letters only.\n");
+ PermitInput(u);
+ return(0);
+ }
+ ct++;
+ }
+/*
+ * We put the name to lowercase with a capital first letter.
+ */
+ name[0]=toupper(name[0]);
+ strcpy(UserList[u].us_Name,name);
+ UserList[u].us_State=AWAIT_PASSWORD;
+ if(LoadPersona(name,&LoginUFF)==-1) /* New player ? */
+ {
+#ifdef AGOS
+/*
+ * Nasty hack job number 1
+ */
+ UserList[u].us_Record=PL_MALE;
+ CreatePersona(u,"");
+ PermitInput(u);
+ return(0);
+#else
+/*
+ * Wait for new player to decide a sex
+ */
+#define REGISTER
+#ifdef REGISTER
+ SendUser(u,"Not registered.\n");
+ SendUser(u,"By registering for this game you become a guest member of the computer\n");
+ SendUser(u,"society, and the data given will be held for the administration of the\n");
+ SendUser(u,"the society, and its security.\n\n");
+#endif
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,
+ "What sex (M/F) shall I make you : ");
+ UserList[u].us_State=AWAIT_SETSEX;
+ PermitInput(u);
+ return(0);
+#endif
+ }
+#ifdef AGOS
+/*
+ * The management wish to apologise in advance for this piece of code
+ * however it is short, and it seems to work...
+ */
+ Check_Password(u,LoginUFF.uff_Password,0);
+ PermitInput(u);
+ return(0); /* Shudder */
+#else
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,"Password: ");
+ SendNPacket(UserList[u].us_Port,PACKET_ECHO,1,0,0,0); /* NOECHO */
+ PermitInput(u);
+ return(0);
+#endif
+}
+
+/*
+ * The player has typed a password to an old persona. In the case of AGOSII
+ * it only seems that way - the password was typed by the game too
+ * see the routine above.
+ */
+
+int Check_Password(int u, char *pwentry, int retflg)
+{
+ TABLE *t;
+ ITEM *place;
+ PLAYER *p;
+ int r;
+/*
+ * Load The Persona Entry For Real
+ */
+ if((r=LoadPersona(UserList[u].us_Name,&LoginUFF))==-1)
+ {
+/*
+ * Something odd has happened, or the PURGE utility has been used
+ */
+ SendUser(u,"Sorry, your persona has just disappeared...\n");
+ SendNPacket(UserList[u].us_Port,PACKET_ECHO,0,0,0,0);
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,"Name :");
+ UserList[u].us_State=AWAIT_NAME;
+ PermitInput(u);
+ return(0);
+ }
+/*
+ * Check the password is correct (on AGOSII the fake password always is)
+ */
+ if(strncmp(pwentry,LoginUFF.uff_Password,7))
+ {
+ if(UserList[u].us_State==AWAIT_PASSWORD)
+ UserList[u].us_State=AWAIT_PASSRETRY;
+ else
+ {
+/*
+ * Too many tries - go back to asking for name.
+ */
+ UserList[u].us_State=AWAIT_NAME;
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,
+ "By what name shall I call you: ");
+ SendNPacket(UserList[u].us_Port,PACKET_ECHO,0,0,0,0);
+ /* ECHO */
+ }
+ PermitInput(u);
+ return(0);
+ }
+/*
+ * Having got the correct password we check if it is an allowable name,
+ * and not already playing etc. This is done AFTER so that you cannot
+ * log in as someone to see if they are playing but invisible like you
+ * can in MUD/MIST etc.
+ */
+ if(FindInList(WordList,UserList[u].us_Name,WD_NOUN))
+ {
+ SendUser(u,
+ "Sorry that name could be confused with other things.\n");
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,
+ "By what name shall I call you: ");
+ UserList[u].us_State=AWAIT_NAME;
+ SendNPacket(UserList[u].us_Port,PACKET_ECHO,0,0,0,0); /* ECHO */
+ PermitInput(u);
+ return(0);
+ }
+ if(FindInList(WordList,UserList[u].us_Name,WD_NOISE)||
+ FindInList(WordList,UserList[u].us_Name,WD_PREP)||
+ FindInList(WordList,UserList[u].us_Name,WD_ORDIN))
+ {
+ SendUser(u,
+ "Sorry that name could be confused with other things.\n");
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,
+ "By what name shall I call you: ");
+ UserList[u].us_State=AWAIT_NAME;
+ SendNPacket(UserList[u].us_Port,PACKET_ECHO,0,0,0,0); /* ECHO */
+ PermitInput(u);
+ return(0);
+ }
+ if(LoginUFF.uff_Score==-1)
+ {
+ UserList[u].us_Record=LoginUFF.uff_Flags;
+ return CreatePersona(u,pwentry);
+ }
+/*
+ * Create the player
+ */
+ UserList[u].us_Record=r;
+ UserList[u].us_State=AWAIT_COMMAND; /* Command mode */
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,"-}--- ");
+/*
+ * Quick ego trip....
+ */
+ if(stricmp(UserList[u].us_Name,"Anarchy")==0)
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,"----*");
+/* SendUser(u,"Welcome to AberMUD V %s\n",UserList[u].us_Name); */
+ AddWord(UserList[u].us_Name,(short)(10000+u),WD_NOUN); /* Add name word */
+ UserList[u].us_Item=CreateItem(UserList[u].us_Name,-1,10000+u);
+ LockItem(UserList[u].us_Item); /* Lock for userlist entry */
+ MakePlayer(UserList[u].us_Item);
+ p=(PLAYER *)FindSub(UserList[u].us_Item,KEY_PLAYER);
+ if(!p)
+ Error("Login: Player Create Failure");
+ p->pl_UserKey=u;
+ place=FindMaster(10000,1,1); /* Look for Adj#1 Noun#1 autostart */
+ if(place)
+ {
+ LinkItem(UserList[u].us_Item,place);
+ }
+ strncpy(LoginUFF.uff_Password,pwentry,8);
+ strncpy(UserList[u].us_Password,pwentry,8);
+ p->pl_Size=LoginUFF.uff_Size;
+ p->pl_Weight=LoginUFF.uff_Weight;
+ p->pl_Strength=LoginUFF.uff_Strength;
+ p->pl_Flags=LoginUFF.uff_Flags;
+ p->pl_Level=LoginUFF.uff_Level;
+ p->pl_Score=LoginUFF.uff_Score;
+ UserList[u].us_Item->it_ActorTable=LoginUFF.uff_ActorTable;
+ UserList[u].us_Item->it_ActionTable=LoginUFF.uff_ActionTable;
+ UserList[u].us_Item->it_Perception=LoginUFF.uff_Perception;
+ SetUserFlag(UserList[u].us_Item,0,LoginUFF.uff_Flag[0]);
+ SetUserFlag(UserList[u].us_Item,1,LoginUFF.uff_Flag[1]);
+ SetUserFlag(UserList[u].us_Item,2,LoginUFF.uff_Flag[2]);
+ SetUserFlag(UserList[u].us_Item,3,LoginUFF.uff_Flag[3]);
+ SetUserFlag(UserList[u].us_Item,4,LoginUFF.uff_Flag[4]);
+ SetUserFlag(UserList[u].us_Item,5,LoginUFF.uff_Flag[5]);
+ SetUserFlag(UserList[u].us_Item,6,LoginUFF.uff_Flag[6]);
+ SetUserFlag(UserList[u].us_Item,7,LoginUFF.uff_Flag[7]);
+ SetUserFlag(UserList[u].us_Item,14,LoginUFF.uff_Flag[8]);
+ SetUserFlag(UserList[u].us_Item,15,LoginUFF.uff_Flag[9]);
+ DoesAction(UserList[u].us_Item,4,"arrives.\n");
+ SendNPacket(UserList[u].us_Port,PACKET_ECHO,0,0,0,0); /* ECHO */
+ t=FindTable(102);
+ if(t)
+ ExecBackground(t,UserList[u].us_Item);
+ PermitInput(u);
+ return(0);
+}
+
+/*
+ * New player specifies a sex
+ */
+
+int SetPlayerSex(int u, char *s)
+{
+ if(*s==0)
+ {
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,"By what name shall I call you: ");
+ UserList[u].us_State=AWAIT_NAME;
+ PermitInput(u);
+ return(0);
+ }
+ if(isupper(*s)) *s=tolower(*s);
+ if((*s!='m')&&(*s!='f')) /* Nothing else ... */
+ {
+ SendUser(u,"Male or Female (Return to abandon).\n");
+ PermitInput(u);
+ return(0);
+ }
+ if(*s=='m')
+ UserList[u].us_Record=PL_MALE;
+ else
+ UserList[u].us_Record=PL_FEMALE;
+ UserList[u].us_State=AWAIT_EMAIL;
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,
+ "Email address (Required): ");
+ PermitInput(u);
+ return(0);
+}
+
+
+int SetPlayerEmail(int u, char *mail)
+{
+ FILE *f=fopen("register.log","a");
+ if(f==NULL)
+ Error("Register.log open failed.\n");
+ fprintf(f,"Register of %s: EMail is %s\n",UserList[u].us_Name,mail);
+ fclose(f);
+ SendUser(u,"Thank you. You should be registered shortly.\n");
+/*
+ * Prepare to wait for a password
+ */
+ UserList[u].us_State=AWAIT_PWSET;
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,
+ "Give me a password for this character : ");
+ SendNPacket(UserList[u].us_Port,PACKET_ECHO,1,0,0,0); /* NOECHO */
+ PermitInput(u);
+ return(0);
+}
+
+/*
+ * Create a new player
+ */
+
+int CreatePersona(int u, char *pw)
+{
+ ITEM *place;
+ PLAYER *p;
+ TABLE *t;
+ SendNPacket(UserList[u].us_Port,PACKET_ECHO,0,0,0,0);
+/*
+ * Verify the legality of the players name
+ */
+ if(FindInList(WordList,UserList[u].us_Name,WD_NOUN))
+ {
+ SendUser(u,
+ "Sorry that name could be confused with other things.\n");
+ UserList[u].us_State=AWAIT_NAME;
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,
+ "By what name shall I call you: ");
+ PermitInput(u);
+ return(0);
+ }
+ if(FindInList(WordList,UserList[u].us_Name,WD_NOISE)||
+ FindInList(WordList,UserList[u].us_Name,WD_PREP)||
+ FindInList(WordList,UserList[u].us_Name,WD_ORDIN))
+ {
+ SendUser(u,
+ "Sorry that name could be confused with other things.\n");
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,
+ "By what name shall I call you: ");
+ UserList[u].us_State=AWAIT_NAME;
+ PermitInput(u);
+ return(0);
+ }
+/*
+ * Now create the player
+ */
+ UserList[u].us_State=AWAIT_COMMAND; /* Command mode */
+ strncpy(UserList[u].us_Password,pw,8);
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,"-}--- ");
+ if(stricmp(UserList[u].us_Name,"Anarchy")==0)
+ SendTPacket(UserList[u].us_Port,PACKET_SETPROMPT,"----*");
+/* SendUser(u,"Welcome to AberMUD V %s\n",UserList[u].us_Name); */
+ AddWord(UserList[u].us_Name,(short)(10000+u),WD_NOUN); /* Add name word */
+ UserList[u].us_Item=CreateItem(UserList[u].us_Name,-1,10000+u);
+ LockItem(UserList[u].us_Item); /* Lock for userlist entry */
+ MakePlayer(UserList[u].us_Item);
+ p=(PLAYER *)FindSub(UserList[u].us_Item,KEY_PLAYER);
+ if(!p)
+ Error("Login: Player Create Failure");
+ p->pl_UserKey=u;
+ place=FindMaster(10000,1,1);
+ if(place)
+ {
+ LinkItem(UserList[u].us_Item,place);
+/* Cmd_Look(UserList[u].us_Item);*/
+ }
+ p->pl_Size=120; /* Change these defaults if you want to */
+ p->pl_Weight=120;
+ p->pl_Strength=60;
+ p->pl_Flags=UserList[u].us_Record; /* We 'Borrow' this field */
+ p->pl_Level=1;
+ p->pl_Score=0;
+ UserList[u].us_Item->it_ActorTable=0;
+ UserList[u].us_Item->it_ActionTable=2;
+ UserList[u].us_Item->it_Perception=0;
+ UserList[u].us_Record=-1;
+ SetUserFlag(UserList[u].us_Item,0,0);
+ SetUserFlag(UserList[u].us_Item,1,0);
+ SetUserFlag(UserList[u].us_Item,2,0);
+ SetUserFlag(UserList[u].us_Item,3,0);
+ SetUserFlag(UserList[u].us_Item,4,0);
+ SetUserFlag(UserList[u].us_Item,5,0);
+ SetUserFlag(UserList[u].us_Item,6,0);
+ SetUserFlag(UserList[u].us_Item,7,0);
+ SetUserFlag(UserList[u].us_Item,15,LoginUFF.uff_Flag[9]);
+ DoesAction(UserList[u].us_Item,4,"arrives.\n");
+ t=FindTable(101);
+ if(t)
+ ExecBackground(t,UserList[u].us_Item);
+ PermitInput(u);
+ return(0);
+}
+
+/*
+ * The user has typed in a command to be done
+ */
+
+int Run_Command(int u, char *cmd)
+{
+ ITEM *i=UserList[u].us_Item;
+ int v;
+ char *x;
+ TABLE *t;
+ WordPtr=cmd;
+ if(i==NULL)
+ return(0); /* Do nothing.. person is dead */
+ if(setjmp(Oops)) /* Set the error trap */
+ goto panic;
+ if(strlen(WordPtr)==0) /* Nothing said */
+ goto l2;
+/* printf("User %d Cmd %s\n",u,WordPtr); */
+ /* Fake seeing the input string for snoopers */
+ /* Ought to show prompts I guess but I'm lazy */
+ SnoopCheckString(i,cmd);
+ SnoopCheckString(i,"\n");
+ if(stricmp(cmd,"INIT")==0)
+ {
+/*
+ * Yes you can fool this check for INIT being done, but if you do
+ * it's on your own head.
+ */
+ if(FindInList(WordList,"Abort",WD_VERB)==0)
+ {
+ AddWord("Abort",1,WD_VERB);
+ AddWord("AddVerb",2,WD_VERB);
+ AddWord("AddNoun",3,WD_VERB);
+ AddWord("AddAdj",4,WD_VERB);
+ AddWord("AddPrep",5,WD_VERB);
+ AddWord("AddPronoun",6,WD_VERB);
+ AddWord("AddOrdinate",7,WD_VERB);
+ AddWord("II",8,WD_VERB);
+ AddWord("ListItems",9,WD_VERB);
+ AddWord("SetName",10,WD_VERB);
+ AddWord("Set",11,WD_VERB);
+ AddWord("Create",12,WD_VERB);
+ AddWord("Delete",13,WD_VERB);
+ AddWord("BeRoom",14,WD_VERB);
+ AddWord("BeObject",15,WD_VERB);
+ AddWord("BePlayer",16,WD_VERB);
+ AddWord("UnRoom",17,WD_VERB);
+ AddWord("UnObject",18,WD_VERB);
+ AddWord("UnPlayer",19,WD_VERB);
+ AddWord("SaveUniverse",20,WD_VERB);
+ AddWord("StatMe",21,WD_VERB);
+ AddWord("SetShort",22,WD_VERB);
+ AddWord("SetLong",25,WD_VERB);
+ AddWord("ShowRoom",23,WD_VERB);
+ AddWord("SetRFlag",24,WD_VERB);
+ AddWord("Look",26,WD_VERB);
+ AddWord("Goto",27,WD_VERB);
+ AddWord("Brief",28,WD_VERB);
+ AddWord("Verbose",29,WD_VERB);
+ AddWord("ShowObject",30,WD_VERB);
+ AddWord("SetOFlag",31,WD_VERB);
+ AddWord("SetDesc",32,WD_VERB);
+ AddWord("Invisible",33,WD_VERB);
+ AddWord("Visible",34,WD_VERB);
+ AddWord("Say",35,WD_VERB);
+ AddWord("Place",36,WD_VERB);
+ AddWord("ListWord",37,WD_VERB);
+ AddWord("DelVerb",38,WD_VERB);
+ AddWord("DelNoun",39,WD_VERB);
+ AddWord("DelAdj",40,WD_VERB);
+ AddWord("DelPrep",41,WD_VERB);
+ AddWord("DelPronoun",42,WD_VERB);
+ AddWord("DelOrdinate",43,WD_VERB);
+ AddWord("NewExit",44,WD_VERB);
+ AddWord("DelExit",45,WD_VERB);
+ AddWord("OSize",46,WD_VERB);
+ AddWord("OWeight",47,WD_VERB);
+ AddWord("ShowPlayer",48,WD_VERB);
+ AddWord("SetPFlag",49,WD_VERB);
+ AddWord("SetPSize",50,WD_VERB);
+ AddWord("SetPWeight",51,WD_VERB);
+ AddWord("PSize",50,WD_VERB);
+ AddWord("PWeight",51,WD_VERB);
+ AddWord("PStrength",52,WD_VERB);
+ AddWord("SetPStrength",52,WD_VERB);
+ AddWord("SetPLevel",53,WD_VERB);
+ AddWord("SetPScore",54,WD_VERB);
+ AddWord("PLevel",53,WD_VERB);
+ AddWord("PScore",54,WD_VERB);
+ AddWord("Users",55,WD_VERB);
+ AddWord("ListTables",56,WD_VERB);
+ AddWord("DeleteTable",57,WD_VERB);
+ AddWord("LoadTable",58,WD_VERB);
+ AddWord("EditTable",59,WD_VERB);
+ AddWord("NewTable",60,WD_VERB);
+ AddWord("Quit",61,WD_VERB);
+ AddWord("Chain",62,WD_VERB);
+ AddWord("UnChain",63,WD_VERB);
+ AddWord("Rename",64,WD_VERB);
+ AddWord("SaveTable",65,WD_VERB);
+ AddWord("SetActor",66,WD_VERB);
+ AddWord("SetAction",67,WD_VERB);
+ AddWord("BeContainer",68,WD_VERB);
+ AddWord("UnContainer",69,WD_VERB);
+ AddWord("SetVolume",70,WD_VERB);
+ AddWord("ShowContainer",71,WD_VERB);
+ AddWord("MessageExit",72,WD_VERB);
+ AddWord("SetCFlag",73,WD_VERB);
+ AddWord("SetUFlag",74,WD_VERB);
+ AddWord("SetUItem",75,WD_VERB);
+ AddWord("ShowUser",76,WD_VERB);
+ AddWord("SetPicture",77,WD_VERB);
+ AddWord("Share",78,WD_VERB);
+ AddWord("UnShare",79,WD_VERB);
+ AddWord("Status",80,WD_VERB);
+ AddWord("NameFlag",81,WD_VERB);
+ AddWord("UnNameFlag",82,WD_VERB);
+ AddWord("ListFlag",83,WD_VERB);
+ AddWord("DoorPair",84,WD_VERB);
+ AddWord("ShowFlag",85,WD_VERB);
+ AddWord("SetFlag",86,WD_VERB);
+ AddWord("SetPerception",87,WD_VERB);
+ AddWord("ShowAllRooms",88,WD_VERB);
+ AddWord("ShowAllObjects",89,WD_VERB);
+ AddWord("ShowAllPlayers",95,WD_VERB);
+ AddWord("EditObject",96,WD_VERB);
+/*
+ * Directions
+ */
+ AddWord("North",100,WD_VERB);
+ AddWord("East",101,WD_VERB);
+ AddWord("South",102,WD_VERB);
+ AddWord("West",103,WD_VERB);
+ AddWord("Up",104,WD_VERB);
+ AddWord("Down",105,WD_VERB);
+ AddWord("NorthEast",106,WD_VERB);
+ AddWord("NorthWest",107,WD_VERB);
+ AddWord("SouthEast",108,WD_VERB);
+ AddWord("SouthWest",109,WD_VERB);
+ AddWord("In",110,WD_VERB);
+ AddWord("Out",111,WD_VERB);
+/*
+ * Second Verb Set
+ */
+ AddWord("ListClass",150,WD_VERB);
+ AddWord("NameClass",151,WD_VERB);
+ AddWord("SetClass",152,WD_VERB);
+ AddWord("UnsetClass",153,WD_VERB);
+ AddWord("TrackFlag",154,WD_VERB);
+ AddWord("UnTrackFlag",155,WD_VERB);
+ AddWord("ListTrack",156,WD_VERB);
+ AddWord("Debugger",157,WD_VERB);
+ AddWord("FindItem",158,WD_VERB);
+ AddWord("FindFlag",159,WD_VERB);
+ AddWord("Exorcise",160,WD_VERB);
+/*
+ * New for 5.07
+ */
+ AddWord("NameTable",161,WD_VERB);
+ AddWord("NameRFlag",162,WD_VERB);
+ AddWord("NameOFlag",163,WD_VERB);
+ AddWord("NamePFlag",164,WD_VERB);
+ AddWord("NameCFlag",165,WD_VERB);
+ AddWord("ListRFlags",166,WD_VERB);
+ AddWord("ListOFlags",167,WD_VERB);
+ AddWord("ListPFlags",168,WD_VERB);
+ AddWord("ListCFlags",169,WD_VERB);
+ AddWord("Which",170,WD_VERB);
+/*
+ * 5.08 Item table editing features
+ */
+ AddWord("EditOTable",171,WD_VERB);
+ AddWord("EditSTable",172,WD_VERB);
+ AddWord("CondExit",173,WD_VERB);
+/*
+ * 5.21 extensions
+ */
+ AddWord("EditDTable",174,WD_VERB);
+ AddWord("SetSuper",175,WD_VERB);
+ AddWord("ShowSuper",176,WD_VERB);
+ AddWord("DeleteBSX",177,WD_VERB);
+ AddWord("LoadBSX",178,WD_VERB);
+ AddWord("ListBSX",179,WD_VERB);
+ AddWord("ShowBSX",180,WD_VERB);
+/*
+ * Prepositions
+ */
+ AddWord("in",1,WD_PREP);
+ AddWord("to",2,WD_PREP);
+ AddWord("with",3,WD_PREP);
+ AddWord("at",4,WD_PREP);
+/*
+ * 5.07 System bit flag default names
+ */
+ RBitNames[0]=strdup("dark");
+ RBitNames[1]=strdup("outside");
+ RBitNames[2]=strdup("death");
+ RBitNames[3]=strdup("merge");
+ RBitNames[4]=strdup("join");
+ RBitNames[5]=strdup("dropemsg");
+ OBitNames[0]=strdup("flannel");
+ OBitNames[1]=strdup("noit");
+ OBitNames[2]=strdup("worn");
+ OBitNames[3]=strdup("reserved");
+ OBitNames[4]=strdup("canget");
+ OBitNames[5]=strdup("canwear");
+ OBitNames[6]=strdup("light");
+ OBitNames[7]=strdup("light0");
+ OBitNames[8]=strdup("noseecarry");
+ PBitNames[0]=strdup("male");
+ PBitNames[1]=strdup("female");
+ PBitNames[2]=strdup("brief");
+ PBitNames[3]=strdup("blind");
+ PBitNames[4]=strdup("deaf");
+ SendUser(u,"Initialised...\n");
+ }
+ else
+ SendUser(u,"It already is, bird brain.\n");
+ goto l1;
+ }
+ SetPersona(u);
+/*
+ * ! can be used if you put in a table 0 entry like any any any done, as
+ * a mistake. !command does the command without checking tables
+ */
+ if((*WordPtr==':')&&(ArchWizard(i)))
+ {
+ WordPtr++;
+ v=GetVerb();
+ goto l4;
+ }
+/*
+ * '*' cancels the autoverb feature
+ */
+ if(*WordPtr=='*')
+ {
+ WordPtr++;
+ goto l7;
+ }
+ if(GetContext((short)u)->pa_Verb>0) /* AUTOVERB */
+ v=GetContext((short)u)->pa_Verb;
+ else
+l7: v=GetVerb();
+ x=WordPtr;
+/*
+ * See if there is a table entry for the player. If so then
+ * do that and be finished.
+ */
+ if(UserAction(i,v)==1)
+ goto l1;
+ WordPtr=x;
+l4: switch(v)
+ {
+/*
+ * Select the correct system command routine
+ */
+ case -1:SendItem(i,"Sorry, But I don't recognise that verb.\n");
+ break;
+ case 1: Cmd_Abort(i);break;
+ case 2: Cmd_AddVerb(i);break;
+ case 3: Cmd_AddNoun(i);break;
+ case 4: Cmd_AddAdj(i);break;
+ case 5: Cmd_AddPrep(i);break;
+ case 6: Cmd_AddPronoun(i);break;
+ case 7: Cmd_AddOrdinate(i);break;
+ case 8: Cmd_ItemInfo(i);break;
+ case 9: Cmd_ListItems(i);break;
+ case 10:Cmd_SetName(i);break;
+ case 11:Cmd_SetState(i);break;
+ case 12:Cmd_NewItem(i);break;
+ case 13:Cmd_DelItem(i);break;
+ case 14:Cmd_BeRoom(i);break;
+ case 15:Cmd_BeObject(i);break;
+ case 16:Cmd_BePlayer(i);break;
+ case 17:Cmd_UnRoom(i);break;
+ case 18:Cmd_UnObject(i);break;
+ case 19:Cmd_UnPlayer(i);break;
+ case 20:Cmd_SaveUniverse(i);
+ PermitInput(u);
+ return(1);
+ case 21:Cmd_StatMe(i);break;
+ case 22:Cmd_SetShort(i);break;
+ case 23:Cmd_ShowRoom(i);break;
+ case 24:Cmd_SetRFlag(i);break;
+ case 25:Cmd_SetLong(i);break;
+ case 26:Cmd_Look(i);break;
+ case 27:Cmd_Goto(i);break;
+ case 28:Cmd_Brief(i);break;
+ case 29:Cmd_Verbose(i);break;
+ case 30:Cmd_ObjectShow(i);break;
+ case 31:Cmd_SetOFlag(i);break;
+ case 32:Cmd_SetDesc(i);break;
+ case 33:Cmd_Invisible(i);break;
+ case 34:Cmd_Visible(i);break;
+ case 35:Cmd_Say(i);break;
+ case 36:Cmd_Place(i);break;
+ case 37:Cmd_ListWord(i);break;
+ case 38:Cmd_DelVerb(i);break;
+ case 39:Cmd_DelNoun(i);break;
+ case 40:Cmd_DelAdj(i);break;
+ case 41:Cmd_DelPrep(i);break;
+ case 42:Cmd_DelPronoun(i);break;
+ case 43:Cmd_DelOrdinate(i);break;
+ case 44:Cmd_NewExit(i);break;
+ case 45:Cmd_DelExit(i);break;
+ case 46:Cmd_SetOSize(i);break;
+ case 47:Cmd_SetOWeight(i);break;
+ case 48:Cmd_PlayerShow(i);break;
+ case 49:Cmd_SetPFlag(i);break;
+ case 50:Cmd_SetPSize(i);break;
+ case 51:Cmd_SetPWeight(i);break;
+ case 52:Cmd_SetPStrength(i);break;
+ case 53:Cmd_SetPLevel(i);break;
+ case 54:Cmd_SetPScore(i);break;
+ case 55:Cmd_Users(i);break;
+ case 56:Cmd_ListTables(i);break;
+ case 57:Cmd_DeleteTable(i);break;
+ case 58:Cmd_AddTable(i);break;
+ case 59:Cmd_EditTable(i);break;
+ case 60:Cmd_NewTable(i);break;
+ case 61:
+#ifdef ATTACH
+ if(UserList[u].us_RealPerson)
+ {
+ SetMe(i);
+ Act_UnAlias();
+ break;
+ }
+#endif
+ SendTPacket(UserList[u].us_Port,PACKET_CLEAR,
+ "Goodbye......\n");
+ RemoveUser(u);
+ return(1);
+ case 62:Cmd_Chain(i);break;
+ case 63:Cmd_UnChain(i);break;
+ case 64:Cmd_Rename(i);break;
+ case 65:Cmd_SaveTable(i);break;
+ case 66:Cmd_SetActor(i);break;
+ case 67:Cmd_SetAction(i);break;
+ case 68:Cmd_BeContainer(i);break;
+ case 69:Cmd_UnContainer(i);break;
+ case 70:Cmd_SetVolume(i);break;
+ case 71:Cmd_ContainerShow(i);break;
+ case 72:Cmd_MsgExit(i);break;
+ case 73:Cmd_SetCFlag(i);break;
+ case 74:Cmd_SetUFlag(i);break;
+ case 75:Cmd_SetUItem(i);break;
+ case 76:Cmd_UFlagShow(i);break;
+ case 77:Cmd_SetPicture(i);break;
+ case 78:Cmd_Share(i);break;
+ case 79:Cmd_UnShare(i);break;
+ case 80:Cmd_Status(i);break;
+ case 81:Cmd_NameFlag(i);break;
+ case 82:Cmd_UnNameFlag(i);break;
+ case 83:Cmd_ListFlags(i);break;
+ case 84:Cmd_DoorPair(i);break;
+ case 85:Cmd_ShowFlag(i);break;
+ case 86:Cmd_SetFlag(i);break;
+ case 87:Cmd_SetPerception(i);break;
+ case 88:Cmd_ShowAllRooms(i);break;
+ case 89:Cmd_ShowAllObjects(i);break;
+ case 95:Cmd_ShowAllPlayers(i);break;
+ case 96:Cmd_ObjEdit(i);break;
+ case 100:Cmd_MoveDirn(i,0);break;
+ case 101:Cmd_MoveDirn(i,1);break;
+ case 102:Cmd_MoveDirn(i,2);break;
+ case 103:Cmd_MoveDirn(i,3);break;
+ case 104:Cmd_MoveDirn(i,4);break;
+ case 105:Cmd_MoveDirn(i,5);break;
+ case 106:Cmd_MoveDirn(i,6);break;
+ case 107:Cmd_MoveDirn(i,7);break;
+ case 108:Cmd_MoveDirn(i,8);break;
+ case 109:Cmd_MoveDirn(i,9);break;
+ case 110:Cmd_MoveDirn(i,10);break;
+ case 111:Cmd_MoveDirn(i,11);break;
+ case 150:Cmd_ListClass(i);break;
+ case 151:Cmd_NameClass(i);break;
+ case 152:Cmd_SetClass(i);break;
+ case 153:Cmd_UnsetClass(i);break;
+ case 154:Cmd_TrackFlag(i);break;
+ case 155:Cmd_UnTrackFlag(i);break;
+ case 156:Cmd_ListTrack(i);break;
+ case 157:Cmd_Debugger(i);break;
+ case 158:Cmd_FindItem(i);break;
+ case 159:Cmd_FindFlag(i);break;
+ case 160:Cmd_Exorcise(i);break;
+ case 161:Cmd_NameTable(i);break;
+ case 162:Cmd_RBitName(i);break;
+ case 163:Cmd_OBitName(i);break;
+ case 164:Cmd_PBitName(i);break;
+ case 165:Cmd_CBitName(i);break;
+ case 166:Cmd_ListRBits(i);break;
+ case 167:Cmd_ListOBits(i);break;
+ case 168:Cmd_ListPBits(i);break;
+ case 169:Cmd_ListCBits(i);break;
+ case 170:Cmd_Which(i);break;
+ case 171:Cmd_EditOTable(i);break;
+ case 172:Cmd_EditSTable(i);break;
+ case 173:Cmd_CondExit(i);break;
+ case 174:Cmd_EditDTable(i);break;
+ case 175:Cmd_SetSuperClass(i);break;
+ case 176:Cmd_ShowSuperClass(i);break;
+ case 177:Cmd_DeleteBSX(i);break;
+ case 178:Cmd_LoadBSX(i);break;
+ case 179:Cmd_ListBSX(i);break;
+ case 180:Cmd_ShowBSX(i);break;
+ default:SendItem(i,"I don't understand.\n");
+ break;
+ }
+/*
+ * Run the status table
+ */
+l1: t=FindTable(100);
+ if(t&&UserList[u].us_State==AWAIT_COMMAND)
+ ExecBackground(t,UserList[u].us_Item);
+panic:;
+l2: PermitInput(u);
+ return 0;
+}
+
diff --git a/ComServer.c b/ComServer.c
new file mode 100644
index 0000000..ebbeedb
--- /dev/null
+++ b/ComServer.c
@@ -0,0 +1,358 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Daemon Communications Server Routines
+ *
+ * Strange this but the theory behind the user being in a state
+ * and of having a set of state changing vectors actually came
+ * from the original pre-abermud basic experiments on a sirius!
+ */
+
+#include "System.h" /* System includes and options */
+#include "User.h"
+
+Module "Communication Server";
+Version "1.28";
+Author "----*(A)";
+
+/*
+ * 1.21 AGC General Version With SUPERCEDE
+ * 1.22 AGC Added acknowledged clear to avoid crashes
+ * 1.23 AGC Fixed TPacket sent as NPacket bug in Handle_Login
+ * 1.24 AGC Changes to fit in nicely with new IPC
+ * 1.25 AGC Tweaks to FixLineFaults()
+ * 1.26 AGC Moved motd code
+ * 1.27 AGC BSX Aware
+ * 1.28 AGC ANSIfication cleanup
+ */
+
+PORT *Master_Port=NULL; /* Our Port */
+USER UserList[MAXUSER]; /* Information about each user */
+short LineFault[MAXUSER]; /* 1 = user has timeout problem */
+
+void FixLineFaults(void)
+{
+ int ct=0;
+ while(ct<MAXUSER)
+ {
+ if(UserList[ct].us_Port!=NULL)
+ {
+ SiloFlush(UserList[ct].us_Port);
+ if(LineFault[ct]||UserList[ct].us_Port->po_Flags&FL_FAULT)
+ {
+ /* Fighting.. no getouts allowed */
+ if(UserList[ct].us_Item && GetUserFlag(UserList[ct].us_Item,2)!=0)
+ {
+ ct++;
+ continue;
+ }
+ RemoveUser(ct);
+ UserList[ct].us_State=AWAIT_LOGIN;
+ }
+ }
+ LineFault[ct]=0;
+ ct++;
+ }
+}
+
+
+int Current_UserList; /* Number of the current user */
+
+
+/*
+ * Post a block of data to a PLAY process.
+ */
+
+int SendBlock(PORT *us, COMTEXT *block, int size)
+{
+ int er;
+ if((er=WriteMPort(us,block,size))<0)
+ {
+ if(er!=-20)
+ {
+ Log("Error: Port write fail - %d\n",er);
+ exit(10);
+ }
+ return(-20); /* Queue Filled */
+ }
+ return(1);
+}
+
+/*
+ * Post a text block to a PLAY process
+ */
+
+int SendTPacket(PORT *us, short class, char *data)
+{
+ COMTEXT a;
+ a.pa_Type=class;
+ a.pa_Sender=-1;
+ strcpy(a.pa_Data,data);
+ return(SendBlock(us,&a,strlen(data)+2*(sizeof(short))+1));
+}
+
+/*
+ * Post a numeric block to a PLAY process
+ */
+
+int SendNPacket(PORT *us, short class, short p1, short p2, short p3, short p4)
+{
+ COMDATA a;
+ a.pa_Type=class;
+ a.pa_Sender=-1;
+ a.pa_Data[0]=p1;
+ a.pa_Data[1]=p2;
+ a.pa_Data[2]=p3;
+ a.pa_Data[3]=p4;
+ return(SendBlock(us,(COMTEXT *)&a,sizeof(COMDATA)));
+}
+
+
+/*
+ * Get a message sent to us from the Master_Port
+ */
+
+int GetPacket(PORT *port, COMTEXT *packet)
+{
+ int er;
+ BlockOff(port);
+ if((er=ReadMPort(port, packet))<0)
+ {
+ if(er==-3||er==-2) /* Interruted call */
+ return(-2); /* Port empty */
+ exit(11);
+ }
+ if(packet->pa_Type==PACKET_BONG)
+ return(-2); /* Fake a timer event */
+ return(0);
+}
+
+/*
+ * This function starts the process of logging a new user into the
+ * game environment.
+ */
+
+void Handle_Login(char *msg)
+{
+ PORT *port;
+ long v;
+ char *a;
+ int ct=0;
+ char ubf[MAXUSERID+64];
+ char mbuf[256];
+ FILE *motd;
+ extern PORT *Bind_Port();
+/*
+ * Look for a free slot
+ */
+ while(ct<MAXUSER)
+ {
+ if(UserList[ct].us_Name[0]==0)
+ break;
+ ct++;
+ }
+/*
+ * See if there was room to login
+ */
+ if(ct==MAXUSER-1||ct>=MaxSlot())
+ {
+ while(*msg!='$') msg++;
+ *msg++=0;
+ if(sscanf(msg,"%ld$%s",&v,ubf)==0)
+ {
+ Log("Error: Corrupt Login Attempt");
+ return;
+ }
+ port=(PORT *)Bind_Port(ct,v);
+ if(port==NULL)
+ {
+ UserList[ct].us_Port=NULL;
+ return;
+ }
+ if(port->po_fd&256)
+ {
+ if(ct<MAXUSER-1)
+ goto oops;
+ }
+ /* New IPC needs a user associating with the channel
+ before we do work on it */
+ UserList[ct].us_Port=port;
+ SendTPacket(port,PACKET_CLEAR,
+ "Sorry..... the game is currently full.\n");
+ CloseMPort(port);
+ UserList[ct].us_Port=NULL;
+ }
+ else
+/*
+ * Accept the new login and enter it into the userlist
+ */
+ {
+oops:
+ a=msg;
+ while(*msg!='$')
+ msg++;
+ *msg++=0;
+ if(!sscanf(msg,"%ld$%s",&v,ubf))
+ {
+ Log("Error: Corrupt Login");
+ return;
+ }
+ port=Bind_Port(ct,v);
+ if(port==NULL)
+ {
+ Log("Error: Port Open Failed");
+ return;
+ }
+ strcpy(UserList[ct].us_UserName,a);
+ strcpy(UserList[ct].us_Name,"<login>");
+ UserList[ct].us_State=AWAIT_NAME;
+ UserList[ct].us_Flags=0;
+ UserList[ct].us_Port=port;
+ time(&(UserList[ct].us_Login));
+ if(*ubf!='*')
+ sprintf(UserList[ct].us_UserName,"Internet:%s",ubf);
+/*
+ * Game Login Code Here
+ */
+ if(!IsBSX(ct) || (motd=fopen("motd.bsx","r"))==NULL)
+ motd=fopen("motd","r");
+ if(motd)
+ {
+ while(fgets(mbuf,255,motd)!=NULL)
+ {
+ SendUser(ct,mbuf);
+ }
+ fclose(motd);
+ }
+ SendNPacket(port,PACKET_LOGINACCEPT,0,ct,0,0); /* login ok */
+ SendNPacket(port,PACKET_ECHO,0,0,0,0); /* Echo On */
+ SendTPacket(port,PACKET_SETPROMPT,"What be thy name ? ");
+ SendNPacket(port,PACKET_INPUT,1,0,0,0); /* Go ahead and type */
+ }
+ return;
+}
+
+/*
+ * Decide what to do with a packet recieved from a PLAY
+ */
+
+void InterpretPacket(COMTEXT *x)
+{
+ Current_UserList=x->pa_Sender;
+
+ switch(x->pa_Type)
+ {
+ case PACKET_SUPERCEDE: /* Sent when new SERVER takes over */
+
+ SupercedeFlag=1;
+ break;
+
+ case PACKET_ABORT: /* Sent to cause termination */
+
+ Broadcast("Remote Abort Requested: Terminating Abruptly.\n",0);
+ exit(0);
+
+ case PACKET_CLEAR: /* Client gone pop! */
+
+ if(Current_UserList!=-1)
+ {
+ printf("Time Out From %d\n",Current_UserList);
+ TimeOut(Current_UserList);
+ }
+ break;
+
+ case PACKET_CLEARED: /* Sent to confirm a CLEAR request */
+
+ if(Current_UserList!=-1)
+ UserList[Current_UserList].us_State=AWAIT_LOGIN;
+ break;
+
+ case PACKET_LOOPECHO: /* Loopback for testing */
+
+ if(Current_UserList!=-1)
+ SendNPacket(UserList[Current_UserList].us_Port,
+ PACKET_ECHOBACK,0,0,0,0);
+ break; /* Honour echoback protocols */
+
+ case PACKET_COMMAND: /* Input from a player */
+
+ Handle_Command(Current_UserList,x->pa_Data);
+ break;
+
+ case PACKET_LOGINREQUEST: /* A new login */
+
+ Handle_Login(x->pa_Data);
+ break;
+
+ case PACKET_OUTPUT:
+
+ Handle_Output(x->pa_Data); /* Console Out */
+ break;
+
+ case PACKET_COMMFORCE: /* Command off menu bar */
+
+ Handle_CommForce(Current_UserList,x->pa_Data);
+ break; /* State AWAIT_COMMAND command */
+
+ case PACKET_BSXSCENE: /* Incoming BSX Request */
+
+ Handle_BSXPacket(Current_UserList,x->pa_Data);
+ break;
+
+ default: Log("Invalid Packet: Type %d.\n",
+ x->pa_Type);
+ }
+}
+
+/*
+ * Handle all of the pending input from the Master_Port
+ */
+
+void ProcessPackets(void)
+{
+ int er;
+ COMTEXT p;
+ while(1)
+ {
+ er=GetPacket(Master_Port,&p);
+ if(er==-2)
+ break;
+ InterpretPacket(&p);
+ }
+}
+
+int Handle_Output(char *x)
+{
+ printf("%s",x); /* For Now */
+ return(0);
+}
+
+/*
+ * Sort out what must be done when a user does a command
+ */
+
+int Handle_Command(int ch, char *x)
+{
+ if(ch==-1)
+ return(-1);
+ Command_Driver(ch,UserList[ch].us_State,x);
+ return(0);
+}
+
+
+int Handle_CommForce(int ch, char *x)
+{
+ if(ch==-1)
+ return(-1);
+ if(UserList[ch].us_State==AWAIT_COMMAND)
+ Command_Driver(ch,AWAIT_COMMAND,x);
+ return(0);
+}
diff --git a/Comms.h b/Comms.h
new file mode 100644
index 0000000..2163bd9
--- /dev/null
+++ b/Comms.h
@@ -0,0 +1,55 @@
+#define MSGPORT
+struct Com_Pack1
+{
+ short pa_Type;
+ short pa_Sender;
+ short pa_Data[4];
+};
+
+struct Com_Pack2
+{
+ short pa_Type;
+ short pa_Sender;
+ char pa_Data[512];
+};
+
+typedef struct Com_Pack1 COMDATA;
+typedef struct Com_Pack2 COMTEXT;
+
+typedef struct SysPacket
+{
+#ifdef MSGPORT
+ long pa_Type;
+#endif
+ short pa_Size;
+ char pa_Data[516];
+} PACKET;
+
+#define PACKET_CLEAR 0 /*Num. parser clear and shutdown */
+#define PACKET_LOOPECHO 1 /*Num. cause either end to echo 2*/
+#define PACKET_ECHOBACK 2 /*Num. echo back */
+#define PACKET_LOGINACCEPT 3 /*Num. p1 holds systems ctrl sig */
+ /* p2 holds your 'user ref' */
+#define PACKET_CLEARED 4 /*User has cleared */
+#define PACKET_ECHO 5 /* Set echo on p1=1 off on p1=0 */
+#define PACKET_INPUT 6 /* p1=input on p2=input off */
+#define PACKET_LOGINREQUEST 128 /*Text. text holds:-
+ SigCode:UserID:FilePath */
+
+#define PACKET_OUTPUT 129 /*Text for printing */
+#define PACKET_COMMAND 130 /*Incoming command line */
+#define PACKET_SETPROMPT 131 /*Set prompt line */
+#define PACKET_COMMFORCE 132 /*Command but always from base */
+ /*eg menu selections etc */
+#define PACKET_EDIT 133 /*Edit Request */
+#define PACKET_SNOOPTEXT 134 /*Snooped text */
+#define PACKET_SETFIELD 135 /*Field shift */
+#define PACKET_SETTITLE 240 /*Title bar for clients */
+#define PACKET_BSXSCENE 200 /*Draw a picture request */
+#define PACKET_BSXOBJECT 201 /*Draw an object */
+
+#define PACKET_ABORT 140 /* REMOTE DIE REQUEST */
+#define PACKET_SUPERCEDE 141 /* I'VE PINCHED YOUR PORT..... */
+
+#define PACKET_BONG 150 /* Once per second packet shover */
+
diff --git a/CompileTable.c b/CompileTable.c
new file mode 100644
index 0000000..379ed41
--- /dev/null
+++ b/CompileTable.c
@@ -0,0 +1,928 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+Module "Table Compiler";
+Version "1.10";
+Author "Alan Cox";
+
+
+/*
+ * 1.00 AGC Created this file
+ * 1.01 AGC Added support for {$}
+ * 1.02 AGC Added $RM $ME $1 $2
+ * 1.03 AGC Added {$2}
+ * 1.04 AGC Added NONE
+ * 1.05 AGC Added reverse compiler for table editing
+ * 1.06 AGC Added the code to handle named flags
+ * 1.07 AGC Added #item
+ * 1.08 AGC Classes
+ * 1.09 AGC Added the BitName fields
+ */
+
+/*
+ * Routines to convert between source and line data
+ *
+ */
+
+
+static unsigned short DataBuffer[1024]; /* A Line Buffer */
+static short DPtr=0;
+static char LineBuffer[512];
+static char *LinePtr=LineBuffer;
+
+static char *GetText2()
+{
+ extern char *strtok2();
+ if(LinePtr==LineBuffer)
+ {
+ LinePtr++;
+ return(strtok2(LineBuffer,"\t {","}"));
+ }
+ return(strtok2(NULL," \t{","}"));
+}
+
+
+static char *GetText()
+{
+ char *a;
+l1: a=GetText2();
+ if(a==NULL)
+ return(a);
+ if(a==(char *)-1)
+ return(a);
+ if(strlen(a)==0)
+ goto l1;
+ return(a);
+}
+
+static char *GetToken2()
+{
+ extern char *strtok2();
+ if(LinePtr==LineBuffer)
+ {
+ LinePtr++;
+ return(strtok2(LineBuffer," \n\t,"," \n\t,"));
+ }
+ return(strtok2(NULL," \n\t,"," \n\t,"));
+}
+
+static char *GetToken()
+{
+ char *a;
+l1: a=GetToken2();
+ if(a==NULL)
+ return(a);
+ if(strlen(a)==0) goto l1;
+ return(a);
+}
+
+static int WriteDb(n)
+int n;
+{
+ if(DPtr==1024)
+ return(-1);
+ DataBuffer[DPtr++]=n;
+ return(0);
+}
+
+static int EncodeFlag(i)
+ITEM *i;
+{
+ char *a=GetToken();
+ int b;
+ int shf=0;
+ if(a==NULL)
+ {
+ SendItem(i,"Missing Numeric Argument.\n");
+ return(-1);
+ }
+ if((*a=='F')||(*a=='f'))
+ {
+ a++;
+ shf=30000;
+ }
+ if(*a=='@')
+ {
+ b=GetFlagByName(a);
+ if(b==-1)
+ {
+ SendItem(i,"Invalid Flag Name - %s.\n",a);
+ return(-1);
+ }
+ }
+ else
+ {
+ if(sscanf(a,"%d",&b)==0)
+ {
+ SendItem(i,"Invalid Numeric Argument - %s.\n",a);
+ return(-1);
+ }
+ }
+ if(WriteDb(b+shf)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+}
+
+static int EncodeClass(i)
+ITEM *i;
+{
+ char *a=GetToken();
+ short b=WhichClass(a);
+ if(stricmp(a,"0")==0)
+ {
+ if(WriteDb(-1)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+ }
+ if(b==-1)
+ {
+ SendItem(i,"Unknown class %s.\n",a);
+ return(-1);
+ }
+ if(WriteDb(b)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+}
+
+static int EncodeRFlag(i)
+ITEM *i;
+{
+ char *a=GetToken();
+ int b;
+ if(a==NULL)
+ {
+ SendItem(i,"Missing Room Bit Flag.\n");
+ return(-1);
+ }
+ b=FindRBit(a);
+ if(b==-1)
+ {
+ SendItem(i,"Unknown Room Bit Flag '%s'.\n",a);
+ return(-1);
+ }
+ if(WriteDb(b)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+}
+
+static int EncodeOFlag(i)
+ITEM *i;
+{
+ char *a=GetToken();
+ int b;
+ if(a==NULL)
+ {
+ SendItem(i,"Missing Object Bit Flag.\n");
+ return(-1);
+ }
+ b=FindOBit(a);
+ if(b==-1)
+ {
+ SendItem(i,"Unknown Object Bit Flag '%s'.\n",a);
+ return(-1);
+ }
+ if(WriteDb(b)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+}
+
+static int EncodePFlag(i)
+ITEM *i;
+{
+ char *a=GetToken();
+ int b;
+ if(a==NULL)
+ {
+ SendItem(i,"Missing Player Bit Flag.\n");
+ return(-1);
+ }
+ b=FindPBit(a);
+ if(b==-1)
+ {
+ SendItem(i,"Unknown Player Bit Flag '%s'.\n",a);
+ return(-1);
+ }
+ if(WriteDb(b)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+}
+
+static int EncodeCFlag(i)
+ITEM *i;
+{
+ char *a=GetToken();
+ int b;
+ if(a==NULL)
+ {
+ SendItem(i,"Missing Container Bit Flag.\n");
+ return(-1);
+ }
+ b=FindCBit(a);
+ if(b==-1)
+ {
+ SendItem(i,"Unknown Container Bit Flag '%s'.\n",a);
+ return(-1);
+ }
+ if(WriteDb(b)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+}
+
+static int EncodeNumber(i)
+ITEM *i;
+{
+ char *a=GetToken();
+ int b;
+ int shf=0;
+ if(a==NULL)
+ {
+ SendItem(i,"Missing Numeric Argument.\n");
+ return(-1);
+ }
+ if((*a=='F')||(*a=='f'))
+ {
+ a++;
+ shf=30000;
+ }
+ if(sscanf(a,"%d",&b)==0)
+ {
+ SendItem(i,"Invalid Numeric Argument - %s.\n",a);
+ return(-1);
+ }
+ if(WriteDb(b+shf)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+}
+
+static int EncodeProcess(i)
+ITEM *i;
+{
+ char *a=GetToken();
+ int b;
+ int shf=0;
+ if(a==NULL)
+ {
+ SendItem(i,"Missing Table Name/Number.\n");
+ return(-1);
+ }
+ if((*a=='F'||*a=='f')&&isdigit(a[1]))
+ {
+ a++;
+ shf=30000;
+ }
+ if(!shf&&!isdigit(*a))
+ {
+ b=FindTableByName(a);
+ if(b==-1)
+ {
+ SendItem(i,"Unknown table %s\n",a);
+ return(-1);
+ }
+ if(WriteDb(b)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+ }
+ if(sscanf(a,"%d",&b)==0)
+ {
+ SendItem(i,"Invalid Numeric Argument - %s.\n",a);
+ return(-1);
+ }
+ if(WriteDb(b+shf)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+}
+
+static char *WorType[]=
+{
+ "",
+ "noun","preposition","pronoun","class","verb","adjective","noise word"
+};
+
+static int EncodeWord(i,type)
+ITEM *i;
+short type;
+{
+ char *a=GetToken();
+ WLIST *b;
+ if(a==NULL)
+ {
+ SendItem(i,"Missing %s argument.\n",WorType[type]);
+ return(-1);
+ }
+ if(stricmp(a,"ANY")==0)
+ {
+ if(WriteDb(-1)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+ }
+ if(stricmp(a,"NONE")==0)
+ {
+ if(WriteDb(-2)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+ }
+ if(type==-1)
+ {
+ b=FindInList(WordList,a,WD_VERB);
+ if(!b)
+ b=FindInList(WordList,a,WD_ADJ);
+ }
+ else
+ b=FindInList(WordList,a,type);
+ if(b==NULL)
+ {
+ SendItem(i,"Unknown %s '%s'.\n",WorType[type],a);
+ return(-1);
+ }
+ if(WriteDb(b->wd_Code)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+}
+
+static ITEM *LockList[256];
+static short LockCount;
+
+int RememberToLockItem(i)
+ITEM *i;
+{
+ if(LockCount==256) return(-1);
+ LockList[LockCount++]=i;
+ return(0);
+}
+
+void LockLockList()
+{
+ short x=0;
+ while(x<LockCount)
+ LockItem(LockList[x++]);
+}
+
+static int EncodeItem(i)
+ITEM *i;
+{
+ char *a=GetToken();
+ char *b;
+ ITEM *x;
+ WLIST *ad,*no;
+ int refid=1;
+ static WLIST DummyNullWord={"ANY",WD_ADJ,-1,NULL};
+ if(a==NULL)
+ {
+ SendItem(i,"Object expected.\n");
+ return(-1);
+ }
+ if(stricmp(a,"$1")==0)
+ {
+ x=(ITEM *)1;
+ goto l1;
+ }
+ if(stricmp(a,"$2")==0)
+ {
+ x=(ITEM *)3;
+ goto l1;
+ }
+ if(stricmp(a,"$ME")==0)
+ {
+ x=(ITEM *)5;
+ goto l1;
+ }
+ if(stricmp(a,"$AC")==0)
+ {
+ x=(ITEM *)7;
+ goto l1;
+ }
+ if(stricmp(a,"$RM")==0)
+ {
+ x=(ITEM *)9;
+ goto l1;
+ }
+ b=GetToken();
+ if(*a=='#')
+ {
+ if(sscanf(a,"#%d",&refid)==0)
+ {
+ SendItem(i,"Bad # identity %s.\n",a);
+ return(-1);
+ }
+ a=b;
+ b=GetToken();
+ }
+ if(a==NULL||b==NULL)
+ {
+ SendItem(i,"Object expected.\n");
+ return(-1);
+ }
+ if(stricmp(a,"ANY")==0)
+ ad=&DummyNullWord;
+ else
+ ad=FindInList(WordList,a,WD_ADJ);
+ if(ad==NULL)
+ {
+ SendItem(i,"Unknown Word %s.\n",a);
+ return(-1);
+ }
+ no=FindInList(WordList,b,WD_NOUN);
+ if(no==NULL)
+ {
+ SendItem(i,"Unknown Word %s.\n",b);
+ return(-1);
+ }
+ x=FindMaster(32767,ad->wd_Code,no->wd_Code);
+ if(refid>1)
+ {
+ while((--refid)&&(x))
+ x=NextMaster(32767,x,ad->wd_Code,no->wd_Code);
+ if(x==NULL)
+ SendItem(i,"# out of range for item %s %s.\n",a,b);
+ }
+ if(x==NULL)
+ {
+ SendItem(i,"Unknown Item %s %s.\n",a,b);
+ return(-1);
+ }
+ if(RememberToLockItem(x))
+ return(-1); /* Lock the reference */
+l1: if(WriteDb((unsigned short)(((unsigned int)(x))/65536L))==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ if(WriteDb((unsigned short)(((unsigned int)(x))%65536L))==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+}
+
+
+
+static int EncodeText(i,n)
+ITEM *i;
+int n;
+{
+ TPTR a;
+ char *b;
+ b=GetText();
+ if(b==NULL)
+ {
+ SendItem(i,"Text Argument Missing.\n");
+ return(-1);
+ }
+ if(b==(char *)-1)
+ {
+ SendItem(i,"{ expected.\n");
+ return(-1);
+ }
+ if(stricmp(b,"$")==0)
+ a=(TPTR)1;
+ else
+ {
+ if(stricmp(b,"$2")==0)
+ a=(TPTR)3;
+ else
+ {
+ if(n)
+
+ a=AllocComment(b);
+ else
+ a=AllocText(b);
+ }
+ }
+ if(WriteDb((unsigned short)(((unsigned int)(a))/65536L))==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ if(WriteDb((unsigned short)(((unsigned int)(a))%65536L))==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ return(0);
+}
+
+static int EncodeCommand(i,n)
+ITEM *i;
+short n; /* Command Code */
+{
+ int v;
+ char *d=Cnd_Table[n];
+ if(WriteDb(n)==-1)
+ {
+ SendItem(i,"Line Too Complex.\n");
+ return(-1);
+ }
+ while(*d!=' ')
+ {
+ switch(*d)
+ {
+ case 'w':v=EncodeWord(i,-1);break;
+ case 'W':v=EncodeNumber(i);break;
+ case 'Z':v=EncodeNumber(i);break;
+ case 'I':v=EncodeItem(i);break;
+ case 'F':v=EncodeFlag(i);break;
+ case 'N':v=EncodeNumber(i);break;
+ case 'B':v=EncodeNumber(i);break;
+ case 'a':v=EncodeWord(i,WD_ADJ);break;
+ case 'n':v=EncodeWord(i,WD_NOUN);break;
+ case 'p':v=EncodeWord(i,WD_PREP);break;
+ case 'v':v=EncodeWord(i,WD_VERB);break;
+ case 'T':v=EncodeText(i,0);break;
+ case '$':v=EncodeText(i,1);break;
+ case 't':v=EncodeProcess(i);break;
+ case 'C':v=EncodeClass(i);break;
+ case 'c':v=EncodeCFlag(i);break;
+ case 'R':v=EncodeRFlag(i);break;
+ case 'O':v=EncodeOFlag(i);break;
+ case 'P':v=EncodePFlag(i);break;
+ default:
+ Error("Invalid Entry in Cnd_Table");
+ }
+ if(v==-1)
+ return(-1);
+ d++;
+ }
+ return(0);
+}
+
+static int EncodeLine(i)
+ITEM *i;
+{
+ char *a;
+ short c;
+ DPtr=0;
+ LockCount=0;
+ if(EncodeWord(i,WD_VERB)==-1)
+ return(-1);
+ if(EncodeWord(i,WD_NOUN)==-1)
+ return(-1);
+ if(EncodeWord(i,WD_NOUN)==-1)
+ return(-1);
+ while((a=GetToken())!=NULL)
+ {
+ if(!strlen(a))
+ continue;
+ c=FindCnd(a);
+ if(c==-1)
+ {
+ SendItem(i,"Unknown Condition/Action '%s'.\n",a);
+ return(-1);
+ }
+ if(EncodeCommand(i,c)==-1)
+ return(-1);
+ }
+ WriteDb(CMD_EOL);
+ LockLockList();
+ return(0);
+}
+
+void LoadLineBuffer(x)
+char *x;
+{
+ strcpy(LineBuffer,x);
+ LinePtr=LineBuffer;
+}
+
+int EncodeEntry(i,l)
+ITEM *i;
+LINE *l;
+{
+ int ct=3;
+ if(EncodeLine(i)==-1)
+ return(-1);
+ free((char *)l->li_Data);
+ l->li_Data=(unsigned short *)malloc((DPtr-3)*sizeof(unsigned short));
+ if(l->li_Data==NULL)
+ {
+ SendItem(i,"Out Of Memory.\n");
+ return(-1);
+ }
+ l->li_Verb=DataBuffer[0];
+ l->li_Noun1=DataBuffer[1];
+ l->li_Noun2=DataBuffer[2];
+ while(ct<DPtr)
+ {
+ l->li_Data[ct-3]=DataBuffer[ct];
+ ct++;
+ }
+ return(0);
+}
+
+int EncodeTable(i,t,f)
+ITEM *i;
+TABLE *t;
+FILE *f;
+{
+ LINE *l;
+ char *lp=LineBuffer;
+ while(fgets(lp,511,f))
+ {
+l3: if((*lp)&&(lp[strlen(lp)-2]=='+'))
+ {
+ lp+=strlen(lp)-2; /* Continuation */
+ if(lp-LineBuffer>400) goto l2;
+ if(!fgets(lp,511,f))
+ goto l2;
+ goto l3;
+ }
+l2: LineBuffer[511]=0;
+ LinePtr=LineBuffer;
+ lp=LineBuffer;
+ l=NewLine(t,32767);
+ if(EncodeEntry(i,l)==-1)
+ return(-1);
+ }
+ return(0);
+}
+
+static void DiscItem(dp)
+unsigned short *dp;
+{
+ extern unsigned long PairArg();
+ ITEM *a=(ITEM *)PairArg(dp);
+ if((a!=(ITEM *)1)&&(a!=(ITEM *)3)&&(a!=(ITEM *)5)
+ &&(a!=(ITEM *)7)&&(a!=(ITEM *)9))
+ UnlockItem(a);
+}
+
+static void DiscText(dp,n)
+unsigned short *dp;
+int n;
+{
+ TPTR a=(TPTR )(*dp*65536L+(*(dp+1)));
+ if(a==(TPTR )1)
+ return;
+ if(a==(TPTR )3)
+ return;
+ if(n)
+ FreeComment(a);
+ else
+ FreeText(a);
+}
+
+void WipeLine(l)
+LINE *l;
+{
+ unsigned short *dp=l->li_Data;
+ char *a;
+ while(*dp!=CMD_EOL)
+ {
+ a=Cnd_Table[*dp];
+ dp++;
+ while(*a!=' ')
+ {
+ switch(*a++)
+ {
+ case 'W':;
+ case 'w':;
+ case 'Z':;
+ case 'R':dp++;break;
+ case 'O':dp++;break;
+ case 'P':dp++;break;
+ case 'c':dp++;break;
+ case 'C':dp++;break;
+ case 'N':dp++;break;
+ case 'F':dp++;break;
+ case 'B':dp++;break;
+ case 'a':dp++;break;
+ case 'n':dp++;break;
+ case 'p':dp++;break;
+ case 'v':dp++;break;
+ case 't':dp++;break;
+ case 'I':DiscItem(dp);
+ dp+=2;
+ break;
+ case 'T':DiscText(dp,0);
+ dp+=2;
+ break;
+ case '$':DiscText(dp,1);
+ dp+=2;
+ break;
+ default:
+ Error("Cnd_Table: Invalid Entry");
+ }
+ }
+ }
+}
+
+
+void DeleteTable(t) /* Free Up A Table Entry, except for header */
+TABLE *t;
+{
+ LINE *l=t->tb_First;
+ LINE *n;
+ t->tb_First=NULL;
+ FreeText(t->tb_Name);
+ t->tb_Name=AllocText("(unset)");
+ while(l)
+ {
+ n=l->li_Next;
+ WipeLine(l);
+ free((char *)l->li_Data);
+ free((char *)l);
+ l=n;
+ }
+}
+
+/*
+ * Free a table header. Only use this on item bound tables, with
+ * no table data!
+ */
+
+void FreeTableHeader(t)
+TABLE *t;
+{
+ FreeText(t->tb_Name);
+ free((char *)t);
+}
+
+unsigned long PairArg(x)
+unsigned short *x;
+{
+ return((*x)<<16|x[1]);
+}
+
+char *NumText(n)
+int n;
+{
+ static char x[16];
+ if(n>29999)
+ sprintf(x,"F%d",n-30000);
+ else
+ sprintf(x,"%d",n);
+ return(x);
+}
+
+/*
+ * BUG:
+ *
+ * This routine should check the line does not overflow the 512 char
+ * buffer. What it does if this happens now is crash, what it should
+ * do is also a problem.
+ */
+
+void Decompress(line,buffer)
+LINE *line;
+char *buffer;
+{
+ register char *TLine;
+ unsigned short *x;
+ TABLE *tmp;
+ sprintf(buffer,"%s %s %s ",FindWText(line->li_Verb,WD_VERB),
+ FindWText(line->li_Noun1,WD_NOUN),
+ FindWText(line->li_Noun2,WD_NOUN));
+ x=(unsigned short *)(line->li_Data);
+ while(*x!=CMD_EOL)
+ {
+ int n=*x++;
+ int ct=0;
+ strcat(buffer,Cnd_Table[n]+8);
+ strcat(buffer," ");
+ TLine=Cnd_Table[n];
+ while(TLine[ct]!=' ')
+ {
+ ITEM *i;
+ TPTR t;
+ switch(TLine[ct])
+ {
+ case 'I':
+ i=(ITEM *)PairArg(x);
+ x+=2;
+ switch((int)i)
+ {
+ case 1:strcat(buffer,"$1");
+ break;
+ case 3:strcat(buffer,"$2");
+ break;
+ case 5:strcat(buffer,"$ME");
+ break;
+ case 7:strcat(buffer,"$AC");
+ break;
+ case 9:strcat(buffer,"$RM");
+ break;
+ default:
+ if(!IsUnique(32766,
+ i->it_Adjective,
+ i->it_Noun))
+ sprintf(buffer+strlen(buffer),"#%d ",ItemNumber(32766,
+ i));
+ if(i->it_Adjective!=-1)
+ {
+ strcat(buffer,FindWText(i->it_Adjective,WD_ADJ));
+ strcat(buffer," ");
+ }
+ else
+ strcat(buffer,"ANY ");
+ strcat(buffer,FindWText(i->it_Noun,WD_NOUN));
+ }
+ break;
+ case '$':;
+ case 'T':t=(TPTR )PairArg(x);
+ x+=2;
+ if(t==(TPTR )1)
+ strcat(buffer,"{$}");
+ else
+ {
+ if(t==(TPTR) 3)
+ strcat(buffer,"{$2}");
+ else
+ {
+ strcat(buffer,"{");
+ strcat(buffer,TextOf(t));
+ strcat(buffer,"}");
+ }
+ }
+ break;
+ case 'F':strcat(buffer,GetFlagName(*x++));
+ break;
+ case 'N':;
+ case 'W':;
+ case 'w':; /* THIS IS WRONG FOR NOW */
+ case 'Z':;
+ case 'B':strcat(buffer,NumText(*x++));
+ break;
+ case 'p':strcat(buffer,FindWText((short)*x++,WD_PREP));
+ break;
+ case 'v':strcat(buffer,FindWText((short)*x++,WD_VERB));
+ break;
+ case 'a':strcat(buffer,FindWText((short)*x++,WD_ADJ));
+ break;
+ case 'n':strcat(buffer,FindWText((short)*x++,WD_NOUN));
+ break;
+ case 'C':strcat(buffer,GetClassName(*x++));
+ break;
+ case 'c':strcat(buffer,CBitName(*x++));
+ break;
+ case 'O':strcat(buffer,OBitName(*x++));
+ break;
+ case 'R':strcat(buffer,RBitName(*x++));
+ break;
+ case 'P':strcat(buffer,PBitName(*x++));
+ break;
+ case 't':tmp=FindTable(*x);
+ if(tmp&&
+ strcmp(TextOf(tmp->tb_Name),
+ "(unset)"))
+ strcat(buffer,
+ TextOf(tmp->tb_Name));
+ else
+ strcat(buffer,NumText(*x));
+ x++;
+ break;
+ default:
+ Error("Invalid Entry In Cnd_Table");
+ }
+ strcat(buffer," ");
+ ct++;
+ }
+ }
+}
+
diff --git a/CondCode.c b/CondCode.c
new file mode 100644
index 0000000..ef04756
--- /dev/null
+++ b/CondCode.c
@@ -0,0 +1,646 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+
+Module "Conditions";
+Version "1.20";
+Author "Alan Cox";
+
+/*
+ * Condition Code Logic For Table Drivers
+ *
+ * 1.15 Up to date for 5.06 release
+ * 1.16 Fixed nasty order dependancies in condition logic
+ * Added specific bit flag entries
+ * 1.17 5.07 version with the extra types (table etc)
+ * 1.18 5.12 Stuff added to tables
+ * 1.19 5.20 RWHO added
+ * 1.20 5.20 Added FORKDUMP
+ * 1.21 5.21 Added PROCOBJECT PROCSUBJECT PROCDAEMON
+ */
+
+char *Cnd_Table[]=
+{
+ "I AT",
+ "I NOTAT",
+ "I PRESENT",
+ "I ABSENT",
+ "I WORN",
+ "I NOTWORN",
+ "I CARRIED",
+ "I NOTCARR",
+ "II ISAT",
+ "II ISNOTAT",
+ "II ISBY",
+ "II ISNOTBY",
+ "F ZERO",
+ "F NOTZERO",
+ "FN EQ",
+ "FN NOTEQ",
+ "FN GT",
+ "FN LT",
+ "FF EQF",
+ "FF NOTEQF",
+ "FF LTF",
+ "FF GTF",
+ "II ISIN",
+ "II ISNOTIN",
+ "a ADJ1",
+ "a ADJ2",
+ "n NOUN1",
+ "n NOUN2",
+ "p PREP",
+ "N CHANCE",
+ "I ISPLAYER",
+ "I ISUSER",
+ "I ISROOM",
+ "I ISOBJECT",
+ "IN STATE",
+ "IP PFLAG",
+ "IO OFLAG",
+ "II CANPUT",
+ "IR RFLAG",
+ "N LEVEL",
+ " IFDEAF",
+ " IFBLIND",
+ " ARCH",
+ "I GET",
+ "I DROP",
+ "I REMOVE",
+ "I WEAR",
+ "I CREATE",
+ "I DESTROY",
+ "I PUTO",
+ "II SWAP",
+ "II PLACE",
+ "II PUTIN",
+ "II TAKEOUT",
+ "IBF COPYOF",
+ "FIB COPYFO",
+ "FF COPYFF",
+ "N WHATO",
+ "NI GETO",
+ "IF WEIGH",
+ "F SET",
+ "F CLEAR",
+ "IP PSET",
+ "IP PCLEAR",
+ "FN LET",
+ "FN ADD",
+ "FN SUB",
+ "FF ADDF",
+ "FF SUBF",
+ "FN MUL",
+ "FN DIV",
+ "FF MULF",
+ "FF DIVF",
+ "FN MOD",
+ "FF MODF",
+ "FN RANDOM",
+ "F MOVE",
+ "I GOTO",
+ "IN WEIGHT",
+ "IN SIZE",
+ "IO OSET",
+ "IO OCLEAR",
+ "IR RSET",
+ "IR RCLEAR",
+ "II PUTBY",
+ "I INC",
+ "I DEC",
+ "IN SETSTATE",
+ "T PROMPT",
+ "F PRINT",
+ " SCORE",
+ "T MESSAGE",
+ "T MSG",
+ "I LISTOBJ",
+ "I LISTAT",
+ " INVEN",
+ " DESC",
+ "T END",
+ " DONE",
+ " NOTDONE",
+ " OK",
+ " ABORT",
+ " SAVE",
+ "T PARSE",
+ " NEWTEXT",
+ "t PROCESS",
+ "ICN DOCLASS",
+ "II GIVE",
+ "INT SETUT",
+ "ITN DOESACTION",
+ "ITIN DOESTO",
+ "ITIN DOESTOPLAYER",
+ "IN POBJ",
+ "IN PLOC",
+ "I PNAME",
+ "I PCNAME",
+ "Ivnn DAEMON",
+ "vnn ALLDAEMON",
+ "Ivnn HDAEMON",
+ "Nt WHEN",
+ "IT SETNAME",
+ "INN DUP",
+ " FRIG",
+ "N POINTS",
+ "N HURT",
+ "N CURED",
+ "T KILLOFF",
+ "v AUTOVERB",
+ " IF1",
+ " IF2",
+ "T BUG",
+ "T TYPO",
+ "FN NARG",
+ "I ISME",
+ "TN BROADCAST",
+ "IT ISCALLED",
+ "II IS",
+ "I SETME",
+ " PRONOUNS",
+ "N CHANCELEV",
+ "I EXITS",
+ " PWCHANGE",
+ "I SNOOP",
+ "NI UNSNOOP",
+ "IN GETUT",
+ "TTT CAT",
+ "T BECOME",
+ "I ALIAS",
+ " UNALIAS",
+ "N FIELD",
+ "N NEEDFIELD",
+ "N UNVEIL",
+ "N DEBUG",
+ "IF GETSCORE",
+ "IF GETSTR",
+ "IF GETLEV",
+ "IF SETSCORE",
+ "IF SETLEV",
+ "IF SETSTR",
+ "T SHELL",
+ "Ic CSET",
+ "Ic CCLEAR",
+ "Ic CFLAG",
+ "I CANSEE",
+ " RESCAN",
+ "vnnN MEANS",
+ "Ivnn TREEDAEMON",
+ "T SETIN",
+ "T SETOUT",
+ "T SETHERE",
+ "IF CANGOTO",
+ " MOBILES",
+ " DIR",
+ " ROOMS",
+ "Ivnn CHAINDAEMON",
+ "IF CANGOBY",
+ "INI SETIFLAG",
+ "INN GETIFLAG",
+ "IN CLEARIFLAG",
+ "II [FIGHT]", /* Unused */
+ "INN WHERETO",
+ "IIF DOOREXIT",
+ "I CANMOVEROPE",
+ "II PLACEROPE",
+ "I ISROPE",
+ "I ISTIED",
+ "IN ROPEPREV",
+ "IN ROPENEXT",
+ "II TIE",
+ "II UNTIE",
+ "II JOIN",
+ "II CUTROPE",
+ "IIN DISTANCE",
+ "IIN WHICHWAY",
+ "IC CLASSAT",
+ "II DUPOF",
+ "IN MASTEROF",
+ "IN TIEDTO",
+ "$ COMMENT",
+ "vanpan COMVOCAB",
+ "vIpI COMMAND",
+ "T BSXSCENE",
+ "NNT BSXOBJECT",
+ " NOT",
+ " IFDARK",
+ "IN VISIBILITY",
+ "IN GETPARENT",
+ "IN GETNEXT",
+ "IN GETCHILDREN",
+ "N PEXIT",
+ "INTTT SETDESC",
+ "ITTT SETLONG",
+ "ITTT SETSHORT",
+ "I GETLONG",
+ "I GETSHORT",
+ "IN GETDESC",
+ "I GETNAME",
+ " SWAT",
+ "F FLAT",
+ "NN FINDMASTER",
+ "INN NEXTMASTER",
+ "INN FINDIN",
+ "INNN NEXTIN",
+ "TN LENTEXT",
+ "I PROCSUBJECT",
+ "I PROCOBJECT",
+ "I PROCDAEMON",
+ "IN GETSUPER",
+ "II SETSUPER",
+ "II MEMBER",
+ " ",
+ " CLS",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ " ",
+ "IC ISCLASS",
+ "TT SUBSTR",
+ "I GETIN",
+ "I GETOUT",
+ "I GETHERE",
+ "TTT LOG",
+ "IC SETCLASS",
+ "IC UNSETCLASS",
+ "FN BITCLEAR",
+ "FN BITSET",
+ "FN BITTEST",
+ "F SPRINT",
+ "NNNIIT USER",
+ "NI SETI",
+ "Ivnn CDAEMON",
+ "T DELETE",
+ "TI ULOAD",
+ "TI USAVE",
+ "TNN FLOAD",
+ "TNN FSAVE",
+ "IF GETVIS",
+ "IT MESSAGETO",
+ "IT MSGTO",
+ "TTTT RWHOINIT",
+ " RWHODOWN",
+ "TT RWHOLOGIN",
+ "T RWHOLOGOUT",
+ " RWHOPING",
+ "INI SETEXIT",
+ "IN DELEXIT",
+ "INN GETEXIT",
+ "T FORKDUMP",
+ NULL
+};
+
+/* ARGUMENT CODING:
+ * N=NUMBER I=ITEM p=PREPWORD n=NOUNWORD a=ADJWORD
+ * F=FLAG(0-511) B=BIT(0-15) $=COMMENT TEXT R=RBIT
+ * P=PBIT O=OBIT C=CLASS c=CBIT t=table
+ *
+ * Thus an action needing a text an item and a noun would be
+ * TIN<5 spaces>ACTIONNAME
+ *
+ * And would call ArgText(),ArgItem(), and ArgNum() to get its args
+ * Note: ArgText returns a TXT pointer - to get the string use
+ * TextOf(ArgText()).
+ */
+
+/*
+ * Find an action/condition by name
+ */
+
+int FindCnd(x)
+char *x;
+{
+ int i=0;
+ while(Cnd_Table[i])
+ {
+ if(stricmp(x,Cnd_Table[i]+8)==0)
+ return(i);
+ i++;
+ }
+ return(-1);
+}
+
+/*
+ * Condition Evaluators
+ */
+
+int Cnd_At(void)
+{
+ return(O_PARENT(Me())==ArgItem());
+}
+
+int Cnd_NotAt(void)
+{
+ return(O_PARENT(Me())!=ArgItem());
+}
+
+int Cnd_Present(void)
+{
+ ITEM *i=ArgItem();
+ if(O_PARENT(i)==Me())
+ return(1);
+ if(O_PARENT(i)==O_PARENT(Me()))
+ return(1);
+ return(0);
+}
+
+int Cnd_Absent(void)
+{
+ return(1-Cnd_Present());
+}
+
+int Cnd_Worn(void)
+{
+ ITEM *i=ArgItem();
+ if(!IsObject(i))
+ return(0);
+ if(O_PARENT(i)!=Me())
+ return(0);
+ if(ObjectOf(i)->ob_Flags&OB_WORN)
+ return(1);
+ return(0);
+}
+
+int Cnd_NotWorn(void)
+{
+ return(1-Cnd_Worn());
+}
+
+int Cnd_Carried(void)
+{
+ return(O_PARENT(ArgItem())==Me());
+}
+
+int Cnd_NotCarr(void)
+{
+ return(O_PARENT(ArgItem())!=Me());
+}
+
+int Cnd_IsAt(void)
+{
+ ITEM *i=ArgItem();
+ return(O_PARENT(i)==ArgItem());
+}
+
+int Cnd_IsNotAt(void)
+{
+ ITEM *i=ArgItem();
+ return(O_PARENT(i)!=ArgItem());
+}
+
+int Cnd_IsBy(void)
+{
+ ITEM *i=ArgItem();
+ return(O_PARENT(i)==O_PARENT(ArgItem()));
+}
+
+int Cnd_IsNotBy(void)
+{
+ ITEM *i=ArgItem();
+ return(O_PARENT(i)!=O_PARENT(ArgItem()));
+}
+
+int Cnd_Zero(void)
+{
+ return(GetFlag(ArgNum())==0);
+}
+
+int Cnd_NotZero(void)
+{
+ return(GetFlag(ArgNum())!=0);
+}
+
+int Cnd_Eq(void)
+{
+ int v=ArgNum();
+ return(GetFlag(v)==ArgNum());
+}
+
+int Cnd_NotEq(void)
+{
+ int v=ArgNum();
+ return(GetFlag(v)!=ArgNum());
+}
+
+int Cnd_Gt(void)
+{
+ int v=ArgNum();
+ return(GetFlag(v)>ArgNum());
+}
+
+int Cnd_Lt(void)
+{
+ int v=ArgNum();
+ return(GetFlag(v)<ArgNum());
+}
+
+int Cnd_EqF(void)
+{
+ int v=ArgNum();
+ return(GetFlag(v)==GetFlag(ArgNum()));
+}
+
+int Cnd_NeF(void)
+{
+ int v=ArgNum();
+ return(GetFlag(v)!=GetFlag(ArgNum()));
+}
+
+int Cnd_LtF(void)
+{
+ int v=ArgNum();
+ return(GetFlag(v)<GetFlag(ArgNum()));
+}
+
+int Cnd_GtF(void)
+{
+ int v=ArgNum();
+ return(GetFlag(v)>GetFlag(ArgNum()));
+}
+
+int Cnd_IsIn(void)
+{
+ ITEM *i=ArgItem();
+ return(Contains(i,ArgItem()));
+}
+
+int Cnd_IsNotIn(void)
+{
+ return(1-Cnd_IsIn());
+}
+
+int Cnd_Adj1(void)
+{
+ return(ArgWord()==Adj1);
+}
+
+int Cnd_Adj2(void)
+{
+ return(ArgWord()==Adj2);
+}
+
+int Cnd_Noun1(void)
+{
+ return(ArgWord()==Noun1);
+}
+
+int Cnd_Noun2(void)
+{
+ return(ArgWord()==Noun2);
+}
+
+int Cnd_Prep(void)
+{
+ return(ArgWord()==Prep);
+}
+
+int Cnd_Chance(void)
+{
+ return(RandPerc()<ArgNum());
+}
+
+int Cnd_IsPlayer(void)
+{
+ return(IsPlayer(ArgItem()));
+}
+
+int Cnd_IsUser(void)
+{
+ return(UserOf(ArgItem())!=-1);
+}
+
+int Cnd_IsRoom(void)
+{
+ return(IsRoom(ArgItem()));
+}
+
+int Cnd_IsObject(void)
+{
+ return(IsObject(ArgItem()));
+}
+
+int Cnd_State(void)
+{
+ ITEM *i=ArgItem();
+ return(O_STATE(i)==ArgNum());
+}
+
+int Cnd_PFlag(void)
+{
+ PLAYER *p=PlayerOf(ArgItem());
+ if(p==NULL)
+ {
+ ArgNum();
+ return(0);
+ }
+ return(((p->pl_Flags&(1<<ArgNum())))?1:0);
+}
+
+int Cnd_OFlag(void)
+{
+ OBJECT *o=ObjectOf(ArgItem());
+ if(o==NULL)
+ {
+ ArgNum();
+ return(0);
+ }
+ return(((o->ob_Flags&(1<<ArgNum())))?1:0);
+}
+
+int Cnd_RFlag(void)
+{
+ ROOM *r=RoomOf(ArgItem());
+ if(r==NULL)
+ {
+ ArgNum();
+ return(0);
+ }
+ return(((r->rm_Flags&(1<<ArgNum())))?1:0);
+}
+
+int Cnd_CFlag(void)
+{
+ CONTAINER *c=ContainerOf(ArgItem());
+ if(c==NULL)
+ {
+ ArgNum();
+ return(0);
+ }
+ return(((c->co_Flags&(1<<ArgNum())))?1:0);
+}
+
+int Cnd_CanPut(void)
+{
+ ITEM *a=ArgItem();
+ return(((CanPlace(a,ArgItem()))==0)?1:0);
+}
+
+int Cnd_Level(void)
+{
+ return(LevelOf(Me())>=ArgNum());
+}
+
+int Cnd_IfDeaf(void)
+{
+ PLAYER *p=PlayerOf(Me());
+ if(p==NULL)
+ return(0);
+ return(p->pl_Flags&PL_DEAF);
+}
+
+int Cnd_IfBlind(void)
+{
+ PLAYER *p=PlayerOf(Me());
+ if(p==NULL)
+ return(0);
+ return(p->pl_Flags&PL_BLIND);
+}
+
+int Cnd_Arch(void)
+{
+ return(ArchWizard(Me()));
+}
+
+int Cnd_Is(void)
+{
+ return(ArgItem()==ArgItem());
+}
+
+int Cnd_ChanceLev(void)
+{
+ return(RandPerc()<(ArgNum()*LevelOf(Me())));
+}
+
+int Cnd_CanSee(void)
+{
+ return(CanSee(LevelOf(Me()),ArgItem()));
+}
+
+int Cnd_IsClass(void)
+{
+ ITEM *i=ArgItem();
+ short cm=1<<ArgNum();
+ if(i->it_Class&cm)
+ return(1);
+ else
+ return(0);
+}
+
+
diff --git a/ContCommand.c b/ContCommand.c
new file mode 100644
index 0000000..ec47b8d
--- /dev/null
+++ b/ContCommand.c
@@ -0,0 +1,151 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Commands To Do With Containers
+ *
+ * 1.00 AGC Original Release
+ * 1.01 AGC Forgot to make it use NameCFlag type stuff - only noticed for 5.21.4
+ */
+
+#include "System.h"
+
+Module "Container Commands";
+Version "1.01";
+Author "----*(A)";
+
+void Cmd_ContainerShow(i)
+ITEM *i;
+{
+ ITEM *a;
+ CONTAINER *c;
+ int ct=0;
+
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Try EXAMINE.\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ c=ContainerOf(a);
+ if(c==NULL)
+ {
+ SendItem(i,"%s is not a container.\n",CNameOf(a));
+ return;
+ }
+ SendItem(i,"Container Name : %s\n",CNameOf(a));
+ SendItem(i,"Volume: %d\n",c->co_Volume);
+
+ while(ct<16)
+ {
+ if(c->co_Flags&(1<<ct))
+ SendItem(i,"%s ",CBitName(ct));
+ else
+ if(strcmp(CBitName(ct),"{unset}"))
+ SendItem(i,"-%s ",CBitName(ct));
+ ct++;
+ }
+ SendItem(i,"\n");
+}
+
+void Cmd_SetCFlag(i)
+ITEM *i;
+{
+ ITEM *a;
+ CONTAINER *c;
+ int flag;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No can do....\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ c=ContainerOf(a);
+ if(c==NULL)
+ {
+ SendItem(i,"%s is not a container.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ while(GetParsedWord())
+ {
+ if(!strlen(WordBuffer))
+ {
+ SendItem(i,"What flag though ?\n");
+ return;
+ }
+ if(*WordBuffer=='-')
+ {
+ flag=FindCBit(WordBuffer+1);
+ if(flag==-1)
+ {
+ SendItem(i,"Unknown flag %s.\n",WordBuffer+1);
+ return;
+ }
+ c->co_Flags&=~(1<<flag);
+ }
+ else
+ {
+ flag=FindCBit(WordBuffer);
+ if(flag==-1)
+ {
+ SendItem(i,"Unknown flag %s.\n",WordBuffer);
+ return;
+ }
+ c->co_Flags|=(1<<flag);
+
+ }
+ }
+}
+
+void Cmd_SetVolume(i)
+ITEM *i;
+{
+ int n;
+ ITEM *a;
+ CONTAINER *c;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ c=ContainerOf(a);
+ if(c==NULL)
+ {
+ SendItem(i,"%s is not a container.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Bad Volume Value.\n");
+ return;
+ }
+ c->co_Volume=n;
+}
+
+
diff --git a/Container.c b/Container.c
new file mode 100644
index 0000000..d1088e5
--- /dev/null
+++ b/Container.c
@@ -0,0 +1,171 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Container Control
+ *
+ * 1.00 AGC Container Logic
+ * 1.01 AGC Added recursion checks
+ * 1.02 AGC Fixed weight limit on player bug
+ */
+
+#include "System.h"
+
+Module "Containers";
+Version "1.02";
+Author "Alan Cox";
+
+
+/*
+ * Find the weight of an item's contents
+ */
+
+
+static int WeightRec(x,d)
+ITEM *x;
+int d;
+{
+ int n=WeightOf(x);
+ register ITEM *o;
+ if(d>32)
+ return(0); /* Depth too great */
+ o=O_CHILDREN(x);
+ while(o)
+ {
+ n+=WeightRec(o,d+1);
+ o=O_NEXT(o);
+ }
+ return(n);
+}
+
+
+int WeighUp(x)
+ITEM *x;
+{
+ return(WeightRec(x,0));
+}
+
+/*
+ * Return the weight of an item alone, not including its contents
+ */
+
+int WeightOf(x)
+ITEM *x;
+{
+ OBJECT *o=ObjectOf(x);
+ PLAYER *p=PlayerOf(x);
+ if(o)
+ return(o->ob_Weight);
+ if(p)
+ return(p->pl_Weight);
+ return(0);
+}
+
+/*
+ * Sort out the size of an items contents
+ */
+
+static int SizeRec(x,d)
+ITEM *x;
+int d;
+{
+ ITEM *o;
+ int n=0;
+ o=O_CHILDREN(x);
+ if(d>32)
+ return(0);
+ while(o)
+ {
+ n+=SizeOfRec(o,d);
+ o=O_NEXT(o);
+ }
+ return(n);
+}
+
+int SizeContents(x)
+ITEM *x;
+{
+ return(SizeRec(x,0));
+}
+
+/*
+ * Calculate size of an item, allowing for soft flags etc.
+ */
+
+int SizeOfRec(o,d)
+ITEM *o;
+int d;
+{
+ OBJECT *a=ObjectOf(o);
+ PLAYER *b=PlayerOf(o);
+ CONTAINER *c=ContainerOf(o);
+ if(((c)&&(c->co_Flags&CO_SOFT))||(!c))
+ {
+ if(a)
+ return(a->ob_Size+SizeRec(o,d+1));
+ if(b)
+ return(b->pl_Size+SizeRec(o,d+1));
+ return(SizeRec(o,d+1));
+ }
+ if(a)
+ return(a->ob_Size);
+ if(b)
+ return(b->pl_Size);
+ return(0);
+}
+/*
+ * CanPlace: BUGS. CanPlace only enforces weight limiting in the direct
+ * parent. Thus an item placed into a container a player holds directly will
+ * fail. Normal operations are such that a player must hold an item to do this.
+ * Be aware of the limitations in special cases. If you need to stick entries
+ * in the tables of the form NOT CANPLACE <item> $ME MESSAGE {Cant carry it}
+ * when moving from item->item through the player
+ */
+
+int CanPlace(x,y)
+ITEM *x;
+ITEM *y;
+{
+ ITEM *z=O_PARENT(x);
+ CONTAINER *c=ContainerOf(y);
+ PLAYER *p=PlayerOf(y);
+ int cap;
+ int wt;
+ if((c==NULL)&&(p==NULL))
+ return(0); /* Fits Fine */
+ XPlace(x,NULL); /* Avoid disturbing figures */
+ if(c)
+ cap=SizeContents(y);
+ wt=WeighUp(y);
+ XPlace(x,z);
+ if(c)
+ {
+ cap=c->co_Volume-cap;
+ cap-=SizeOfRec(x,0); /* - size of item going in */
+ if(cap<0)
+ return(-1); /* Too big to fit */
+ }
+ if(p)
+ if(wt+WeighUp(x)-WeightOf(y)>p->pl_Level*10+400)
+ return(-2); /* Too heavy */
+ if(p)
+ {
+ short ct=0;
+ ITEM *step=O_CHILDREN(y);
+ while(step)
+ {
+ ct++;
+ step=O_NEXT(step);
+ }
+ if(ct>9)
+ return(-3); /* Too much */
+ }
+ return(0);
+}
diff --git a/Daemons.c b/Daemons.c
new file mode 100644
index 0000000..926c249
--- /dev/null
+++ b/Daemons.c
@@ -0,0 +1,159 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Daemon Actions
+ *
+ *
+ * 1.00 AGC Original Release
+ * 1.10 AGC Added TreeDaemon and ChainDaemons
+ * 1.11 AGC Added CDaemon
+ * 1.12 AGC Private Daemon Table Handling
+ *
+ */
+
+#include "System.h"
+#include "User.h"
+extern USER UserList[];
+
+
+Module "Daemons";
+Version "1.12";
+Author "Alan Cox";
+
+/*
+ * Actually carry out a DAEMON or part thereof
+ */
+
+void RunDaemon(i,v,n1,n2)
+ITEM *i;
+int v,n1,n2;
+{
+ int vsv=Verb,n1sv=Noun1,n2sv=Noun2; /* Stack the words */
+ Verb=v; /* Set word to DAEMON words */
+ Noun1=n1;
+ Noun2=n2;
+ UserDaemon(i); /* Run table - see tabledriver.c */
+ Verb=vsv;
+ Noun1=n1sv;
+ Noun2=n2sv; /* Restore them */
+}
+
+/* NOTE: Daemons are defined to always execute before anything else
+ * that may be pending. They can be nested to a degree depending on
+ * system stack - Stack Overflow will result if this occurs
+ * {$} is defined to remain constant through all daemons.
+ * Any item may be the root of a Daemon action, and becomes Me() for
+ * that duration.
+ */
+
+/* Daemon Drivers: There are three current group drivers:
+ * HDAEMON,DAEMON,ALLDAEMON
+ * HDAEMON and ALLDAEMON affect ONLY Users!, this is forced by the
+ * CPU power of the system, which would virtually die on a literal
+ * ALLDAEMON of a big game. Like earlier AberMuds this doesn't affect
+ * attached mobiles, as these become Users while attached. It does
+ * however affect snooped items. An identical affect will be observed
+ * by DoesAction() and similar calls. Later releases of the kernel may
+ * make snooped items users, and redesign the UserList to be expanding
+ *
+ * 1.1: New Daemons TREEDAEMON, affects all contents of item, and CHAINDAEMON
+ * affects all chained items of item, but not item itself. TREEDAEMON
+ * affects only users.
+ */
+
+/*
+ * A DAEMON to every user in the game
+ */
+void AllDaemon(v,n1,n2)
+int v,n1,n2;
+{
+ int ct=0;
+ while(ct<MAXUSER)
+ {
+ if((UserList[ct].us_Port)&&(UserList[ct].us_Item))
+ {
+ RunDaemon(UserList[ct].us_Item,v,n1,n2);
+ }
+ ct++;
+ }
+}
+
+/*
+ * A DAEMON to every user present
+ */
+void HDaemon(i,v,n1,n2)
+ITEM *i;
+int v,n1,n2;
+{
+ int ct=0;
+ while(ct<MAXUSER)
+ {
+ if((UserList[ct].us_Port)&&(UserList[ct].us_Item))
+ {
+ if(O_PARENT(UserList[ct].us_Item)==O_PARENT(i))
+ RunDaemon(UserList[ct].us_Item,v,n1,n2);
+ }
+ ct++;
+ }
+}
+
+/*
+ * DAEMON to everything within an item (every USER)
+ */
+
+void TreeDaemon(i,v,n1,n2)
+ITEM *i;
+int v,n1,n2;
+{
+ int ct=0;
+ while(ct<MAXUSER)
+ {
+ if((UserList[ct].us_Port)&&(UserList[ct].us_Item))
+ {
+ if(Contains(i,UserList[ct].us_Item))
+ RunDaemon(UserList[ct].us_Item,v,n1,n2);
+ }
+ ct++;
+ }
+}
+
+/*
+ * Daemon to everything chained to current item
+ */
+
+void ChainDaemon(i,v,n1,n2)
+ITEM *i;
+int v,n1,n2;
+{
+ CHAIN *c=(CHAIN *)FindSub(i,KEY_CHAIN);
+ while(c)
+ {
+ RunDaemon(c->ch_Chained,v,n1,n2);
+ c=(CHAIN *)NextSub((SUB *)c,KEY_CHAIN);
+ }
+}
+
+void CDaemon(i,v,n1,n2)
+ITEM *i;
+int v,n1,n2;
+{
+ int ct=0;
+ while(ct<MAXUSER)
+ {
+ if((UserList[ct].us_Port)&&(UserList[ct].us_Item))
+ {
+ if(O_PARENT(UserList[ct].us_Item)==i)
+ RunDaemon(UserList[ct].us_Item,v,n1,n2);
+ }
+ ct++;
+ }
+}
+
diff --git a/DarkLight.c b/DarkLight.c
new file mode 100644
index 0000000..fcf1621
--- /dev/null
+++ b/DarkLight.c
@@ -0,0 +1,100 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Dark/Light model
+ *
+ * 1.00 Original Version
+ * 1.01 ANSIfied
+ */
+
+#include "System.h"
+
+Module "DarkLight";
+Author "Alan Cox";
+Version "1.01";
+
+
+/*
+ * Decide if item 'i' is in the dark.
+ */
+
+int IsDarkFor(ITEM *i)
+{
+ ITEM *p;
+ short rct=5;
+ if((p=O_PARENT(i))==NULL)
+ {
+/*
+ * A question for the philosophers - is nothingness dark or not.....
+ * For game purposes we say it isn't, and the player gets 'The void' etc
+ */
+ return(1);
+ }
+/*
+ * We go up the tree first looking for higher lights
+ */
+reup: if(O_PARENT(p))
+ {
+ if(ContainerOf(p))
+ {
+ if((ContainerOf(p)->co_Flags&CO_SEETHRU)||
+ ((ContainerOf(p)->co_Flags&CO_CLOSES)&&(!O_STATE(p))))
+ {
+ p=O_PARENT(p);
+ if(--rct) /* MAX 5 Levels of upping */
+ goto reup;
+ }
+ return(RecCheckDark(p,(short)0));
+ }
+ else
+ {
+ p=O_PARENT(p);
+ if(--rct)
+ goto reup;
+ }
+ }
+ return(RecCheckDark(p,(short)0));
+}
+
+
+/*
+ * Scan recursively downwards looking for light sources
+ */
+
+int RecCheckDark(ITEM *item, short depth)
+{
+ ROOM *r;
+ OBJECT *o;
+ ITEM *x;
+ CONTAINER *c;
+ if(depth>31) /* Recursion Limit of 32 */
+ return(1);
+ r=RoomOf(item);
+ if((r)&&((r->rm_Flags&RM_DARK)==0))
+ return(0); /* lit by room - easy case */
+ o=ObjectOf(item);
+ if((o)&&(IsLit(item)))
+ return(0); /* Do we light it up ?*/
+ x=O_CHILDREN(item);
+ while(x) /* See if the contents do */
+ {
+ c=ContainerOf(x);
+ if((c)&&(c->co_Flags&CO_CLOSES)&&(O_STATE(x)==0))
+ goto l2; /* Open so can see in */
+ if((c)&&((c->co_Flags&CO_SEETHRU)==0))
+ goto nx; /* Opaque item */
+l2: if(RecCheckDark(x,(short)(depth+1))==0)
+ return(0); /* Light found */
+nx: x=O_NEXT(x);
+ }
+ return(1); /* REALLY DARK */
+}
+
diff --git a/Duplicator.c b/Duplicator.c
new file mode 100644
index 0000000..ca09135
--- /dev/null
+++ b/Duplicator.c
@@ -0,0 +1,350 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+
+/*
+ * 1.00 AGC Created File
+ * 1.01 AGC Added IOH to duplicatables
+ * 1.02 AGC Fixed IOH dup
+ * 1.03 AGC Fixed CondExit dup
+ * 1.04 AGC Knows about tables and superclassing
+ * 1.05 AGC ANSIfication
+ */
+
+Module "Duplicator";
+Version "1.05";
+Author "Alan Cox";
+
+/*
+ * This routine is basically a software Xerox machine, one item goes in
+ * and two of them come out. The copy can be either a true copy or one
+ * which will be destroyed later.
+ */
+
+int Clone_Room(ITEM *i, ITEM *j)
+{
+ ROOM *r,*s;
+ if(MakeRoom(i)==-1)
+ return(-1);
+ r=(ROOM *)FindSub(i,KEY_ROOM);
+ s=(ROOM *)FindSub(j,KEY_ROOM);
+ if((!r)||(!s))
+ Error("CloneRoom: Not Room!");
+ FreeText(r->rm_Short);
+ FreeText(r->rm_Long);
+ r->rm_Flags=s->rm_Flags;
+ r->rm_Short=AllocText(TextOf(s->rm_Short));
+ r->rm_Long=AllocText(TextOf(s->rm_Long));
+ return(0);
+}
+
+int Clone_Object(ITEM *i, ITEM *j)
+{
+ short x=0;
+ OBJECT *r,*s;
+ if(MakeObject(i)==-1)
+ return(-1);
+ r=(OBJECT *)FindSub(i,KEY_OBJECT);
+ s=(OBJECT *)FindSub(j,KEY_OBJECT);
+ if((!r)||(!s))
+ Error("CloneObject: Not Object!");
+ FreeText(r->ob_Text[0]);
+ FreeText(r->ob_Text[1]);
+ FreeText(r->ob_Text[2]);
+ FreeText(r->ob_Text[3]);
+ r->ob_Flags=s->ob_Flags;
+ r->ob_Size=s->ob_Size;
+ r->ob_Weight=s->ob_Weight;
+ while(x<4)
+ {
+ r->ob_Text[x]=AllocText(TextOf(s->ob_Text[x]));
+ x++;
+ }
+ return(0);
+}
+
+int Clone_Player(ITEM *i, ITEM *j)
+{
+ PLAYER *r,*s;
+ if(MakePlayer(i)==-1)
+ return(-1);
+ r=(PLAYER *)FindSub(i,KEY_PLAYER);
+ s=(PLAYER *)FindSub(j,KEY_PLAYER);
+ if((!r)||(!s))
+ Error("ClonePlayer: Not Player!");
+ r->pl_Flags=s->pl_Flags;
+ r->pl_UserKey=-1; /* Never DUP user handles! */
+ r->pl_Size=s->pl_Size;
+ r->pl_Weight=s->pl_Weight;
+ r->pl_Level=s->pl_Level;
+ r->pl_Score=s->pl_Score;
+ r->pl_Strength=s->pl_Strength;
+ return(0);
+}
+
+int Clone_GenExit(ITEM *i, ITEM *j)
+{
+ short ct=0;
+ GENEXIT *r,*s;
+ if(MakeGenExit(i)==-1)
+ return(-1);
+ r=(GENEXIT *)FindSub(i,KEY_GENEXIT);
+ s=(GENEXIT *)FindSub(j,KEY_GENEXIT);
+ if((!r)||(!s))
+ Error("CloneGenExit: Not GenExit!");
+ while(ct<12)
+ {
+ r->ge_Dest[ct]=s->ge_Dest[ct];
+ if(r->ge_Dest[ct])
+ LockItem(r->ge_Dest[ct]);
+ ct++;
+ }
+ return(0);
+}
+
+int Clone_MsgExit(ITEM *i, MSGEXIT *s)
+{
+ MSGEXIT *r;
+ if((r=MakeMsgExit(i,s->me_Dest,s->me_ExitNumber,TextOf(s->me_Text)))
+ ==NULL)
+ return(-1);
+ return(0);
+}
+
+int Clone_Chain(ITEM *i, CHAIN *c)
+{
+ AddChain(i,c->ch_Chained);
+ return(0);
+}
+
+int Clone_Container(ITEM *i, CONTAINER *c)
+{
+ CONTAINER *r=BeContainer(i);
+ if(!r)
+ return(-1);
+ r->co_Volume=c->co_Volume;
+ r->co_Flags=c->co_Flags;
+ return(0);
+}
+
+int Clone_UserFlag(ITEM *i, USERFLAG *u)
+{
+ short ct=0;
+ while(ct<8)
+ {
+ SetUserFlag(i,ct,u->uf_Flags[ct]);
+ ct++;
+ }
+ ct=0;
+ while(ct<8)
+ {
+ SetUserItem(i,ct,u->uf_Items[ct]);
+ ct++;
+ }
+ return(0);
+}
+
+int Clone_UserText(ITEM *i, ITEM *j)
+{
+ int ct=0;
+ while(ct<8)
+ {
+ SetUText(j,ct,GetUText(i,ct));
+ ct++;
+ }
+ return(0);
+}
+
+int Clone_Inherit(ITEM *i, INHERIT *h)
+{
+ MakeInherit(i,h->in_Master);
+ return(0);
+}
+
+ITEM *Clone_Item(ITEM *i, short f) /* 1=true dup 0=normal dup */
+{
+ DUP *d;
+ ITEM *n=CreateItem(NameOf(i),i->it_Adjective,i->it_Noun);
+ SUB *s;
+ n->it_ActorTable=i->it_ActorTable;
+ n->it_ActionTable=i->it_ActionTable;
+ n->it_State=i->it_State;
+ n->it_Class=i->it_Class;
+ n->it_Perception=i->it_Perception;
+ n->it_SubjectTable=NULL;
+ n->it_ObjectTable=NULL;
+ n->it_DaemonTable=NULL;
+ /* Cheat: We want the clone to behave as the original, but that
+ would mean copying the tables which is slow and uses lots of
+ memory. We use the new subclassing feature to cheat and make
+ the original superclass of the clones. */
+ LockItem(i);
+ n->it_Superclass=i;
+
+ if(IsRoom(i))
+ Clone_Room(n,i);
+ if(IsPlayer(i))
+ Clone_Player(n,i);
+ if(IsObject(i))
+ Clone_Object(n,i);
+ if(FindSub(i,KEY_GENEXIT))
+ Clone_GenExit(n,i);
+ s=i->it_Properties;
+ while(s)
+ {
+ switch(s->pr_Key)
+ {
+ case KEY_MSGEXIT:Clone_MsgExit(n,(MSGEXIT *)s);
+ break;
+ case KEY_CONTAINER:
+ Clone_Container(n,(CONTAINER *)s);
+ break;
+ case KEY_CHAIN:
+ Clone_Chain(n,(CHAIN *)s);
+ break;
+ case KEY_USERFLAG:
+ case KEY_USERFLAG2:
+ Clone_UserFlag(n,(USERFLAG *)s);
+ break;
+ case KEY_INHERIT:
+ Clone_Inherit(n,(INHERIT *)s);
+ break;
+ case KEY_USERTEXT:
+ Clone_UserText(i,n);
+ break;
+ case KEY_INOUTHERE:
+ SetInMsg(n,TextOf(((INOUTHERE *)s)->io_InMsg));
+ SetOutMsg(n,TextOf(((INOUTHERE *)s)->io_OutMsg));
+ SetHereMsg(n,TextOf(((INOUTHERE *)s)->io_HereMsg));
+ break;
+ case KEY_CONDEXIT:
+ MakeCondExit(n,((CONDEXIT *)s)->ce_Dest,
+ ((CONDEXIT *)s)->ce_Table,
+ ((CONDEXIT *)s)->ce_ExitNumber);
+ break;
+ }
+ s=s->pr_Next;
+ }
+ if(!f)
+ {
+ d=(DUP *)AllocSub(n,KEY_DUPED,sizeof(DUP));
+ d->du_Master=i;
+ LockItem(i);
+ }
+ return(n);
+}
+
+/*
+ * Check if an item is a copy
+ */
+
+int Duped(ITEM *x)
+{
+ if(FindSub(x,KEY_DUPED))
+ return(1);
+ return(0);
+}
+
+/*
+ * Destroy a copied item totally.
+ */
+
+int Disintegrate(ITEM *i)
+{
+ SUB *s;
+ if(!Duped(i))
+ return(-1);
+ Place(i,NULL);
+ while((s=i->it_Properties)!=NULL)
+ {
+ switch(s->pr_Key)
+ {
+ case KEY_ROOM:
+ UnRoom(i);
+ break;
+ case KEY_OBJECT:
+ UnObject(i);
+ break;
+ case KEY_PLAYER:
+ UnPlayer(i);
+ break;
+ case KEY_GENEXIT:
+ UnGenExit(i);
+ break;
+ case KEY_MSGEXIT:
+ UnMsgExit(i,(MSGEXIT *)s);
+ break;
+ case KEY_CHAIN:
+ RemoveChain(i,((CHAIN *)(s))->ch_Chained);
+ break;
+ case KEY_USERFLAG:
+ case KEY_USERFLAG2:
+ UnUserFlag(i);
+ break;
+ case KEY_CONDEXIT:
+ UnCondExit(i,(CONDEXIT *)s);
+ break;
+ case KEY_CONTAINER:
+ UnContainer(i);
+ break;
+ case KEY_INHERIT:
+ UnInherit(i);
+ break;
+ case KEY_SNOOP:;
+ case KEY_SNOOPBACK:
+ StopAllSnoops(i);
+ StopSnoopsOn(i);
+ break;
+ case KEY_DUPED:
+ UnlockItem(((DUP *)(s))->du_Master);
+ FreeSub(i,s);
+ break;
+ case KEY_USERTEXT:
+ UnUserText(i);
+ break;
+ case KEY_INOUTHERE:
+ KillIOH(i);
+ break;
+
+ default:fprintf(stderr,"SUBID=%d\n",s->pr_Key);
+ Error("Disintegrate: Prop Problem");
+ }
+ }
+ KillEventQueue(i);
+ if(FreeItem(i)<0)
+ {
+ i->it_Perception=-1; /* Queue deletion */
+ return(-1);
+ }
+ if(i==Me())
+ SetMe(NULL);
+ if(i==Item1)
+ Item1=NULL;
+ if(i==Item2)
+ Item2=NULL;
+ return(0);
+}
+
+/*
+ * Destroy every copied item in the universe
+ */
+
+void DisintegrateAll(void)
+{
+ ITEM *i=ItemList;
+ ITEM *j;
+ while(i)
+ {
+ j=i->it_MasterNext;
+ Disintegrate(i);
+ i=j;
+ }
+}
diff --git a/Editing.c b/Editing.c
new file mode 100644
index 0000000..6422726
--- /dev/null
+++ b/Editing.c
@@ -0,0 +1,1453 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+#include "User.h"
+
+/*
+ * Everything to do with editing in general
+ *
+ * 1.00 AGC Original Version
+ * 1.01 AGC Added more commands
+ * 1.02 AGC Automatic word numbers
+ * 1.03 AGC More commands
+ * 1.04 AGC More commands again
+ * 1.05 AGC 5.06 tidy up
+ * 1.06 AGC 5.07 changes - named tables etc
+ * 1.07 AGC Addword speeded up using sorted word lists
+ * 1.08 AGC Fixed verb addition, added more info to status
+ * 1.09 AGC TabName function made globally useable.. should move file
+ * 1.10 AGC Support for Superclassing
+ */
+
+Module "Editing Routines";
+Version "1.09";
+Author "Alan Cox";
+
+
+extern USER UserList[];
+
+char CmdBuffer[512]; /* No longer static - shared by BSX commands */
+
+
+void Cmd_Exorcise(i)
+ITEM *i;
+{
+ ITEM *j=FindSomething(i,O_PARENT(i));
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Huh ?\n");
+ return;
+ }
+ if(!j)
+ {
+ SendItem(i,"What is that ?\n");
+ return;
+ }
+ if(!IsUser(j)&&IsPlayer(j))
+ {
+ SendItem(i,"You can only exorcise users.\n");
+ return;
+ }
+ if(IsPlayer(j))
+ {
+ if(UserList[UserOf(j)].us_Item!=j)
+ {
+ SendItem(i,"%s has been exorcised.\n",CNameOf(j));
+ UnlockItem(j);
+ PlayerOf(j)->pl_UserKey=-1;
+ SendItem(i,"Warning: A noun for the player name may still be present.\n");
+ SendItem(i,"Character is now an ordinary mobile.\n");
+ return;
+ }
+ }
+#ifdef IS_AN_EXPERT
+ UnlockItem(j);
+ SendItem(i,"One lock broken on item.\n");
+ SendItem(i,"This may leave your universe corrupted!\n");
+#else
+ SendItem(i,"IS_AN_EXPERT option must be set to compile in Exorcise item.\n");
+#endif
+}
+
+void Cmd_Abort(ITEM *i)
+{
+ if(ArchWizard(i))
+ {
+ Log("Aborted by order of %s",TextOf(i->it_Name));
+ exit(0);
+ }
+ SendItem(i,"You look around frantically for a big red off button, but \
+can't find one!\n");
+}
+
+
+void Cmd_AddWord(ITEM *i, short type)
+{
+ int x;
+ if(ArchWizard(i))
+ {
+ if(GetWord()==(WLIST *)(-1))
+ {
+ SendItem(i,"Yes, but what word shall I add ?\n");
+ return;
+ }
+ strcpy(CmdBuffer,WordBuffer);
+ x=GetNumber();
+ if(x==-1)
+ {
+ x=FindFreeWord(type);
+ if(x==-1)
+ {
+ SendItem(i,"You must specify a code for the word.\n");
+ return;
+ }
+ }
+ if(FindInList(WordList,CmdBuffer,type))
+ {
+ SendItem(i,"'%s' is already defined.\n",CmdBuffer);
+ return;
+ }
+ AddWord(CmdBuffer,(short)x,(short)type);
+ }
+ else
+ SendItem(i,"Wouldn't it be easier to use the ones I've given you.\n");
+}
+
+int FindFreeWord(short t)
+{
+ int n=0;
+ WLIST *w;
+ if(t==WD_VERB)
+ n=200;
+ w=WordList;
+ while(w)
+ {
+ if(n<0)
+ return(-1);
+/*
+ * Since the list is sorted we can spot gaps easily.
+ */
+ if(w->wd_Type==t)
+ {
+ if(w->wd_Code>n+1)
+ return(n+1);
+ if(t!=WD_VERB||w->wd_Code>199)
+ n=w->wd_Code;
+ }
+ w=w->wd_Next;
+ }
+ return(n+1);
+}
+
+void Cmd_AddVerb(i)
+ITEM *i;
+{
+ Cmd_AddWord(i,(short)WD_VERB);
+}
+
+void Cmd_AddNoun(i)
+ITEM *i;
+{
+ Cmd_AddWord(i,(short)WD_NOUN);
+}
+
+void Cmd_AddAdj(i)
+ITEM *i;
+{
+ Cmd_AddWord(i,(short)WD_ADJ);
+}
+
+void Cmd_AddPrep(i)
+ITEM *i;
+{
+ Cmd_AddWord(i,(short)WD_PREP);
+}
+
+void Cmd_AddPronoun(i)
+ITEM *i;
+{
+ Cmd_AddWord(i,(short)WD_PRONOUN);
+}
+
+void Cmd_AddOrdinate(i)
+ITEM *i;
+{
+ Cmd_AddWord(i,WD_ORDIN);
+}
+
+char *TabName(x)
+int x;
+{
+ static char a[8];
+ TABLE *t=FindTable(x);
+ if(!t||t->tb_Name==NULL)
+ {
+ sprintf(a,"%3d",x);
+ return(a);
+ }
+ return(TextOf(t->tb_Name));
+}
+
+void Cmd_ItemInfo(i)
+ITEM *i;
+{
+ ITEM *b;
+ SUB *s;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"'I' means inventory, does 'II' mean a dicky keyboard ?\n");
+ return;
+ }
+ b=FindSomething(i,O_PARENT(i));
+ if(!b)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ SendItem(i,"Item: #%d %s\n",ItemNumber(LevelOf(i),b),CNameOf(b));
+ if(O_PARENT(b))
+ SendItem(i,"Parent: #%d %s\n",ItemNumber(LevelOf(i),O_PARENT(b)),
+ CNameOf(O_PARENT(b)));
+ else
+ SendItem(i,"Parent: None\n");
+ if(O_CHILDREN(b))
+ SendItem(i,"First Child: %s\n",CNameOf(O_CHILDREN(b)));
+ else
+ SendItem(i,"First Child: None\n");
+ if(O_NEXT(b))
+ SendItem(i,"Next Chained: %s\n",CNameOf(O_NEXT(b)));
+ else
+ SendItem(i,"Next Chained: None\n");
+ SendItem(i,"Adjective : %3d Noun: %3d Actor: %s Action: %s State: %3d\n",
+ (int)b->it_Adjective,(int)b->it_Noun,
+ TabName((int)b->it_ActorTable),
+ TabName((int)b->it_ActionTable),(int)b->it_State);
+ SendItem(i,"Perception: %3d Lock: %3d\nClasses: ",
+ (int)b->it_Perception,(int)b->it_Users);
+ ClassDescStr(i,b->it_Class);
+ SendItem(i,"\n");
+ s=b->it_Properties;
+ while(s)
+ {
+ switch(s->pr_Key)
+ {
+ case KEY_ROOM:SendItem(i,"Room");
+ break;
+ case KEY_OBJECT:SendItem(i,"Object");
+ break;
+ case KEY_PLAYER:SendItem(i,"Player");
+ break;
+ case KEY_GENEXIT:SendItem(i,"GenExit");
+ break;
+ case KEY_MSGEXIT:SendItem(i,"MsgExit");
+ break;
+ case KEY_CONDEXIT:SendItem(i,"CondExit");
+ break;
+ case KEY_CONTAINER:SendItem(i,"Container");
+ break;
+ case KEY_CHAIN:SendItem(i,"Chain -> #%d %s",
+ ItemNumber(LevelOf(i),
+ ((CHAIN *)(s))->ch_Chained),
+ CNameOf(((CHAIN *)(s))->ch_Chained));
+ break;
+ case KEY_USERFLAG:SendItem(i,"UserFlag");
+ break;
+ case KEY_BACKTRACK:SendItem(i,"BackTrack");
+ break;
+ case KEY_SNOOP:SendItem(i,"Snoop");
+ break;
+ case KEY_SNOOPBACK:
+ SendItem(i,"SnoopBack");
+ break;
+ case KEY_ROPE:
+ SendItem(i,"Rope");
+ break;
+ case KEY_DUPED:
+ SendItem(i,"Dup of %s",
+ CNameOf(((DUP *)(s))->du_Master));
+ break;
+ case KEY_TIECHAIN:
+ SendItem(i,"Tied");
+ break;
+ case KEY_INHERIT:
+ SendItem(i,"Inerit from #%d %s",
+ ItemNumber(LevelOf(i),
+ ((INHERIT *)(s))->in_Master),
+ CNameOf(((INHERIT *)(s))->in_Master));
+ break;
+ case KEY_INOUTHERE:
+ SendItem(i,"InOutHere");
+ break;
+ case KEY_USERTEXT:
+ SendItem(i,"UserText");
+ break;
+ case KEY_USERFLAG2:
+ SendItem(i,"UserFlag2");
+ break;
+
+ default:SendItem(i,"Unknown - %d\n",s->pr_Key);
+ }
+ SendItem(i,"\n");
+ s=s->pr_Next;
+ }
+}
+
+void Cmd_ListItems(i)
+ITEM *i;
+{
+ ITEM *a=ItemList;
+ if(ArchWizard(i))
+ {
+ while(a)
+ {
+ SendItem(i,"%s\n",CNameOf(a));
+ a=a->it_MasterNext;
+ }
+ SendItem(i,"%ld items.\n",CountItems());
+ }
+ else
+ SendItem(i,"Try INVentory.\n");
+}
+
+
+void Cmd_SetState(i)
+ITEM *i;
+{
+ ITEM *a;
+ int v;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Wasn't he an Egyptian god ?\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ SkipPrep();
+ if((v=GetNumber())==-1)
+ {
+ SendItem(i,"To which state ?\n");
+ return;
+ }
+ if((v<0)||(v>3))
+ {
+ SendItem(i,"States range from 0-3\n");
+ return;
+ }
+ a->it_State=v; /* Doesnt go thru full SetState() drivers */
+}
+
+void Cmd_SetPerception(i)
+ITEM *i;
+{
+ ITEM *a;
+ int v;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Pardon ?\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ SkipPrep();
+ if((v=GetNumber())==-1)
+ {
+ SendItem(i,"To what value ?\n");
+ return;
+ }
+ if((v<0)||(v>32765))
+ {
+ SendItem(i,"Perception ranges from 0-32765\n");
+ return;
+ }
+ a->it_Perception=v; /* Doesnt go thru full SetState() drivers */
+}
+
+
+void Cmd_SetName(i)
+ITEM *i;
+{
+ ITEM *a;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Sorry no name changing round here.\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ SkipPrep();
+ GetAll();
+ if(!strlen(WordBuffer))
+ {
+ SendEdit(i,"SetName #%d %s %s",ItemNumber(LevelOf(Me()),a),CNameOf(a),NameOf(a));
+ return;
+ }
+ SetName(a,WordBuffer);
+}
+
+void Cmd_NewItem(i)
+ITEM *i;
+{
+ int ad,no;
+ ITEM *it;
+ char namebuf[128];
+ if(!ArchWizard(i))
+ {
+ if((GetParsedWord())&&(stricmp(WordBuffer,"draught")==0))
+ {
+ SendItem(i,"You wave your arms around and create a draught.\n");
+ return;
+ }
+ SendItem(i,"Create! The only thing you could create is a draught.\n");
+ return;
+ }
+ if(GetThing(&ad,&no)==-1)
+ {
+ SendItem(i,"There are undefined words in your item.\n");
+ return;
+ }
+ if(no==-1)
+ {
+ SendItem(i,"Invalid noun.\n");
+ return;
+ }
+ if(ad==-1)
+ sprintf(namebuf,"the %s",FindWText(no,WD_NOUN));
+ else
+ sprintf(namebuf,"the %s %s",FindWText(ad,WD_ADJ),
+ FindWText(no,WD_NOUN));
+ it=CreateItem(namebuf,ad,no);
+ SendItem(i,"%s has been created.(AD=%d)(NO=%d)\n",CNameOf(it),ad,no);
+}
+
+void Cmd_DelItem(i)
+ITEM *i;
+{
+ ITEM *a;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Sure.....\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ if(a->it_Users)
+ {
+ SendItem(i,"The item still has %d locks into reality\n",
+ a->it_Users);
+ return;
+ }
+ UnUserFlag(a);
+ UnGenExit(a);
+ KillIOH(a);
+ UnUserText(a);
+ if(O_PROPERTIES(a))
+ {
+ SendItem(i,"The item still has properties.\n");
+ return;
+ }
+ if(!O_EMPTY(a))
+ {
+ SendItem(i,"And what fate shall befall those things that lie within it ?\n");
+ return;
+ }
+ UnlinkItem(a);
+ FreeItem(a);
+ SendItem(i,"It is no more.\n");
+}
+
+void Cmd_BeRoom(i)
+ITEM *i;
+{
+ ITEM *a;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Everything round here will be what it wants!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ if(RoomOf(a))
+ {
+ SendItem(i,"It already is.\n");
+ return;
+ }
+ MakeRoom(a);
+ SendItem(i,"%s is now a room.\n",NameOf(a));
+}
+
+void Cmd_BeObject(i)
+ITEM *i;
+{
+ char *t=WordPtr; /* Remember so we can call EditObj later */
+ ITEM *a;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Everything round here will be what it wants!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ if(ObjectOf(a))
+ {
+ SendItem(i,"It already is.\n");
+ return;
+ }
+ MakeObject(a);
+ SendItem(i,"%s is now an object.\n",NameOf(a));
+ WordPtr=t;
+ Cmd_ObjEdit(i); /* Edit it up... */
+}
+
+void Cmd_BePlayer(i)
+ITEM *i;
+{
+ ITEM *a;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Everything round here will be what it wants!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ if(PlayerOf(a))
+ {
+ SendItem(i,"It already is.\n");
+ return;
+ }
+ MakePlayer(a);
+ SendItem(i,"%s is now a player.\n",NameOf(a));
+}
+
+void Cmd_BeContainer(i)
+ITEM *i;
+{
+ ITEM *a;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Everything round here will be what it wants!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ if(ContainerOf(a))
+ {
+ SendItem(i,"It already is.\n");
+ return;
+ }
+ BeContainer(a);
+ SendItem(i,"%s is now a container.\n",NameOf(a));
+}
+
+void Cmd_UnRoom(i)
+ITEM *i;
+{
+ ITEM *a;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Everything round here will be what it wants!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ if(!RoomOf(a))
+ {
+ SendItem(i,"That is not a room anyway.\n");
+ return;
+ }
+ UnRoom(a);
+ SendItem(i,"%s is no longer a room.\n",NameOf(a));
+}
+
+void Cmd_UnObject(i)
+ITEM *i;
+{
+ ITEM *a;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Everything round here will be what it wants!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ if(!ObjectOf(a))
+ {
+ SendItem(i,"That is not an object.\n");
+ return;
+ }
+ UnObject(a);
+ SendItem(i,"%s is no longer an object.\n",NameOf(a));
+}
+
+void Cmd_UnPlayer(i)
+ITEM *i;
+{
+ ITEM *a;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Everything round here will be what it wants!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ if(!PlayerOf(a))
+ {
+ SendItem(i,"That is not a player.\n");
+ return;
+ }
+ if(PlayerOf(a)->pl_UserKey!=-1)
+ {
+ SendItem(i,"\
+That cannot be done, for it is said that upon the time that a user is not a\n\
+player, the fourth guru shall descend upon the world...\n");
+ return;
+ }
+ UnPlayer(a);
+ SendItem(i,"%s is no longer a player.\n",NameOf(a));
+}
+
+void Cmd_UnContainer(i)
+ITEM *i;
+{
+ ITEM *a;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Everything round here will be what it wants!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ if(!ContainerOf(a))
+ {
+ SendItem(i,"That is not a container.\n");
+ return;
+ }
+ UnContainer(a);
+ SendItem(i,"%s is no longer a container.\n",NameOf(a));
+}
+
+void Cmd_SaveUniverse(i)
+ITEM *i;
+{
+ int x=UserOf(i);
+ int v;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Who do you think you are , superman ?\n");
+ return;
+ }
+ if(CountUsers()!=1)
+ {
+ SendItem(i,"Sorry, you must be alone in the game to do this. \n");
+ return;
+ }
+ DisintegrateAll();
+ DisintegrateAll(); /* 2nd in case it mops up 1st lot */
+ SendItem(i,"You have been removed from the universe. \n");
+ SetPrompt(i,"Relogin : ");
+ ExitUser(x);
+ GetAll();
+ v=SaveSystem(WordBuffer);
+ switch(v)
+ {
+ case 0:SendUser(x,"Save completed.\n");break;
+ case -1:SendUser(x,"Save failed: Can't create .bak file.\n");
+ break;
+ case -2:SendUser(x,"Save failed: Cant't open save file.\n");
+ break;
+ default:SendUser(x,"Save failed: Unix Error Code=%d.\n",
+ v);
+ }
+ SetMe(NULL);
+ AddEvent(0,1); /* Run Table 1 on re-entry */
+}
+
+void Cmd_StatMe(i)
+ITEM *i;
+{
+ if(!ArchWizard(i))
+ SendItem(i,"Go away, Peasant!\n");
+}
+
+void Cmd_ListWord(i)
+ITEM *i;
+{
+ int wtype=-1;
+ int wcd=1;
+ char *wptr;
+ extern WLIST *WordList;
+ WLIST *w;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"When the boss is away, the mortals will play....\n");
+ return;
+ }
+ GetAll();
+ wptr=WordBuffer;
+ if(*wptr=='#')
+ {
+ if(sscanf(wptr+1,"%d",&wcd)==0)
+ {
+ SendItem(i,"Invalid number!\n");
+ return;
+ }
+ goto l2;
+ }
+ if(*wptr=='$')
+ {
+ wptr++;
+ switch(*wptr)
+ {
+ case 'V':wtype=WD_VERB;wptr++;break;
+ case 'N':wtype=WD_NOUN;wptr++;break;
+ case 'A':wtype=WD_ADJ;wptr++;break;
+ case 'P':wtype=WD_PREP;wptr++;break;
+ case 'n':wtype=WD_NOISE;wptr++;break;
+ case 'p':wtype=WD_PRONOUN;wptr++;break;
+ }
+ }
+/*
+ * Now list matches
+ */
+ w=WordList;
+ while(w)
+ {
+ if(((w->wd_Type==wtype)||(wtype==-1))&&
+ ((strcmp(wptr,"")==0)||
+ (stricmp(wptr,w->wd_Text)==0)))
+ {
+ SendItem(i,"%s %c %d\n",
+ w->wd_Text,
+ "?NPpCVAnO"[w->wd_Type],
+ w->wd_Code);
+ }
+ w=w->wd_Next;
+ }
+ return;
+l2: w=WordList;
+ while(w)
+ {
+ if(w->wd_Code==wcd)
+ {
+ SendItem(i,"%s %c %d\n",
+ w->wd_Text,
+ "?NPpCVAnO"[w->wd_Type],
+ w->wd_Code);
+ }
+ w=w->wd_Next;
+ }
+}
+
+void Cmd_DelWord(ITEM *i, short type)
+{
+ if(ArchWizard(i))
+ {
+ if(GetWord()==(WLIST *)(-1))
+ {
+ SendItem(i,"Yes, but what word shall I delete ?\n");
+ return;
+ }
+ strcpy(CmdBuffer,WordBuffer);
+ if(FindInList(WordList,CmdBuffer,type)==0)
+ {
+ SendItem(i,"'%s' is not defined.\n",CmdBuffer);
+ return;
+ }
+ FreeWord(CmdBuffer,(short)type);
+ }
+ else
+ SendItem(i,"No chance buster.\n");
+}
+
+void Cmd_DelVerb(i)
+ITEM *i;
+{
+ Cmd_DelWord(i,(short)WD_VERB);
+}
+
+void Cmd_DelPronoun(i)
+ITEM *i;
+{
+ Cmd_DelWord(i,(short)WD_PRONOUN);
+}
+
+void Cmd_DelNoun(i)
+ITEM *i;
+{
+ Cmd_DelWord(i,(short)WD_NOUN);
+}
+
+void Cmd_DelAdj(i)
+ITEM *i;
+{
+ Cmd_DelWord(i,(short)WD_ADJ);
+}
+
+void Cmd_DelPrep(i)
+ITEM *i;
+{
+ Cmd_DelWord(i,(short)WD_PREP);
+}
+
+void Cmd_DelOrdinate(i)
+ITEM *i;
+{
+ Cmd_DelWord(i,WD_ORDIN);
+}
+
+void Cmd_Rename(i)
+ITEM *i;
+{
+ int ad,no;
+ ITEM *x;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What makes you think you can rename things?\n");
+ return;
+ }
+ x=FindSomething(i,O_PARENT(i));
+ if(!x)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ SkipPrep();
+ if(GetThing(&ad,&no)==-1)
+ {
+ SendItem(i,"There are undefined words in your new name.\n");
+ return;
+ }
+ O_ADJECTIVE(x)=ad;
+ O_NOUN(x)=no;
+ SendItem(i,"It has been changed.\n");
+}
+
+void Cmd_Chain(i)
+ITEM *i;
+{
+ ITEM *x,*y;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What makes you think you can chain things?\n");
+ return;
+ }
+ x=FindSomething(i,O_PARENT(i));
+ if(!x)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ SkipPrep();
+ y=FindSomething(i,O_PARENT(i));
+ if(!y)
+ {
+ SendItem(i,"I don't know what you are trying to chain it to.\n");
+ return;
+ }
+ AddChain(x,y);
+ SendItem(i,"%s is now chained to %s.\n",CNameOf(x),NameOf(y));
+}
+
+void Cmd_UnChain(i)
+ITEM *i;
+{
+ ITEM *x,*y;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What makes you think you can unchain things?\n");
+ return;
+ }
+ x=FindSomething(i,O_PARENT(i));
+ if(!x)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ SkipPrep();
+ y=FindSomething(i,O_PARENT(i));
+ if(!y)
+ {
+ SendItem(i,"I don't know what you are trying to unchain.\n");
+ return;
+ }
+ if(RemoveChain(x,y))
+ {
+ SendItem(i,"%s is not chained to %s.\n",CNameOf(x),NameOf(y));
+ return;
+ }
+ SendItem(i,"%s is no longer chained to %s.\n",CNameOf(x),NameOf(y));
+}
+
+void Cmd_UFlagShow(i)
+ITEM *i;
+{
+ ITEM *x,*y;
+ int c=0;;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What are you gibbering about now ?\n");
+ return;
+ }
+ x=FindSomething(i,O_PARENT(i));
+ if(!x)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ while(c<15)
+ {
+ SendItem(i,"Flag %d : %d Flag %d : %d ",
+ c,GetUserFlag(x,c),c+1,GetUserFlag(x,c+1));
+ SendItem(i,"Flag %d : %d Flag %d : %d\n",
+ c+2,GetUserFlag(x,c+2),c+3,GetUserFlag(x,c+3));
+ c+=4;
+ }
+ c=0;
+ while(c<15)
+ {
+ y=GetUserItem(x,c);
+ if(y!=NULL)
+ SendItem(i,"Entry %d : %s\n",c,CNameOf(y));
+ c++;
+ }
+ c=0;
+ while(c<8)
+ {
+ SendItem(i,"Text %d : %s\n",c,GetUText(x,c));
+ c++;
+ }
+}
+
+void Cmd_SetUFlag(i)
+ITEM *i;
+{
+ ITEM *x;
+ int c,n;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What makes you think you can do that ?\n");
+ return;
+ }
+ x=FindSomething(i,O_PARENT(i));
+ if(!x)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ SkipPrep();
+ c=GetNumber();
+ if(c==-1)
+ {
+ SendItem(i,"You must specify which flag (0-15)\n");
+ return;
+ }
+ if((c<0)||(c>15))
+ {
+ SendItem(i,"Flag range is 0-15\n");
+ return;
+ }
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"You must specify a number to set it to.\n");
+ return;
+ }
+ SetUserFlag(x,c,n);
+}
+
+void Cmd_SetUItem(i)
+ITEM *i;
+{
+ ITEM *x,*n;
+ int c;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What makes you think you can do that ?\n");
+ return;
+ }
+ x=FindSomething(i,O_PARENT(i));
+ if(!x)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ SkipPrep();
+ c=GetNumber();
+ if(c==-1)
+ {
+ SendItem(i,"You must specify which flag (0-7)\n");
+ return;
+ }
+ if((c<0)||(c>15))
+ {
+ SendItem(i,"Flag range is 0-15\n");
+ return;
+ }
+ n=FindSomething(i,O_PARENT(i));
+ if(n==NULL)
+ {
+ SendItem(i,"Setting to NULL item.\n");
+ }
+ SetUserItem(x,c,n);
+}
+
+void Cmd_ShowFlag(i)
+ITEM *i;
+{
+ int st,en;
+ short s1=0,s2=0;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"You have no flags worth showing to anyone!\n");
+ return;
+ }
+ GetAll();
+ switch(sscanf(WordBuffer,"%d,%d",&st,&en))
+ {
+ case 1:en=st;break;
+ case 2:break;
+ default:SendItem(i,"You must specify which flags (from,to)\n");
+ return;
+ }
+ if((st<0)||(en>511)||(en<st))
+ {
+ SendItem(i,"The range specified is invalid.\n");
+ return;
+ }
+ s1=st;
+ while(s1<=en)
+ {
+ SendItem(i,"%-3d=%-5d ",s1,GetFlag(s1));
+ if(s2%4==3)
+ SendItem(i,"\n");
+ s2++;
+ s1++;
+ }
+ if(s2%4!=0) /* Print CR unless just done so */
+ SendItem(i,"\n");
+}
+
+void Cmd_SetFlag(i)
+ITEM *i;
+{
+ int fl,v;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Try setting jelly - it's more your level.\n");
+ return;
+ }
+ GetAll();
+ if(sscanf(WordBuffer,"%d %d",&fl,&v)!=2)
+ {
+ SendItem(i,"You must specify a flag and a value.\n");
+ return;
+ }
+ if((fl<0)||(fl>511))
+ {
+ SendItem(i,"Flag out of range.\n");
+ return;
+ }
+ SetFlag(fl,v);
+}
+
+void Cmd_Share(i)
+ITEM *i;
+{
+ ITEM *a,*b;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Share and enjoy...\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ SkipPrep();
+ b=FindSomething(i,O_PARENT(i));
+ if(b==NULL)
+ {
+ SendItem(i,"I don't know what you want %s to inherit.\n",
+ NameOf(a));
+ return;
+ }
+ if(Inheritor(b))
+ {
+ SendItem(i,"Warning: %s inherits from %s. This inheritance\
+ will not be passed onto %s.\n",CNameOf(b),NameOf(Inheritor(b)),
+ NameOf(a));
+ }
+ if(Inheritor(a))
+ {
+ SendItem(i,"%s no longer inherits from %s.\n",
+ CNameOf(a),NameOf(Inheritor(a)));
+ }
+ MakeInherit(a,b);
+ SendItem(i,"%s now inherits from %s.\n",CNameOf(a),NameOf(b));
+}
+
+void Cmd_UnShare(i)
+ITEM *i;
+{
+ ITEM *a;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Ok, don't share and enjoy then...\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ UnInherit(a);
+ SendItem(i,"%s no longer inherits.\n",CNameOf(a));
+}
+
+void Cmd_Status(i)
+ITEM *i;
+{
+ extern long MemFree();
+ long n[25];
+ ITEM *w=ItemList;
+ SUB *s;
+ long t;
+ time(&t);
+ SendItem(i,"Creator Of Legends - Version 5.21\n\n");
+ SendItem(i,"System Status at %s\n",ctime(&t));
+#ifdef CHECK_TXT
+ SendItem(i,"Text Pointer Validation: ON\n");
+#else
+ SendItem(i,"Text Pointer Validation: OFF\n");
+#endif
+#ifdef CHECK_ITEM
+ SendItem(i,"Item Pointer Validation: ON\n");
+#else
+ SendItem(i,"Item Pointer Validation: OFF\n");
+#endif
+ n[0]=0;n[1]=0;n[2]=0;n[3]=0;n[4]=0;
+ n[5]=0;n[6]=0;n[7]=0;n[8]=0;n[9]=0;
+ n[10]=0;n[11]=0;n[12]=0;n[13]=0;n[14]=0;
+ n[15]=0;n[16]=0;n[17]=0;n[18]=0;n[19]=0;
+ n[20]=0;n[21]=0;n[22]=0;n[23]=0;n[24]=0;
+ while(w)
+ {
+ s=w->it_Properties;
+ while(s)
+ {
+ if(s->pr_Key==KEY_INHERIT)
+ n[0]++;
+ else
+ n[s->pr_Key]++;
+ s=s->pr_Next;
+ }
+ w=w->it_MasterNext;
+ }
+ SendItem(i,"Number Of Items : %ld\n",CountItems());
+ SendItem(i,"Number Of Rooms : %ld\n",n[KEY_ROOM]);
+ SendItem(i,"Number Of Objects : %ld\n",n[KEY_OBJECT]);
+ SendItem(i,"Number Of Players : %ld\n",n[KEY_PLAYER]);
+ SendItem(i,"Number Of GenExits : %ld\n",n[KEY_GENEXIT]);
+ SendItem(i,"Number Of MsgExits : %ld\n",n[KEY_MSGEXIT]);
+ SendItem(i,"Number Of CondExits : %ld\n",n[KEY_CONDEXIT]);
+ SendItem(i,"Number Of Containers : %ld\n",n[KEY_CONTAINER]);
+ SendItem(i,"Number Of Chains : %ld\n",n[KEY_CHAIN]);
+ SendItem(i,"Number Of UserFlags : %ld\n",n[KEY_USERFLAG]);
+ SendItem(i,"Number Of Snoops : %ld\n",n[KEY_SNOOP]);
+ SendItem(i,"Number Of InoutHeres : %ld\n",n[KEY_INOUTHERE]);
+ SendItem(i,"Number Of Dups : %ld\n",n[KEY_DUPED]);
+ SendItem(i,"Number Of UserTexts : %ld\n",n[KEY_USERTEXT]);
+ SendItem(i,"Number Of UserFlag2s : %ld\n",n[KEY_USERFLAG2]);
+ SendItem(i,"Number Of Shares : %ld\n",n[0]);
+ SendItem(i,"Number Of Schedules : %ld\n",CountSchedules());
+ if(MemFree()!=-1)
+ SendItem(i,"Free Heap Space : %ld\n",MemFree());
+}
+
+
+void Cmd_TrackFlag(i)
+ITEM *i;
+{
+ int v=GetNumber();
+ short c=0;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What ?\n");
+ return;
+ }
+ Debugger=i; /* Set debug destination */
+ if(v==-1)
+ {
+ SendItem(i,"Which flag ?\n");
+ return;
+ }
+ if(v<0||v>511)
+ {
+ SendItem(i,"Flag number out of range, range is 0-511\n");
+ return;
+ }
+ while(c<4)
+ {
+ if(Traf[c]==-1)
+ {
+ Traf[c]=v;
+ SendItem(i,"Tracking flag %d\n",v);
+ return;
+ }
+ c++;
+ }
+ SendItem(i,"\
+You can only track four flags at a time - stop tracking one with untrack.\n");
+}
+
+void Cmd_UnTrackFlag(i)
+ITEM *i;
+{
+ int v=GetNumber();
+ short c=0;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What ?\n");
+ return;
+ }
+ if(v==-1)
+ {
+ SendItem(i,"Which flag ?\n");
+ return;
+ }
+ while(c<4)
+ {
+ if(Traf[c]==v)
+ {
+ SendItem(i,"Stopped tracking flag %d\n",v);
+ Traf[c]=-1;
+ return;
+ }
+ c++;
+ }
+ SendItem(i,"You are not tracking flag %d\n",v);
+}
+
+void Cmd_ListTrack(i)
+ITEM *i;
+{
+ short c=0;
+ short f=0;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What ?\n");
+ return;
+ }
+ while(c<4)
+ {
+ if(Traf[c]!=-1)
+ {
+ if(f==0)
+ {
+ f=1;
+ SendItem(i,"You are tracking flag(s) %d",Traf[c]);
+ }
+ else
+ SendItem(i,",%d",Traf[c]);
+ }
+ c++;
+ }
+ if(f)
+ SendItem(i,".\n");
+ else
+ SendItem(i,"You are tracking no flags\n");
+}
+
+void Cmd_Debugger(i)
+ITEM *i;
+{
+ if(ArchWizard(i))
+ Debugger=i;
+ else
+ SendItem(i,"Such delusions of grandeur...\n");
+}
+
+void Cmd_FindItem(i)
+ITEM *i;
+{
+ ITEM *j=FindSomething(i,O_PARENT(i));
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"You will have too look for yourself chum!\n");
+ return;
+ }
+ if(j==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ CheckAllFor(i,j,-1);
+}
+
+void Cmd_FindFlag(i)
+ITEM *i;
+{
+ int v=GetNumber();
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"You will have too look for yourself chum!\n");
+ return;
+ }
+ if(v==-1)
+ {
+ SendItem(i,"Which flag ?\n");
+ return;
+ }
+ if(v<0||v>511)
+ {
+ SendItem(i,"Flags range from 0-511\n");
+ return;
+ }
+ CheckAllFor(i,NULL,v);
+}
+
+void Cmd_Which(i)
+ITEM *i;
+{
+ ITEM *a=FindSomething(i,O_PARENT(i));
+ if(!ArchWizard(i))
+ SendItem(i,"Pardon ?\n");
+ else
+ {
+ if(a)
+ SendItem(i,"#%d %s\n",ItemNumber(LevelOf(i),a),NameOf(a));
+ else
+ SendItem(i,"None.\n");
+ }
+}
+
+void Cmd_ShowSuperClass(i)
+ITEM *i;
+{
+ ITEM *a=FindSomething(i,O_PARENT(i));
+ ITEM *b;
+ int ct=20;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Go to school.\n");
+ return;
+ }
+ if(a==NULL)
+ {
+ SendItem(i,"What is that.\n");
+ return;
+ }
+ if(a->it_Superclass==NULL)
+ {
+ SendItem(i,"%s is unclassed.\n", CNameOf(a));
+ return;
+ }
+ b=a->it_Superclass;
+ while(b)
+ {
+ SendItem(i,"%s has superclass %s\n",CNameOf(a),NameOf(b));
+ a=b;
+ b=b->it_Superclass;
+ ct--;
+ if(ct==0)
+ {
+ SendItem(i,"Classing too deep.\n");
+ return;
+ }
+ }
+}
+
+void Cmd_SetSuperClass(i)
+ITEM *i;
+{
+ ITEM *a=FindSomething(i,O_PARENT(i));
+ ITEM *b;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Go to school.\n");
+ return;
+ }
+ if(a==NULL)
+ {
+ SendItem(i,"What ?\n");
+ return;
+ }
+ b=FindSomething(i,O_PARENT(i));
+ if(b==NULL)
+ {
+ SendItem(i,"Unknown superclass object.\n");
+ return;
+ }
+
+ if(a->it_Superclass!=NULL)
+ {
+ UnlockItem(a->it_Superclass);
+ a->it_Superclass=NULL;
+ }
+ if(b==a)
+ {
+ SendItem(i,"Item self classed.\n");
+ return;
+ }
+ LockItem(b);
+ a->it_Superclass=b;
+ SendItem(i,"Ok.\n");
+}
diff --git a/ExitLogic.c b/ExitLogic.c
new file mode 100644
index 0000000..b580679
--- /dev/null
+++ b/ExitLogic.c
@@ -0,0 +1,32 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Conditional Exit Logic Evaluator
+ *
+ * 1.00 AGC Created this file, to replace stub version
+ */
+
+#include "System.h"
+
+Module "Exit Logic";
+Version "1.00";
+Author "Alan Cox";
+
+
+int TestCondExit(e)
+CONDEXIT *e;
+{
+ TABLE *t=FindTable(e->ce_Table);
+ if(t!=NULL)
+ if(ExecBackground(t,Me())==-1)
+ return(0);
+ return(1);
+}
diff --git a/FindPW.c b/FindPW.c
new file mode 100644
index 0000000..ab45f4a
--- /dev/null
+++ b/FindPW.c
@@ -0,0 +1,37 @@
+
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+
+int main(int argc, char *argv[])
+{
+ short ct=1;
+ UFF u;
+ while(argv[ct])
+ {
+ if(LoadPersona(argv[ct],&u)==-1)
+ printf("%s: Not Registered\n",argv[ct]);
+ else
+ printf("%d:%s: Password %s\n",ct,argv[ct],
+ u.uff_Password);
+ ct++;
+ }
+ return 0;
+}
+
+void Log(char *fmt, ...){;}
+
+void ErrFunc(char *x, char *y, char *z, int a, char *b)
+{
+ fprintf(stderr,"%s %s %s %d %s\n",x,y,z,a,b);
+ exit(1);
+}
+
diff --git a/FlagControl.c b/FlagControl.c
new file mode 100644
index 0000000..cf532d1
--- /dev/null
+++ b/FlagControl.c
@@ -0,0 +1,181 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+
+/*
+ * Flag handlers
+ *
+ * 1.00 Initial release
+ * 1.01 Strict ANSIfication
+ */
+
+Module "Flag Controller";
+Version "1.01";
+Author "Alan Cox";
+
+char *FlagName[512]; /* Crude but effective ! */
+
+
+/*
+ * Given a name, find the flag number
+ */
+
+int GetFlagByName(char *x)
+{
+ short c=0;
+ while(c<512)
+ {
+ if((FlagName[c])&&(stricmp(FlagName[c],x)==0))
+ return(c);
+ c++;
+ }
+ return(-1);
+}
+
+/*
+ * Set the name of a flag
+ */
+
+void SetFlagName(short f, char *x)
+{
+ if(f<0||f>511)
+ return;
+ if(FlagName[f]!=NULL)
+ free(FlagName[f]);
+ if(x==NULL)
+ {
+ FlagName[f]=NULL;
+ return;
+ }
+ if((FlagName[f]=malloc(strlen(x)+1))==NULL)
+ Error("FlagController: No Free Memory.\n");
+ strcpy(FlagName[f],x);
+}
+
+/*
+ * Get the name of a flag
+ */
+
+char *GetFlagName(short f)
+{
+ static char b[8];
+ if((f>=0)&&(f<512)&&(FlagName[f]))
+ return(FlagName[f]);
+ else
+ {
+ sprintf(b,"%d",f);
+ return(b);
+ }
+}
+
+/*
+ * The actual flag naming command function
+ */
+
+void Cmd_NameFlag(ITEM *i)
+{
+ short n=GetNumber();
+ char *c=WordBuffer;
+ if(n==-1)
+ {
+ SendItem(i,"Which flag number ?\n");
+ return;
+ }
+ GetAll();
+ if(!strlen(c))
+ {
+ SendItem(i,"You must specify a name for the flag.\n");
+ return;
+ }
+ if(*c!='@')
+ {
+ SendItem(i,"Flags must start with the '@' character.\n");
+ return;
+ }
+ if(GetFlagByName(c)!=-1)
+ {
+ SendItem(i,"But flag %d is already called '%s'.\n",
+ GetFlagByName(c),c);
+ return;
+ }
+ if((n<0)||(n>511))
+ {
+ SendItem(i,"Flag numbers are from 0-511 inclusive.\n");
+ return;
+ }
+ SetFlagName(n,c);
+ SendItem(i,"Flag %d is now called %s.\n",n,c);
+}
+
+/*
+ * UnName a flag - command
+ */
+
+void Cmd_UnNameFlag(ITEM *i)
+{
+ short n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Which flag number ?\n");
+ return;
+ }
+ if((n<0)||(n>511))
+ {
+ SendItem(i,"Flag numbers are from 0-511 inclusive.\n");
+ return;
+ }
+ SetFlagName(n,NULL);
+ SendItem(i,"Flag %d is now un-named.\n",n);
+}
+
+/*
+ * The listflag command
+ */
+
+void Cmd_ListFlags(ITEM *i)
+{
+/*
+ * LISTFLAG lists all flags, LISTFLAG @NAME lists flag 'name'
+ * LISTFLAG n lists flag n
+ */
+ int v;
+ GetAll();
+ if(!strlen(WordBuffer))
+ {
+ short c=0;
+ while(c<512)
+ {
+ if(FlagName[c])
+ SendItem(i,"%-3d %s\n",c,GetFlagName(c)+1);
+ c++;
+ }
+ return;
+ }
+ if(sscanf(WordBuffer,"%d",&v)==0)
+ {
+ if(*WordBuffer=='@')
+ {
+ if(GetFlagByName(WordBuffer))
+ SendItem(i,"%-3d %s\n",
+ GetFlagByName(WordBuffer),WordBuffer);
+ return;
+ }
+ else
+ SendItem(i,"Flag names always start with '@'.\n");
+ }
+ else
+ {
+ if(FlagName[v])
+ {
+ SendItem(i,"%-3d %s\n",v,GetFlagName((short)v));
+ }
+ }
+}
diff --git a/FlagName.c b/FlagName.c
new file mode 100644
index 0000000..eaa335e
--- /dev/null
+++ b/FlagName.c
@@ -0,0 +1,190 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Controller to handle names of bit flags (player/object etc)
+ */
+
+#include "System.h"
+
+Module "BitFlag Names";
+Version "1.00";
+Author "----*(A)";
+
+/*
+ * 1.00 AGC Initial Release For 5.07
+ * 1.01 AGC Core Dump Cure Time
+ *
+ */
+
+char *PBitNames[16];
+char *OBitNames[16];
+char *RBitNames[16];
+char *CBitNames[16];
+
+static void ListBitSet(i,l)
+ITEM *i;
+char **l;
+{
+ int ct= -1;
+ while(++ct<16)
+ SendItem(i,"%d\t%s\n",ct,l[ct]?l[ct]:"{unset}");
+}
+
+
+static void SetBitName(i,l)
+ITEM *i;
+char **l;
+{
+ int n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"You must specify a bit number.\n");
+ return;
+ }
+ if(n<0||n>15)
+ {
+ SendItem(i,"Number Out Of Range (0-15)\n");
+ return;
+ }
+ if(GetParsedWord()==NULL)
+ {
+ SendItem(i,"You must specify a name for the bitflag.\n");
+ return;
+ }
+ if(l[n])
+ free(l[n]);
+ l[n]=malloc(strlen(WordBuffer)+1);
+ if(!l[n])
+ Error("SetBitName: Out Of Memory");
+ strcpy(l[n],WordBuffer);
+}
+
+static char *BitName(l,n)
+char **l;
+int n;
+{
+ return(l[n]?l[n]:"{unset}"); /* Note: Several things check for this
+ string - be careful if you
+ change it at all. */
+}
+
+static int WhichBitField(l,x)
+char **l;
+char *x;
+{
+ int ct= -1;
+ while(++ct<16)
+ {
+ if(l[ct] &&stricmp(l[ct],x)==0)
+ return(ct);
+ }
+ return(-1);
+}
+
+int FindRBit(x)
+char *x;
+{
+ return(WhichBitField(RBitNames,x));
+}
+
+int FindPBit(x)
+char *x;
+{
+ return(WhichBitField(PBitNames,x));
+}
+
+int FindCBit(x)
+char *x;
+{
+ return(WhichBitField(CBitNames,x));
+}
+
+int FindOBit(x)
+char *x;
+{
+ return(WhichBitField(OBitNames,x));
+}
+
+char *RBitName(n)
+int n;
+{
+ return(BitName(RBitNames,n));
+}
+
+char *PBitName(n)
+int n;
+{
+ return(BitName(PBitNames,n));
+}
+
+char *CBitName(n)
+int n;
+{
+ return(BitName(CBitNames,n));
+}
+
+char *OBitName(n)
+int n;
+{
+ return(BitName(OBitNames,n));
+}
+
+/*
+ * Commands for using these facilities
+ */
+
+void Cmd_RBitName(i)
+ITEM *i;
+{
+ SetBitName(i,RBitNames);
+}
+
+void Cmd_PBitName(i)
+ITEM *i;
+{
+ SetBitName(i,PBitNames);
+}
+
+void Cmd_CBitName(i)
+ITEM *i;
+{
+ SetBitName(i,CBitNames);
+}
+
+void Cmd_OBitName(i)
+ITEM *i;
+{
+ SetBitName(i,OBitNames);
+}
+
+void Cmd_ListRBits(i)
+ITEM *i;
+{
+ ListBitSet(i,RBitNames);
+}
+
+void Cmd_ListPBits(i)
+ITEM *i;
+{
+ ListBitSet(i,PBitNames);
+}
+
+void Cmd_ListCBits(i)
+ITEM *i;
+{
+ ListBitSet(i,CBitNames);
+}
+
+void Cmd_ListOBits(i)
+ITEM *i;
+{
+ ListBitSet(i,OBitNames);
+}
diff --git a/GenCommand.c b/GenCommand.c
new file mode 100644
index 0000000..c1b9d3f
--- /dev/null
+++ b/GenCommand.c
@@ -0,0 +1,96 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Some General Command Functions
+ */
+
+#include "System.h"
+
+Module "General Commands";
+Version "1.01";
+Author "----*(A)";
+
+void Cmd_Invisible(i)
+ITEM *i;
+{
+ if(LevelOf(i)<16)
+ {
+ SendItem(i,"You can't do that.\n");
+ return;
+ }
+ if(i->it_Perception!=0)
+ {
+ SendItem(i,"You are already invisible.\n");
+ return;
+ }
+ DoesAction(i,4,"vanishes in a haze of multihued light.\n");
+ i->it_Perception=LevelOf(i);
+ DoesAction(i,4,"is now invisible.\n");
+}
+
+void Cmd_Visible(i)
+ITEM *i;
+{
+ if(i->it_Perception==0)
+ {
+ SendItem(i,"You are already visible.\n");
+ return;
+ }
+ i->it_Perception=0;
+ DoesAction(i,4,"appears amidst a puff of greenish smoke.\n");
+}
+
+void Cmd_Say(i)
+ITEM *i;
+{
+ GetAll();
+ if(!strlen(WordBuffer))
+ strcpy(WordBuffer,"something");
+ DoesAction(i,7,"says '%s'.\n",WordBuffer);
+}
+
+void Cmd_Place(i)
+ITEM *i;
+{
+ ITEM *src;
+ ITEM *dest;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Sorry, I don't understand that.\n");
+ return;
+ }
+ src=FindSomething(i,O_PARENT(i));
+ SkipPrep();
+ dest=FindSomething(i,O_PARENT(i));
+ if(!src)
+ {
+ SendItem(i,"I don't know what you are trying to place.\n");
+ return;
+ }
+ if(!dest)
+ {
+ SendItem(i,"I don't know where you are trying to place that.\n");
+ return;
+ }
+ if(O_PARENT(src))
+ {
+ if(CanSee(LevelOf(O_PARENT(src)),src))
+ SendItem(O_PARENT(src),
+ "%s has just vanished from your belongings.\n",CNameOf(src));
+ }
+ DoesAction(src,4,"vanishes.\n");
+ Place(src,dest);
+ DoesAction(src,4,"appears with a bang.\n");
+ if(CanSee(LevelOf(dest),src))
+ SendItem(dest,"%s suddenly appears in your belongings!\n",
+ CNameOf(src));
+}
+
diff --git a/IPC.h b/IPC.h
new file mode 100644
index 0000000..fa0f28b
--- /dev/null
+++ b/IPC.h
@@ -0,0 +1,40 @@
+struct IPC_Message
+{
+ long ms_Size;
+ struct IPC_Message *ms_Next;
+};
+
+typedef struct IPC_Message MESSAGE;
+#ifdef AMIGA_OLD
+struct IPC_Port
+{
+ long po_SystemKey;
+ MESSAGE *po_MessageList;
+ long po_Flags;
+ struct Task *po_Task;
+ short po_Signal;
+ short po_Open;
+};
+
+#else
+struct IPC_Port
+{
+ int po_pid;
+ int po_fd;
+ int po_Open;
+ int po_Flags;
+ int po_SiloPtr;
+ char po_Silo[8192];
+};
+#endif
+typedef struct IPC_Port PORT;
+
+#define PORT_SYSKEY 37612
+#define FL_DELETE (1<<4)
+#define FL_TEMPORARY (1<<4)
+#define FL_FAULT (1<<5)
+#define NOWAIT (1<<6)
+#define FL_BOUND (1<<7)
+extern PORT *CreateMPort();
+extern PORT *OpenMPort();
+extern PORT *FindService();
diff --git a/IPCDirect.c b/IPCDirect.c
new file mode 100644
index 0000000..7f1645d
--- /dev/null
+++ b/IPCDirect.c
@@ -0,0 +1,810 @@
+#ifdef AMIGA
+#include <exec/types.h>
+#endif
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <sys/ioctl.h>
+#include <netinet/in.h>
+#ifndef AMIGA
+#include <time.h>
+#endif
+#include <fcntl.h>
+#include <errno.h>
+#ifndef AMIGA
+#include <arpa/telnet.h>
+#else
+#define IAC 255
+#define DONT 254
+#define DO 253
+#define WILL 252
+#define WONT 251
+#define TELOPT_ECHO 1
+#endif
+#include "System.h"
+#include "User.h"
+#ifdef AMIGA
+#include <pragmas/socket_pragmas.h>
+extern long SocketBase;
+#define errno Errno()
+#endif
+
+#define MK_NET(a,b,c,d) ((a<<24)|(b<<16)|(c<<8)|d)
+
+/*
+ * Implement embedded comms client, and telnet modes direct from
+ * the server. This replaces the front end stuff to drive tcp/ip
+ * on 5.14. We now do it all BSD style with sockets and select,
+ * so the game shouldn't need a sys5 style interface anywhere.
+ *
+ * 1.00 AGC Created Initial Version For 5.16
+ * 1.01 AGC Fixed Minor Bugs/Upgrades
+ * 1.02 AGC Added Client Mode Switch
+ * 1.03 AGC Added '!' facility for nonclienters
+ * 1.04 AGC Tidying Up Of Code
+ * 1.05 AGC Added stuff for -p <port>
+ * 1.06 AGC Spots dropped idle lines
+ * 1.07 AGC HARDBANNER optional
+ * 1.08 CCS Added TCP_WRAPPER and echo control
+ * 1.09 AGC Removed wrapper, moved motd code.
+ * 1.10 AGC Fix endian problems, also fixes for some dodgier tcp stacks
+ * 1.11 AGC Client mode fixed (silly mistake), round robin scheduler.
+ * 1.12 AGC BSX graphics support
+ * 1.13 AGC Minor client mode bug, and @TMS bug fixed
+ * 1.14 AGC 'Smart' prompt code. Only alpha prompts are sent to BSX users
+ * 1.15 AGC Server supports AmiTCP. Small changes only. I am seriously impressed
+ * with the AmiTCP package.
+ */
+
+extern USER UserList[];
+
+Module "IPCDirect";
+Version "1.15";
+Author "Alan Cox";
+
+/*
+ * This is definitely a case for a big structure for each user, but
+ * I do a lot of scanning of this data, even on fairly idle channels
+ * so stuffing it into arrays, in this chosen order lowers paging
+ * Its probably academic considering the amount of background stuff
+ * people put in a typical abermud5
+ */
+
+static char UserLine[MAXUSER][81];
+static short UserPos[MAXUSER];
+static char SnoopLine[MAXUSER][81];
+static short SnoopPos[MAXUSER];
+static char Prompts[MAXUSER][64];
+/* Stuff below this comment gets scanned every second */
+static char UserInput[MAXUSER][514];
+static short InputPos[MAXUSER];
+static char UserState[MAXUSER];
+static char UserEcho[MAXUSER];
+
+static int MainFD,AltFD,BsxFD;
+static fd_set ReadMask,WriteMask;
+int SysPort=TCP_PORT;
+
+/*
+ * This info is needed elsewhere (BSX.c)
+ */
+
+int IsBSX(int u)
+{
+ if(UserState[u]==2)
+ return(1);
+ return(0);
+}
+
+/*
+ * Given a file descriptor, find its owner process. Assumes that all
+ * channels have an owner. See changes to ComServer Handle_Login() to
+ * make this true
+ */
+
+int FindUserFD(int fd)
+{
+ int ct=0;
+ while(ct<MAXUSER)
+ {
+ if(UserList[ct].us_Port&&(UserList[ct].us_Port->po_fd&255)==(fd&255))
+ {
+ return(ct);
+ }
+ ct++;
+ }
+ Error("No User associated with fd"); /* Boom! */
+}
+
+int IsUserFD(int fd)
+{
+ int ct=0;
+ while(ct<MAXUSER)
+ {
+ if(UserList[ct].us_Port&&(UserList[ct].us_Port->po_fd&255)==(fd&255))
+ return(ct);
+ ct++;
+ }
+ return(-1);
+}
+
+/*
+ * Grab incoming data from a channel. If we finish reading a line, make
+ * a packet of it and stuff it into the main game.
+ */
+
+int ReadBlock(int u, COMTEXT *pkt)
+{
+/* We read only when we get something pending off select - so if we
+ read nothing first try they have buggered off */
+ int gotany=0;
+ char c;
+ int l;
+unsigned char t_iac=IAC,
+ t_will=WILL,
+ t_wont=WONT,
+ t_do =DO,
+ t_dont=DONT;
+
+ while((l=recv(UserList[u].us_Port->po_fd,&c,1,0))>0)
+ {
+ gotany=1;
+
+/*
+ * Telnet traps - get dump any IAC stuff
+ */
+
+ if( ((unsigned char) c) == t_iac)
+ {
+ read(UserList[u].us_Port->po_fd,&c,1);
+
+ if( ((unsigned char)c== t_will)
+ || ((unsigned char)c== t_wont)
+ || ((unsigned char)c== t_do )
+ || ((unsigned char)c== t_dont) )
+ {
+ read(UserList[u].us_Port->po_fd,&c,1);
+ }
+ continue;
+ }
+
+ if(c=='!'&&InputPos[u]==0&&UserState[u]==0)
+ {
+ c='\n';
+ InputPos[u]=strlen(UserInput[u]);
+ }
+ if(c==8||c==127)
+ {
+ if(InputPos[u]>0&&UserState[u]==0)
+ InputPos[u]--;
+ return(0);
+ }
+ if(c!='\r')
+ {
+ UserInput[u][InputPos[u]++]=c;
+ if(InputPos[u]==513||c=='\n')
+ {
+ if(UserState[u]==0 && UserEcho[u]==1)
+ {
+ CharPut(u,'\r'); /* Fix echo in nonecho mode */
+ CharPut(u,'\n');
+ }
+ UserInput[u][InputPos[u]-1]=0;
+ if(UserState[u]>0 && UserEcho[u]==0) /* BSX expects us to neatly echo command */
+ {
+ if(*UserInput[u]!='#') /* But not # commands */
+ {
+ char *p=UserInput[u];
+ CharPut(u,'>');
+ CharPut(u,' ');
+ while(*p)
+ CharPut(u,*p++);
+ CharPut(u,'\r');
+ CharPut(u,'\n');
+ }
+ }
+ strcpy(pkt->pa_Data,UserInput[u]);
+ pkt->pa_Sender=u;
+ if(UserState[u]==2 && UserInput[u][0]=='#')
+ pkt->pa_Type=PACKET_BSXSCENE; /* BSX process the line */
+ else
+ pkt->pa_Type=PACKET_COMMAND;
+ InputPos[u]=0;
+ return(1);
+ }
+ }
+ }
+ /* EAGAIN added for SYS5 machines */
+ if((l==-1 && errno!=EWOULDBLOCK && errno != EAGAIN) || gotany==0)
+ {
+ /* Network fault.. shove it */
+ UserList[u].us_Port->po_Flags|=FL_FAULT;
+ FD_CLR(UserList[u].us_Port->po_fd,&ReadMask);
+ FD_CLR(UserList[u].us_Port->po_fd,&WriteMask);
+ }
+ return(0);
+}
+
+/*
+ * Client used to do formatting, so we have to do wrapping here now
+ */
+
+void SnoopPut(int u, char c)
+{
+ SnoopLine[u][SnoopPos[u]++]=c;
+}
+
+void SnoopFlush(int u, int n)
+{
+ if(UserState[u]==1)
+ WriteSocket(u,"\002S",2);
+ else
+ WriteSocket(u,"|",1);
+ WriteSocketText(u,SnoopLine[u],n);
+ WriteSocket(u,"\r\n",2);
+ if(UserState[u]==1)
+ WriteSocket(u,"\003",1);
+ SnoopPos[u]=0;
+}
+
+
+void SnoopCharPut(int u, char c)
+{
+ if(SnoopPos[u]==79)
+ {
+ if(c==' '||c=='\n'||c=='\t')
+ SnoopFlush(u,79);
+ else
+ {
+ int ct=78;
+ while(ct--)
+ {
+ if(SnoopLine[u][ct]==' '||SnoopLine[u][ct]=='\t')
+ {
+ SnoopFlush(u,ct);
+ while(++ct<=78)
+ SnoopPut(u,SnoopLine[u][ct]);
+ SnoopPut(u,c);
+ return;
+ }
+ }
+ SnoopFlush(u,78);
+ SnoopPut(u,c);
+ }
+ }
+ else
+ {
+ if(c=='\n')
+ {
+ SnoopFlush(u,SnoopPos[u]);
+ return;
+ }
+ SnoopPut(u,c);
+ }
+ return;
+}
+
+/* Formatting for normal text output */
+
+void CharPut(int u, char c)
+{
+ if(UserPos[u]==79)
+ {
+ if(c==' '||c=='\n'||c=='\t')
+ LineFlush(u,79);
+ else
+ {
+ int ct=78;
+ while(ct--)
+ {
+ if(UserLine[u][ct]==' '||UserLine[u][ct]=='\t')
+ {
+ LineFlush(u,ct);
+ while(++ct<=78)
+ LinePut(u,UserLine[u][ct]);
+ LinePut(u,c);
+ return;
+ }
+ }
+ LineFlush(u,78);
+ LinePut(u,c);
+ }
+ }
+ else
+ {
+ if(c=='\n')
+ {
+ LineFlush(u,UserPos[u]);
+ return;
+ }
+ LinePut(u,c);
+ }
+ return;
+}
+
+
+void LinePut(int u, char c)
+{
+ UserLine[u][UserPos[u]++]=c;
+}
+
+void LineFlush(int u, char n)
+{
+ WriteSocketText(u,UserLine[u],n);
+ WriteSocket(u,"\r\n",2);
+ UserPos[u]=0;
+}
+
+void FieldShift(int u, int f)
+{
+ if(f==0||f>77)
+ return;
+ do
+ {
+ CharPut(u,' ');
+ }
+ while(UserPos[u]%f!=0);
+}
+
+/* Fake the port binding operating - we use the fd that is involved as the
+ key to the port */
+
+PORT *Bind_Port(int u, int p)
+{
+ PORT *a=Allocate(PORT);
+
+ a->po_fd=(p&255);
+ UserState[u]=0;
+ UserEcho[u]=0;
+ UserState[u]=p/256;
+ UserPos[u]=0;
+ UserInput[u][0]=0;
+ Prompts[u][0]=0;
+ InputPos[u]=0;
+ SnoopPos[u]=0;
+ a->po_Flags=0;
+ a->po_SiloPtr=0;
+ return(a);
+}
+
+/* Set up the master socket */
+
+PORT *CreateMPort(int f)
+{
+ PORT *p=Allocate(PORT);
+ p->po_fd=Make_Socket(SysPort);
+ MainFD=p->po_fd;
+ FD_ZERO(&ReadMask);
+ FD_SET(p->po_fd,&ReadMask);
+ AltFD=Make_Socket(SysPort+1);
+ FD_SET(AltFD,&ReadMask);
+ BsxFD=Make_Socket(SysPort+2);
+ FD_SET(BsxFD,&ReadMask);
+ return(p);
+}
+
+/* Open a port, meaningless really */
+
+PORT *OpenMPort(PORT *port)
+{
+ port->po_Open++;
+ return(port);
+}
+
+/* Close down a port */
+
+int CloseMPort(PORT *port)
+{
+ SiloFlush(port);
+ port->po_Open--;
+#ifdef AMIGA
+ CloseSocket(port->po_fd);
+#else
+ close(port->po_fd);
+#endif
+ FD_CLR(port->po_fd,&ReadMask);
+ FD_CLR(port->po_fd,&WriteMask);
+ free((char *)port);
+ return 0;
+}
+
+/* We don't use the blocking switches at all in this set of IPC code */
+
+void BlockOn(PORT *p){;}
+void BlockOff(PORT *p){;}
+
+/*
+ * Take an outgoing packet service and turn it into action on the
+ * sockets.
+ */
+
+int WriteMPort(PORT *a, COMTEXT *block, int len)
+{
+ COMDATA *d=(COMDATA *)block;
+ char *fp;
+ int u=FindUserFD(a->po_fd);
+ switch(block->pa_Type)
+ {
+ case PACKET_OUTPUT:;
+ fp=block->pa_Data;
+ while(*fp)
+ CharPut(u,*fp++);
+ break;
+ case PACKET_CLEAR:
+ fp=block->pa_Data;
+ while(*fp)
+ CharPut(u,*fp++);
+ if(UserState[u]==2)
+ WriteSocket(u,"@TMS",4);
+ break;
+ case PACKET_SETPROMPT:
+ if(UserState[u]!=1)
+ strcpy(Prompts[u],block->pa_Data);
+ else
+ {
+ WriteSocket(u,"\002P",2);
+ WriteSocket(u,block->pa_Data,strlen(block->pa_Data));
+ WriteSocket(u,"\003",1);
+ }
+ break;
+ case PACKET_LOGINACCEPT:
+ InputPos[u]=0;
+ break;
+ case PACKET_EDIT:
+ if(UserState[u]==1)
+ {
+ WriteSocket(u,"\002T",2);
+ WriteSocket(u,block->pa_Data,strlen(block->pa_Data));
+ WriteSocket(u,"\003",1);
+ }
+ break;
+ case PACKET_SNOOPTEXT:
+ fp=block->pa_Data;
+ while(*fp)
+ SnoopCharPut(u,*fp++);
+ break;
+ case PACKET_SETTITLE:break;
+ case PACKET_LOOPECHO:
+ break; /* Cant be bothered.. */
+ case PACKET_ECHOBACK:break;
+ case PACKET_BSXSCENE: /* Graphics stuff - only goes to BSX users */
+ if(UserState[u]==2)
+ WriteSocket(u,block->pa_Data,strlen(block->pa_Data));
+ break;
+ case PACKET_ECHO:
+ UserEcho[u]=d->pa_Data[0];
+ switch(UserState[u])
+ {
+ case 1:
+ WriteSocket(u,"\002E",2);
+ WriteSocket(u,d->pa_Data[0]?"Y\003":"N\003",2);
+ break;
+ case 2:
+ break;
+ case 0:
+ {
+ unsigned char t_iac=IAC,
+ t_will=WILL,
+ t_wont=WONT,
+ t_echo=TELOPT_ECHO;
+
+ WriteSocket(u,(char *)&t_iac,1);
+ WriteSocket(u,(d->pa_Data[0])?((char *)&t_will):((char *)&t_wont),1);
+ WriteSocket(u,(char *)&t_echo,1);
+ }
+ break; /* Dont bother with echoing now */
+ }
+ break;
+ case PACKET_INPUT:
+ switch(UserState[u])
+ {
+ case 2:
+ if(!isalpha(*Prompts[u]))
+ break;
+ WriteSocketText(u,Prompts[u],strlen(Prompts[u]));
+ WriteSocketText(u,"\r\n",2);
+ break;
+ case 0:
+ WriteSocketText(u,Prompts[u],strlen(Prompts[u]));
+ break;
+ case 1:
+ if(isalpha(*Prompts[u]))
+ {
+ WriteSocketText(u,Prompts[u],strlen(Prompts[u]));
+ WriteSocketText(u,"\r\n",2);
+ }
+ WriteSocket(u,"\002G\003",3);
+ break;
+ }
+ break;
+ case PACKET_SETFIELD:
+ FieldShift(u,d->pa_Data[0]);
+ break;
+ }
+ return(0);
+}
+
+/* Delete a closed port */
+
+int DeleteMPort(PORT *a)
+{
+ if(a->po_Open)
+ {
+ a->po_Flags|=FL_DELETE;
+ return(0);
+ }
+#ifdef AMIGA
+ CloseSocket(a->po_fd);
+#else
+ close(a->po_fd);
+#endif
+ free((char *)a);
+ return(0);
+}
+
+/* We don't use the service finding stuff any more */
+
+int AssignService(char *s, PORT *p){return(0);}
+int DeAssignService(char *s){return(0);}
+PORT *FindService(char *s) {return NULL;}
+
+/*
+ * Wait up to a second for a message to read.
+ *
+ * This code has changed only slightly for Beta3, but the implications are significant. Previously
+ * lower numbered connections got a distinct advantage. The new code does a round robin scan of
+ * file decriptors.
+ */
+
+int ReadMPort(PORT *a, COMTEXT *b)
+{
+ struct timeval tvl;
+ static long magic_time_cookie=0;
+ long t;
+ static int ct=0; /* Now static */
+ fd_set rfm;/*WriteMask;*/
+ int oct=ct;
+
+ /* For non ANSI compilers... */
+ memcpy(&rfm,&ReadMask,sizeof(rfm));
+
+ /* Initialise tvl seperately to keep non ansi compilers happy */
+ tvl.tv_sec=1;
+ tvl.tv_usec=0;
+
+ FD_ZERO(&WriteMask);
+
+ /*
+ * Slow machine fix: Stops busy machine never running background jobs
+ */
+
+ time(&t);
+ if(t-magic_time_cookie>2)
+ {
+ magic_time_cookie=t;
+ return(-2);
+ }
+ if(select(NFDBITS,&rfm,NULL,NULL,&tvl)==-1)
+ {
+ perror("select");
+ exit(1);
+ }
+ /* Now do reading */
+ do
+ {
+ if(ct==MainFD||ct==AltFD||ct==BsxFD)
+ {
+ if(FD_ISSET(ct,&rfm))
+ {
+ return(MakeConnection(ct,b));
+/* return(0);*/
+ }
+ }
+ else if(FD_ISSET(ct,&rfm))
+ {
+ if(IsUserFD(ct)!=-1 && ReadBlock(FindUserFD(ct),b)==1)
+ {
+ return(0);
+ }
+ }
+ ct++;
+ if(ct==NFDBITS)
+ ct=0;
+ }
+ while(ct!=oct);
+ return(-2);
+}
+
+/* Handle non-blocking socket queues and the incomplete writes stuff */
+
+int Silo(PORT *port, char *block, int len)
+{
+ if(port->po_SiloPtr+len>8191-sizeof(int))
+ {
+ port->po_Flags|=FL_FAULT;
+ FD_CLR(port->po_fd,&ReadMask);
+ FD_CLR(port->po_fd,&WriteMask);
+ return(-20);
+ }
+ memcpy(port->po_Silo+port->po_SiloPtr,block,len);
+ port->po_SiloPtr+=len;
+ return(0);
+}
+
+int SiloFlush(PORT *port)
+{
+ int sz;
+ if(port==NULL)
+ return(0);
+ if(port->po_Flags&FL_FAULT)
+ return(-1);
+ sz=send(port->po_fd,port->po_Silo,port->po_SiloPtr,0);
+ if(sz==-1&&errno!=EWOULDBLOCK&&errno!=EAGAIN)
+ {
+ port->po_Flags|=FL_FAULT;
+ FD_CLR(port->po_fd,&ReadMask);
+ FD_CLR(port->po_fd,&WriteMask);
+ return(-1);
+ }
+ port->po_SiloPtr-=sz;
+/* Have to bcopy this one : must NOT memcpy it as we need to ensure
+ it handles overlaps right. If you dont have such a beast write one
+ If you have bcopy but not memcpy,then replace the memcpy's - thats ok
+*/
+ if(port->po_SiloPtr==0)
+ return(0);
+ bcopy(port->po_Silo+sz,port->po_Silo,port->po_SiloPtr);
+ return(-1);
+}
+
+/* Send data to someone */
+
+int WriteSocket(int user, char *data, int bytes)
+{
+ int l;
+ if(SiloFlush(UserList[user].us_Port))
+ {
+ return(Silo(UserList[user].us_Port,data,bytes));
+ }
+ l=send(UserList[user].us_Port->po_fd,data,bytes,0);
+ if(l<bytes)
+ if(Silo(UserList[user].us_Port,data+l,bytes-l)!=0)
+ return(-1);
+ return(0);
+}
+
+/* BSX MUD uses @xyz as command strings. This means we have to quote our @
+ characters in BSX mode as @TXT@$ */
+
+int WriteSocketText(int user, char *data, int bytes)
+{
+ /* Do all we can to avoid lots of messy little writes */
+ /* If @TXT actually worked on the BSX client I might even bother
+ checking this code works! */
+#ifdef DONTDEF
+ char *t;
+ if(UserState[user]!=2)
+#endif
+ return WriteSocket(user,data,bytes);
+#ifdef DONTDEF
+ t=memchr(data,'@',bytes);
+ if(t==NULL)
+ return WriteSocket(user,data,bytes);
+ /* We've tried all we can but we will have to do some thinking */
+ do
+ {
+ if(t!=data)
+ {
+ if(WriteSocket(user,data,t-bytes)==-1)
+ return(-1);
+ }
+ if(WriteSocket(user,"@TXT@$",6)==-1)
+ return(-1);
+ bytes-=(t-data);
+ bytes--; /* For the '@' too */
+ data=t+1;
+ t=memchr(data,'@',bytes);
+ }
+ while(t!=NULL);
+ /* All dealt with at last */
+ return(0);
+#endif
+}
+
+void WriteFlush(int u){;}
+
+/* Convert an IP address to a text string. We can't go further than ip
+ names as the lookup can take up to 30 seconds. This is not acceptable
+ in a server environment - note the address has already been fed
+ through ntohl() */
+
+char *NetName(unsigned long l)
+{
+ int code[4];
+ static char name[64];
+ code[0]=l%65536;
+ code[2]=l/65536;
+ code[3]=code[2]/256;
+ code[2]%=256;
+ code[1]=code[0]/256;
+ code[0]%=256;
+ sprintf(name,"%d.%d.%d.%d",code[3],code[2],code[1],code[0]);
+ return(name);
+}
+
+#ifdef TIME_LIMITS
+
+#define CLOSEHOUR 9
+#define CHECK 18
+
+int can_play_now(void)
+{
+ time_t x;
+ struct tm *a;
+
+ time(&x);
+ a = localtime(&x);
+ return (a->tm_hour >= CHECK || a->tm_hour < CLOSEHOUR ||
+ a->tm_wday == 6 || a->tm_wday == 0);
+}
+
+#endif /* TIME_LIMITS */
+
+
+/*
+ * Fake up a login request packet
+ */
+
+int MakeConnection(int fd, COMTEXT *p)
+{
+ struct sockaddr_in netaddr;
+ socklen_t lv=sizeof(netaddr);
+ int ofd=fd;
+#ifdef AMIGA
+ long yes=1;
+#endif
+
+#ifndef AMIGA
+ fcntl(fd,F_SETFL,O_NDELAY);
+#endif
+ fd=accept(fd,(struct sockaddr *)&netaddr,&lv);
+#ifndef AMIGA
+ fcntl(fd,F_SETFL,0);
+#endif
+
+ p->pa_Type=PACKET_LOGINREQUEST;
+ p->pa_Sender=fd;
+
+ /* Reverse the address, that makes it easier to work with everywhere else */
+ netaddr.sin_addr.s_addr=ntohl(netaddr.sin_addr.s_addr);
+
+ sprintf(p->pa_Data,"%s%s$%d$*","Internet:",NetName(netaddr.sin_addr.s_addr),
+ fd+(ofd==AltFD?256:0)+(ofd==BsxFD?512:0));
+
+/* SWANSEA STUFF - PLEASE ENFORCE ELSEWHERE TOO... */
+ if(netaddr.sin_addr.s_addr==MK_NET(137,44,1,1)
+ ||netaddr.sin_addr.s_addr==MK_NET(143,52,2,10))
+ {
+ sprintf(p->pa_Data,"BAD$SITE");
+ p->pa_Sender= -1;
+ send(fd,"Not permitted from this site\n\r",30,0);
+#ifdef AMIGA
+ CloseSocket(fd);
+#else
+ close(fd);
+#endif
+ return(-1);
+ }
+
+/* printf("***GOT CONNECTION\n");*/
+#ifndef AMIGA
+ fcntl(fd,F_SETFL,O_NDELAY);
+#else
+ /* AmiTCP has the BSD blocking ioctl() but lacks the use of fcntl() */
+ ioctl(fd,FIONBIO,&yes);
+#endif
+ FD_SET(fd,&ReadMask);
+ return(0);
+}
+
+
diff --git a/InsAndOuts.c b/InsAndOuts.c
new file mode 100644
index 0000000..259fc6a
--- /dev/null
+++ b/InsAndOuts.c
@@ -0,0 +1,499 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+
+Module "Ins And Outs";
+Version "1.06";
+Author "----*(A)";
+
+/* Exit Drivers
+ *
+ * 1.00 Basic Exit Control GENEXIT Handlers
+ * 1.01 Added MSGEXIT Control
+ * 1.02 Checks CanPlace() when moving
+ * 1.03 Added CanGoto()
+ * 1.04 Added DoorExit() and WhereTo()
+ * 1.05 Added RM_DROPEMSG
+ * 1.06 Doesnt tell you about invisible/dark doors
+ * 1.07 Added complex exit dump for archwizards
+ */
+
+extern ITEM *Item1,*Item2;
+
+char *ExitName(x)
+int x;
+{
+ switch(x)
+ {
+ case 0:return("North");
+ case 1:return("East");
+ case 2:return("South");
+ case 3:return("West");
+ case 4:return("Up");
+ case 5:return("Down");
+ case 6:return("NorthEast");
+ case 8:return("SouthEast");
+ case 7:return("NorthWest");
+ case 9:return("SouthWest");
+ case 10:return("In");
+ case 11:return("Out");
+ }
+ return("<ERROR>");
+}
+
+
+void Cmd_NewExit(i)
+ITEM *i;
+{
+ short v; /* Short gives better array access code */
+ ITEM *a;
+ ITEM *to;
+ GENEXIT *g;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Sorry no walking through walls.\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ g=(GENEXIT *)FindSub(a,KEY_GENEXIT);
+ if(!g)
+ {
+ if(MakeGenExit(a))
+ {
+ SendItem(i,"Couldn't create GENEXIT subinfo.\n");
+ return;
+ }
+ g=(GENEXIT *)FindSub(a,KEY_GENEXIT);
+ }
+ v=(short)GetVerb();
+ if((v<100)||(v>111))
+ {
+ SendItem(i,"You must specify a direction. \n");
+ return;
+ }
+ to=FindSomething(i,O_PARENT(i));
+ if(to==NULL)
+ {
+ SendItem(i,"I don't know where you want it to go to. \n");
+ return;
+ }
+ if(g->ge_Dest[v-100])
+ UnlockItem(g->ge_Dest[v-100]);
+ LockItem(to);
+ g->ge_Dest[v-100]=to;
+ SendItem(i,"Exit Created.\n");
+}
+
+void Cmd_MsgExit(i)
+ITEM *i;
+{
+ char *WStr;
+ short v;
+ ITEM *a;
+ ITEM *to;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Sorry no walking through walls.\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ v=(short)GetVerb();
+ if((v<100)||(v>111))
+ {
+ SendItem(i,"You must specify a direction. \n");
+ return;
+ }
+ WStr=WordPtr;
+ GetAll();
+ if(!strlen(WordBuffer))
+ {
+ MSGEXIT *m;
+ m=FindMsgExit(a,(short)(v-100));
+ if(!m)
+ return;
+ SendEdit(i,"MessageExit %s %s %s %s",
+ NameOf(a),ExitName(v-100),
+ NameOf(m->me_Dest),
+ TextOf(m->me_Text));
+ return;
+ }
+ WordPtr=WStr;
+ to=FindSomething(i,O_PARENT(i));
+ if(to==NULL)
+ {
+ SendItem(i,"I don't know where you want it to go to. \n");
+ return;
+ }
+ GetAll();
+ MakeMsgExit(a,to,(short)(v-100),WordBuffer);
+ SendItem(i,"Exit Created.\n");
+}
+
+void Cmd_CondExit(i)
+ITEM *i;
+{
+ int table;
+ short v;
+ ITEM *a;
+ ITEM *to;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Sorry no walking through walls.\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ v=(short)GetVerb();
+ if((v<100)||(v>111))
+ {
+ SendItem(i,"You must specify a direction. \n");
+ return;
+ }
+ to=FindSomething(i,O_PARENT(i));
+ if(to==NULL)
+ {
+ SendItem(i,"I don't know where you want it to go to. \n");
+ return;
+ }
+ GetAll();
+ table=FindTableByName(WordBuffer);
+ if(table==-1)
+ {
+ SendItem(i,"Unknown table.\n");
+ return;
+ }
+ MakeCondExit(a,to,table,(short)(v-100));
+ SendItem(i,"Exit Created.\n");
+}
+
+/* BUG: Cmd_MoveDirn currently doesn't support MsgExits to doors.
+ * Note: There are NO CondExits to doors.
+ */
+
+void Cmd_MoveDirn(i,x)
+ITEM *i;
+int x;
+{
+ ITEM *d;
+ MSGEXIT *m;
+ CONDEXIT *c;
+ if(O_PARENT(i)==NULL)
+ {
+ SendItem(i,"The void is infinite you can wander lost forever...\n");
+ return;
+ }
+ c=FindCondExit(O_PARENT(i),(short)x);
+ m=FindMsgExit(O_PARENT(i),(short)x);
+ if((c)&&(TestCondExit(c)))
+ {
+ if(CanPlace(i,c->ce_Dest))
+ {
+ SendItem(i,"You can't get into %s.\n",NameOf(c->ce_Dest));
+ return;
+ }
+ DoesAction(i,4,"%s %s.\n",GetOutMsg(i),ExitName(x));
+ Place(i,c->ce_Dest);
+ Cmd_Look(i);
+ DoesAction(i,4,"%s.\n",GetInMsg(i));
+ return;
+ }
+ if(c)
+ {
+ return;
+ }
+ if(m)
+ {
+ if(CanPlace(i,m->me_Dest))
+ {
+ SendItem(i,"You can't get into %s.\n",NameOf(m->me_Dest));
+ return;
+ }
+ DoesAction(i,4,"%s %s.\n",GetOutMsg(i),ExitName(x));
+ Place(i,m->me_Dest);
+ if(!IsDarkFor(i)&&(IsPlayer(i)&&
+ (PlayerOf(i)->pl_Flags&PL_BRIEF)==0))
+ SendItem(i,"%s ",TextOf(m->me_Text));
+ else
+ {
+ Cmd_Look(i);
+ goto l1;
+ }
+ if((IsRoom(m->me_Dest))&&
+ ((RoomOf(m->me_Dest)->rm_Flags&RM_DROPEMSG)==0))
+ Cmd_Look(i);
+l1: DoesAction(i,4,"%s.\n",GetInMsg(i));
+ return;
+ }
+ d=ExitOf(O_PARENT(i),x);
+ if(d)
+ {
+ if(CanPlace(i,d))
+ {
+ SendItem(i,"You can't get into %s.\n",NameOf(d));
+ return;
+ }
+ DoesAction(i,4,"%s %s.\n",GetOutMsg(i),ExitName(x));
+ Place(i,d);
+ Cmd_Look(i);
+ DoesAction(i,4,"%s.\n",GetInMsg(i));
+ return;
+ }
+ if((d=DoorOf(O_PARENT(i),x))!=NULL)
+ {
+ /* SIMPLE FORM FOR NOW! */
+ if(IsDarkFor(i)||!CanSee(LevelOf(i),d))
+ {
+ SendItem(i,"You can't go that way.\n");
+ }
+ else
+ {
+ if(O_STATE(d)==1)
+ SendItem(i,"%s is closed.\n",CNameOf(d));
+ else
+ SendItem(i,"%s is locked.\n",CNameOf(d));
+ }
+ return;
+ }
+ SendItem(i,"You can't go that way.\n");
+}
+
+
+void Cmd_DelExit(i)
+ITEM *i;
+{
+ int v;
+ ITEM *a;
+ GENEXIT *g;
+ MSGEXIT *m;
+ CONDEXIT *c;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Sorry no instant walls.\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ v=GetVerb();
+ if((v<100)||(v>111))
+ {
+ SendItem(i,"You must specify a direction. \n");
+ return;
+ }
+ c=FindCondExit(a,(short)(v-100));
+ m=FindMsgExit(a,(short)(v-100));
+ if(c)
+ UnCondExit(a,c);
+ if(m)
+ UnMsgExit(a,m);
+ g=(GENEXIT *)FindSub(a,KEY_GENEXIT);
+ if(!g)
+ {
+ return;
+ }
+ if(g->ge_Dest[v-100])
+ {
+ UnlockItem(g->ge_Dest[v-100]);
+ g->ge_Dest[v-100]=NULL;
+ }
+ else
+ {
+ return;
+ }
+ SendItem(i,"Exit Deleted.\n");
+}
+
+
+void Cmd_Exits(i,j)
+ITEM *i;
+ITEM *j;
+{
+ MSGEXIT *m;
+ CONDEXIT *ce;
+ ITEM *k;
+ int n=0;
+ int c=0;
+ if(j==NULL)
+ {
+ SendItem(i,"In the void nothing bars your way.\n");
+ return;
+ }
+ while(n<12)
+ {
+ if((k=ExitOf(j,n))!=NULL)
+ {
+ c=1;
+ SendItem(i,"%-20s:%s\n",ExitName(n),CNameOf(k));
+ if(Arch(i))
+ SendItem(i,"StdExit to #%d %s\n",
+ ItemNumber(LevelOf(i),k),CNameOf(k));
+ }
+ m=FindMsgExit(j,(short)n);
+ if(m)
+ {
+ c=1;
+ SendItem(i,"%-20s:%s\n",ExitName(n),
+ CNameOf(m->me_Dest));
+ if(Arch(i))
+ SendItem(i,"MsgExit to #%d %s '%s'\n",
+ ItemNumber(LevelOf(i),m->me_Dest),
+ CNameOf(m->me_Dest),
+ TextOf(m->me_Text));
+ }
+ ce=FindCondExit(j,(short)n);
+ if(ce&&TestCondExit(ce)==1)
+ {
+ c=1;
+ SendItem(i,"%-20s:%s\n",ExitName(n),
+ CNameOf(ce->ce_Dest));
+ if(Arch(i))
+ SendItem(i,"CondExit to #%d %s (%s)\n",
+ ItemNumber(LevelOf(i),ce->ce_Dest),
+ CNameOf(ce->ce_Dest),
+ TabName(ce->ce_Table));
+ }
+ n++;
+ }
+ if(c==0)
+ SendItem(i,"None....\n");
+}
+
+int CanGoto(i,t)
+ITEM *i,*t;
+{
+ short x=0;
+ ITEM *d;
+ MSGEXIT *m;
+ CONDEXIT *c;
+ if(O_PARENT(i)==NULL)
+ {
+ return(255);
+ }
+ while(x<12)
+ {
+ c=FindCondExit(O_PARENT(i),(short)x);
+ m=FindMsgExit(O_PARENT(i),(short)x);
+ if((c)/*&&(TestCondExit(c))*/)
+ {
+ if(CanPlace(i,c->ce_Dest))
+ continue;
+ return(x);
+ }
+ if(m)
+ {
+ if(CanPlace(i,m->me_Dest))
+ {
+ continue;
+ }
+ return(x);
+ }
+ d=ExitOf(O_PARENT(i),x);
+ if(d)
+ {
+ if(CanPlace(i,d))
+ {
+ continue;
+ }
+ return(x);
+ }
+ x++;
+ }
+ return(255);
+}
+
+
+void Act_WhereTo()
+{
+ ITEM *i=ArgItem();
+ short d=ArgNum();
+ short f=ArgNum();
+ MSGEXIT *m;
+ CONDEXIT *c;
+ c=FindCondExit(i,d);
+ m=FindMsgExit(i,d);
+ if((c)/*&&(TestCondExit(c))*/)
+ {
+ if(f==1)
+ Item1=c->ce_Dest;
+ else
+ Item2=c->ce_Dest;
+ return;
+ }
+ if(m)
+ {
+ if(f==1)
+ Item1=m->me_Dest;
+ else
+ Item2=m->me_Dest;
+ return;
+ }
+ if(f==1)
+ Item1=ExitOf(i,d);
+ else
+ Item2=ExitOf(i,d);
+}
+
+void Act_DoorExit()
+{
+ ITEM *i=ArgItem();
+ ITEM *d=ArgItem();
+ short f=ArgNum();
+ short ct=0;
+ while(ct<12)
+ {
+ if(DoorOf(i,ct)==d)
+ {
+ SetFlag(f,ct);
+ return;
+ }
+ ct++;
+ }
+ SetFlag(f,255);
+ return;
+}
+
+int BackExit(n)
+int n;
+{
+ switch(n)
+ {
+ case 0:return(2);
+ case 1:return(3);
+ case 2:return(0);
+ case 3:return(1);
+ case 4:return(5);
+ case 5:return(4);
+ case 6:return(8);
+ case 7:return(9);
+ case 8:return(6);
+ case 9:return(7);
+ case 10:return(11);
+ case 11:return(10);
+ }
+ return(-1);
+}
diff --git a/LibRwho.c b/LibRwho.c
new file mode 100644
index 0000000..fcf6e16
--- /dev/null
+++ b/LibRwho.c
@@ -0,0 +1,195 @@
+/*
+ * This is Marcus J Ranum's RWHO support library file. It is part of the mudwho distribution from decuac.dec.com
+ * and is not part of AberMUD5, but is used in compiling it. The AberMUD license has no bearing on this file,
+ * instead consult the license and information with the mudwho package. If you intend to set up a mudwho server
+ * you will need this package anyway.
+ *
+ * Alan
+ */
+
+
+/*
+ Copyright (C) 1991, Marcus J. Ranum. All rights reserved.
+
+ AmiTCP port Alan Cox 1993.
+
+static char RCSid[] unused = "$Header: /usr/users/mjr/hacks/umud/RWHO/RCS/clilib.c,v 1.2 91/08/18 21:49:44 mjr Exp $";
+
+*/
+
+/*
+code to interface client MUDs with rwho server
+
+this is a standalone library.
+*/
+
+#ifdef AMIGA
+#include <exec/types.h>
+typedef long time_t;
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <string.h>
+#include <time.h>
+#include <unistd.h>
+#ifdef VMS
+#include "tintop_dec:[amolitor.foo]types.h"
+#include "tintop_dec:[amolitor.foo]socket.h"
+#include "tintop_dec:[amolitor.foo]in.h"
+#include "tintop_dec:[amolitor.foo]netdb.h"
+#else
+#include <fcntl.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#endif
+#ifdef AMIGA
+#include <pragmas/socket_pragmas.h>
+extern long SocketBase;
+#endif
+
+#define DGRAMPORT 6888
+
+#ifndef NO_HUGE_RESOLVER_CODE
+extern struct hostent *gethostbyname();
+#endif
+
+static int dgramfd = -1;
+static char *password;
+static char *localnam;
+static char *lcomment;
+static struct sockaddr_in addr;
+static time_t senttime;
+
+
+/* enable RWHO and send the server a "we are up" message */
+int rwhocli_setup(char *server, char *serverpw, char *myname, char *comment)
+{
+#ifndef NO_HUGE_RESOLVER_CODE
+ struct hostent *hp;
+#endif
+ char pbuf[512];
+ char *p;
+
+ if(dgramfd != -1)
+ return(1);
+
+ password = malloc(strlen(serverpw) + 1);
+ localnam = malloc(strlen(myname) + 1);
+ lcomment = malloc(strlen(comment) + 1);
+ if(password == (char *)0 || localnam == (char *)0 || lcomment == (char *)0)
+ return(1);
+ strcpy(password,serverpw);
+ strcpy(localnam,myname);
+ strcpy(lcomment,comment);
+
+ p = server;
+ while(*p != '\0' && (*p == '.' || isdigit(*p)))
+ p++;
+
+ if(*p != '\0') {
+#ifndef NO_HUGE_RESOLVER_CODE
+ if((hp = gethostbyname(server)) == (struct hostent *)0)
+ return(1);
+ (void)bcopy(hp->h_addr,(char *)&addr.sin_addr,hp->h_length);
+#else
+ return(1);
+#endif
+ } else {
+ unsigned long f;
+
+ if((f = inet_addr(server)) == -1L)
+ return(1);
+ (void)bcopy((char *)&f,(char *)&addr.sin_addr,sizeof(f));
+ }
+
+ addr.sin_port = htons(DGRAMPORT);
+ addr.sin_family = AF_INET;
+
+ if((dgramfd = socket(AF_INET,SOCK_DGRAM,0)) < 0)
+ return(1);
+
+ time(&senttime);
+
+ sprintf(pbuf,"U\t%.20s\t%.20s\t%.20s\t%.10ld\t0\t%.25s",
+ localnam,password,localnam,(long)senttime,comment);
+ sendto(dgramfd,pbuf,strlen(pbuf),0,(struct sockaddr *)&addr,sizeof(addr));
+ return(0);
+}
+
+
+
+
+
+/* disable RWHO */
+int rwhocli_shutdown(void)
+{
+ char pbuf[512];
+
+ if(dgramfd != -1) {
+ sprintf(pbuf,"D\t%.20s\t%.20s\t%.20s",localnam,password,localnam);
+ sendto(dgramfd,pbuf,strlen(pbuf),0,(struct sockaddr *)&addr,sizeof(addr));
+ close(dgramfd);
+ dgramfd = -1;
+ free(password);
+ free(localnam);
+ }
+ return(0);
+}
+
+
+
+
+
+/* send an update ping that we're alive */
+int rwhocli_pingalive(void)
+{
+ char pbuf[512];
+
+ if(dgramfd != -1) {
+ sprintf(pbuf,"M\t%.20s\t%.20s\t%.20s\t%.10ld\t0\t%.25s",
+ localnam,password,localnam,(long)senttime,lcomment);
+ sendto(dgramfd,pbuf,strlen(pbuf),0,(struct sockaddr *)&addr,sizeof(addr));
+ }
+ return(0);
+}
+
+
+
+
+
+/* send a "so-and-so-logged in" message */
+int rwhocli_userlogin(char *uid, char *name, time_t tim)
+{
+ char pbuf[512];
+
+ if(dgramfd != -1) {
+ sprintf(pbuf,"A\t%.20s\t%.20s\t%.20s\t%.20s\t%.10ld\t0\t%.20s",
+ localnam,password,localnam,uid,(long)tim,name);
+ sendto(dgramfd,pbuf,strlen(pbuf),0,(struct sockaddr *)&addr,sizeof(addr));
+ }
+ return(0);
+}
+
+
+
+
+
+/* send a "so-and-so-logged out" message */
+int rwhocli_userlogout(char *uid)
+{
+ char pbuf[512];
+
+ if(dgramfd != -1) {
+ sprintf(pbuf,"Z\t%.20s\t%.20s\t%.20s\t%.20s",
+ localnam,password,localnam,uid);
+ sendto(dgramfd,pbuf,strlen(pbuf),0,(struct sockaddr *)&addr,sizeof(addr));
+ }
+ return(0);
+}
+
diff --git a/LibSocket.c b/LibSocket.c
new file mode 100644
index 0000000..b40ab25
--- /dev/null
+++ b/LibSocket.c
@@ -0,0 +1,114 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Socket Creation Functions
+ *
+ * 1.00 Original Version
+ * 1.01 License change
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <stdlib.h>
+#ifdef AMIGA
+#include <pragmas/socket_pragmas.h>
+#endif
+
+extern int errno;
+
+static struct sockaddr_in myaddress;
+static int master_socket;
+
+#ifdef AMIGA
+long SocketBase;
+
+int exit_cleanup(void)
+{
+ if(SocketBase!=NULL)
+ {
+ CloseLibrary(SocketBase);
+ SocketBase=NULL;
+ }
+}
+#endif
+
+/*
+ * Create the server socket
+ */
+
+int Make_Socket(int port)
+{
+#ifdef PARANOIA
+ char buf[64];
+ struct hostent *host;
+#endif
+ int v;
+ int tmp=1;
+#ifdef AMIGA
+ if(SocketBase==NULL)
+ {
+ SocketBase=OpenLibrary("bsdsocket.library",0);
+ if(SocketBase==NULL)
+ {
+ fprintf(stderr,"Fatal error: AmiTCP is not running.\n");
+ exit(1);
+ }
+ SetErrnoPtr(&errno,sizeof(errno));
+ }
+#endif
+#ifdef PARANOIA
+ gethostname(buf,63);
+ host=gethostbyname(buf);
+ if(host==NULL)
+ {
+ fprintf(stderr,"INET: Error can't find '%s'\n",buf);
+ exit(1);
+ }
+ myaddress.sin_family=host->h_addrtype;
+#endif
+ myaddress.sin_port=htons(port);
+ v=socket(AF_INET,SOCK_STREAM,0);
+ if(v==-1)
+ {
+ fprintf(stderr,"(%d)",errno);
+ perror("INET: socket, ");
+ exit(1);
+ }
+ setsockopt(v,SOL_SOCKET,SO_REUSEADDR,&tmp,sizeof(tmp));
+ while(bind(v,(struct sockaddr *)&myaddress,sizeof(myaddress))<0)
+ {
+ if(errno != EADDRINUSE)
+ {
+ close(v);
+ fprintf(stderr,"(%d)",errno);
+ perror("INET: bind, ");
+ exit(1);
+ }
+ printf("Address in use: Retrying...\n");
+ sleep(5);
+ }
+ if(listen(v,5)==-1)
+ {
+ fprintf(stderr,"(%d)",errno);
+ perror("INET: listen,");
+ exit(1);
+ }
+ master_socket=v;
+ return(v);
+}
+
+
diff --git a/LookFor.c b/LookFor.c
new file mode 100644
index 0000000..582c4c3
--- /dev/null
+++ b/LookFor.c
@@ -0,0 +1,135 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+
+Module "Search Routines";
+Version "1.01";
+Author "Alan Cox";
+
+/*
+ * 1.00 AGC Initial Version
+ * 1.01 AGC Made to understand bit classes
+ */
+
+static void PrintLine(l)
+LINE *l;
+{
+ LINE *t=CurrentLine;
+ CurrentLine=l;
+ PCurrentLine();
+ CurrentLine=t;
+}
+
+void CheckLineFor(line,s,st)
+LINE *line;
+ITEM *s;
+int st;
+{
+ register char *TLine;
+ unsigned short *x;
+ x=line->li_Data;
+ while(*x!=CMD_EOL)
+ {
+ int n=*x++;
+ int ct=0;
+ TLine=Cnd_Table[n];
+ while(TLine[ct]!=' ')
+ {
+ ITEM *i;
+ TPTR t;
+ switch(TLine[ct])
+ {
+ case 'I':
+ i=(ITEM *)PairArg(x);
+ x+=2;
+ if(s&&i==s)
+ {
+ PrintLine(line);
+ return;
+ }
+ break;
+ case '$':;
+ case 'T':t=(TPTR )PairArg(x);
+ x+=2;
+ break;
+ case '3':x++;break;
+ case 'F':if(*x++==st)
+ {
+ PrintLine(line);
+ return;
+ }
+ break;
+ case 'N':if(*x++==st+30000&&st!=-1)
+ {
+ PrintLine(line);
+ return;
+ }
+ break;
+ case 'W':;
+ case 'w':; /* THIS IS WRONG FOR NOW */
+ case 'Z':;
+ case 'B':;
+ case 't':;
+ case 'p':x++;
+ break;
+ case 'v':x++;
+ break;
+ case 'a':x++;
+ break;
+ case 'n':x++;
+ break;
+ case 'C':;
+ case 'R':;
+ case 'O':;
+ case 'P':;
+ case 'c':x++;
+ break;
+ default:
+ Error("Invalid Entry In Cnd_Table");
+ }
+ ct++;
+ }
+ }
+}
+
+void CheckTableFor(t,s,st)
+TABLE *t;
+ITEM *s;
+int st;
+{
+ LINE *l=t->tb_First;
+ while(l)
+ {
+ CheckLineFor(l,s,st);
+ l=l->li_Next;
+ }
+}
+
+void CheckAllFor(i,s,st)
+ITEM *i,*s;
+int st;
+{
+ TABLE *t=TableList;
+ TABLE *p;
+ ITEM *tmp=Debugger;
+ Debugger=i;
+ while(t)
+ {
+ p=CurrentTable;
+ CurrentTable=t;
+ SendItem(Debugger,"Checking Table %d\n",t->tb_Number);
+ CheckTableFor(t,s,st);
+ t=t->tb_Next;
+ }
+ Debugger=tmp;
+ CurrentTable=p;
+}
+
diff --git a/Main.c b/Main.c
new file mode 100644
index 0000000..0c09ba5
--- /dev/null
+++ b/Main.c
@@ -0,0 +1,148 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Main Driver For System
+ */
+
+#include "System.h"
+#include <signal.h>
+#include <fcntl.h>
+#include <unistd.h>
+#define SMALL_MALLOC
+
+#undef TCP_WRAP /* Use access controls */
+
+#ifdef TCP_WRAP
+#include <syslog.h>
+#endif
+
+/*
+ * 1.00 AGC Basic Startup
+ * 1.01 AGC Added crash handler
+ * 1.02 AGC MONITOR option
+ * 1.03 AGC Added __interrupt for 5.06 and Lat5
+ * 1.04 AGC Changed to 5.07
+ * 1.05 AGC Tweaked for 5.08
+ * 1.06 AGC 5.10 Unix version uses SIGPIPE
+ * 1.07 AGC 5.16 with -p <port> specifier
+ * 1.08 AGC signal function type specifier
+ * 1.09 AGC Signals checked for definition: Amiga merge
+ * 1.10 AGC Main returns int not void
+ */
+
+Module "Main Program";
+Version "1.10";
+Author "Alan Cox";
+
+short post_boot; /* Set to 1 if game booted */
+
+#ifdef UNIX
+#define signal_function void
+#else
+#define signal_function int
+#endif
+
+signal_function SegV()
+{
+ Log("Segmentation Fault caused abort");
+ abort();
+}
+
+signal_function Bus()
+{
+ Log("Bus error caused abort");
+ abort();
+}
+
+signal_function Div0()
+{
+ Log("Divison by zero");
+ abort();
+}
+
+
+
+int main(argc,argv)
+int argc;
+char *argv[];
+{
+ extern int EditMode();
+ extern int WrapUp();
+ extern void SoftwareFailure();
+ extern int SysPort;
+ if(argc>=3&&strcmp(argv[1],"-p")==0)
+ {
+ SysPort=atoi(argv[2]);
+ if(SysPort<5000) /* Check RFC compliance */
+ {
+ fprintf(stderr,"Port number should be 5000 or higher for a service.\n");
+ exit(1);
+ }
+ argv+=2;
+ argc-=2;
+ }
+ printf("\
+Aberystwyth Multi-User Dungeon Server\n\
+(c) Copyright 1987-2002, Alan Cox.\n\
+Release 5.30.0, April 2002\n\n\
+Booting...\r");
+#ifdef SIGBUS
+ signal(SIGBUS,Bus);
+#endif
+#ifdef SIGSEGV
+ signal(SIGSEGV,SegV);
+#endif
+#ifdef SIGFPE
+ signal(SIGFPE,Div0);
+#endif
+#ifdef SIGPIPE
+ signal(SIGPIPE,SIG_IGN);
+#endif
+/* If we are run from init, escape from the console after reporting the
+ boot */
+#ifdef UNIX
+ if(getppid()==1)
+ {
+ close(0);
+ close(1);
+ close(2);
+ open("/dev/null",O_RDONLY);
+ open("syslog",O_WRONLY|O_APPEND);
+ open("syslog",O_WRONLY|O_APPEND);
+ }
+#endif
+ if(argc>2)
+ {
+ fprintf(stderr,"Arguments! - %s <universe>\n",argv[0]);
+ exit(1);
+ }
+ Log("Startup Commenced");
+ if(argv[1])
+ {
+ printf("Loading '%s'\r",argv[1]);
+ Log("Loading Universe '%s'",argv[1]);
+ LoadSystem(argv[1]);
+ Log("Universe Booted");
+ }
+ printf("%75s\rBoot Completed\n","");
+ Log("Startup Completed");
+ Log("IPC Server Starting");
+
+#ifdef TCP_WRAP
+ openlog("abermud",LOG_PID,LOG_MAIL);
+#endif
+
+ post_boot=1;
+ AddEvent(0,1); /* Queue Autoboot table */
+ IPCMain();
+ exit(0);
+}
+
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..5484712
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,75 @@
+
+
+CFILES = NoMalloc.c Main.c NewCmd.c AnsiBits.c TableDriver.c \
+ TabCommand.c CompileTable.c InsAndOuts.c System.c PlyCommand.c \
+ ObjCommand.c GenCommand.c SysSupport.c RoomCommands.c Editing.c \
+ Parser.c SubHandler.c SaveLoad.c ComDriver.c BootDaemon.c \
+ ComServer.c CondCode.c ActionCode.c TimeSched.c UserFile.c Daemons.c \
+ TableEditing.c Container.c ExitLogic.c ContCommand.c Snoop.c \
+ DarkLight.c Duplicator.c FlagControl.c UtilCommand.c ObjectEdit.c \
+ Class.c LookFor.c UserVector.c FlagName.c FindPW.c runaber.c IPCClean.c \
+ LibRwho.c AberRwho.c IPCDirect.c LibSocket.c ValidLogin.c \
+ BSX.c
+
+OFILES = NoMalloc.o Main.o NewCmd.o AnsiBits.o TableDriver.o \
+ TabCommand.o CompileTable.o InsAndOuts.o System.o PlyCommand.o \
+ ObjCommand.o GenCommand.o SysSupport.o RoomCommands.o Editing.o \
+ Parser.o SubHandler.o SaveLoad.o ComDriver.o BootDaemon.o \
+ ComServer.o CondCode.o ActionCode.o TimeSched.o UserFile.o Daemons.o \
+ TableEditing.o Container.o ExitLogic.o ContCommand.o Snoop.o \
+ DarkLight.o Duplicator.o FlagControl.o UtilCommand.o ObjectEdit.o \
+ Class.o LookFor.o UserVector.o FlagName.o LibRwho.o AberRwho.o \
+ IPCDirect.o LibSocket.o ValidLogin.o BSX.o
+
+
+HEADERS = System.h User.h Comms.h NoProto.h
+
+LDFLAGS =
+ECHO = /bin/echo
+MV = /bin/mv
+TOUCH = touch
+
+CC = gcc -Wall -pedantic
+
+all : server FindPW Run_Aber Reg docs
+ @${ECHO} AberMUD5 is up to date.
+
+server : ${OFILES}
+ ${CC} ${LDFLAGS} ${OFILES}
+ @${TOUCH} server
+ @${MV} server server.old
+ @${MV} a.out server
+
+Reg : Reg.o UserFile.o AnsiBits.o
+ ${CC} ${LDFLAGS} Reg.o UserFile.o AnsiBits.o -o Reg
+
+Reg.o : Reg.c System.h
+
+client : Socket.o Client.o
+ ${CC} ${LDFLAGS} Client.o Socket.o -lcurses -o client
+
+Socket.o : Socket.c
+
+Client.o : Client.c
+
+FindPW : UserFile.o FindPW.o AnsiBits.o
+ ${CC} ${LDFLAGS} FindPW.o UserFile.o AnsiBits.o -o FindPW
+
+FindPW.o : FindPW.c
+
+runaber.o : runaber.c
+
+Run_Aber : Run_Aber.o
+ ${CC} ${LDFLAGS} Run_Aber.o -o Run_Aber
+
+docs:
+ nroff -man DOC/Contents DOC/1-2 DOC/3 DOC/4 DOC/5 DOC/6 DOC/7 DOC/8 DOC/9 DOC/10 DOC/A >Manual.txt
+
+clean:
+ rm -f *.o *~ server FindPW Run_Aber Reg server.old Manual.txt
+
+
+${OFILES} : ${HEADERS}
+.PRECIOUS: ${CFILES} ${HEADERS}
+.DEFAULT: ${CFILES} ${HEADERS}
+
diff --git a/NewCmd.c b/NewCmd.c
new file mode 100644
index 0000000..b9698d7
--- /dev/null
+++ b/NewCmd.c
@@ -0,0 +1,423 @@
+#include "System.h"
+#include "User.h"
+#ifdef UNIX
+#include <unistd.h>
+#endif
+
+extern USER UserList[];
+
+Module "New Commands";
+Author "Alan Cox";
+Version "1.01";
+
+/*
+ * Implement the extra commands added to the dbase language for
+ * 5.12.
+ *
+ * 1.00 AGC Created
+ * 1.01 AGC FORKDUMP
+ * 1.02 AGC PROCDAEMON PROCSUBJECT PROCOBJECT
+ */
+
+void Act_SetI()
+{
+ int n=ArgNum();
+ ITEM *i=ArgItem();
+ if(n==1)
+ Item1=i;
+ else
+ Item2=i;
+}
+
+void Act_CDaemon()
+{
+ ITEM *t=ArgItem();
+ int v=ArgWord();
+ int n=ArgWord();
+ CDaemon(t,v,n,ArgWord());
+}
+
+int Cnd_Delete()
+{
+ char *x=TextOf(ArgText());
+#ifndef SECURE
+ if(unlink(x)==-1)
+ return(0);
+ return(1);
+#else
+ return(0);
+#endif
+}
+
+static char *String_Fetch(f)
+FILE *f;
+{
+ int len;
+ char *t;
+ if(fscanf(f,"%d:",&len)!=1)
+ return(NULL);
+ if(len<0)
+ return(NULL);
+ t=malloc(len+1);
+ if(t==NULL)
+ return(NULL);
+ if(fread(t,len+1,1,f)!=1)
+ {
+ free(t);
+ return(NULL);
+ }
+ return(t);
+}
+
+int Cnd_ULoad()
+{
+#ifndef SECURE
+ int ct=0;
+ char *t=TextOf(ArgText());
+ char *s[4];
+ ITEM *i=ArgItem();
+ FILE *f;
+ USERFLAG a;
+ f=fopen(t,"r");
+ if(f==NULL)
+ return(0);
+ if(fread((char *)&a,sizeof(USERFLAG),1,f)!=1)
+ {
+ fclose(f);
+ return(0);
+ }
+ while(ct<4)
+ {
+ s[ct]=String_Fetch(f);
+ if(s[ct]==NULL)
+ {
+ fclose(f);
+ while(--ct>0)
+ free(s[ct]);
+ return(0);
+ }
+ ct++;
+ }
+ fclose(f);
+/*
+ * Now set the values up witgh the real UserFlag2.
+ */
+ ct=0;
+ while(ct<8)
+ {
+ SetUserFlag(i,ct+8,a.uf_Flags[ct]);
+ ct++;
+ }
+/*
+ * Now set up the strings
+ */
+ ct=0;
+ while(ct<4)
+ {
+ TPTR t;
+ t=AllocText(s[ct]);
+ SetUText(i,ct+4,t);
+ FreeText(t);
+ free(s[ct]);
+ ct++;
+ }
+ return(1);
+#else
+ return(0);
+#endif
+}
+
+int Cnd_USave()
+{
+#ifndef SECURE
+ char *t=TextOf(ArgText());
+ int ct=0;
+ ITEM *i=ArgItem();
+ USERFLAG *u;
+ FILE *f=fopen(t,"w");
+ if(f==NULL)
+ return(0);
+ u=UserFlag2Of(i);
+ if(u==NULL)
+ {
+ fclose(f);
+ return(0);
+ }
+ if(fwrite((char *)u,sizeof(USERFLAG),1,f)!=1)
+ {
+ fclose(f);
+ return(0);
+ }
+ while(ct<4)
+ {
+ char *tmp=TextOf(GetUText(i,ct+4));
+ fprintf(f,"%d:",strlen(tmp));
+ if(fwrite((char *)tmp,strlen(tmp)+1,1,f)!=1)
+ {
+ fclose(f);
+ return(0);
+ }
+ ct++;
+ }
+ fclose(f);
+ return(1);
+#else
+ return(0);
+#endif
+}
+
+int Cnd_FLoad()
+{
+#ifndef SECURE
+ char *t=TextOf(ArgText());
+ int top=ArgNum(),bottom=ArgNum();
+ int *buffer;
+ int ct=0;
+ FILE *f=fopen(t,"r");
+ if(top<0||top>bottom||bottom>511||f==NULL)
+ {
+ if(f!=NULL)
+ fclose(f);
+ return(0);
+ }
+ buffer=(int *)malloc(sizeof(int)*(bottom-top+1));
+ if(buffer==NULL)
+ {
+ fclose(f);
+ return(0);
+ }
+ if(fread((char *)buffer,sizeof(int)*(bottom-top+1),1,f)!=1)
+ {
+ fclose(f);
+ free((char *)buffer);
+ return(0);
+ }
+ while(top<=bottom)
+ {
+ SetFlag(top,buffer[ct]);
+ ct++;
+ top++;
+ }
+ free((char *)buffer);
+ fclose(f);
+ return(1);
+#else
+ return(0);
+#endif
+}
+
+int Cnd_FSave()
+{
+#ifndef SECURE
+ char *t=TextOf(ArgText());
+ int *bp;
+ int top=ArgNum(),bottom=ArgNum();
+ FILE *f=fopen(t,"w");
+ int *buffer;
+ if(f==NULL)
+ {
+ return(0);
+ }
+ if(top<bottom||top<0||bottom>511)
+ {
+ fclose(f);
+ return(0);
+ }
+ buffer=(int *)malloc(sizeof(int)*(bottom-top+1));
+ if(buffer==NULL)
+ {
+ fclose(f);
+ return(0);
+ }
+ bp=buffer;
+ while(top<=bottom)
+ {
+ *bp=GetFlag(top);
+ top++;
+ }
+ if(fwrite((char *)buffer,sizeof(int)*(bottom-top+1),1,f)!=1)
+ {
+ free(buffer);
+ fclose(f);
+ return(0);
+ }
+ fclose(f);
+ free(buffer);
+ return(1);
+#else
+ return(0);
+#endif
+}
+
+void Act_Getvis()
+{
+ ITEM *i=ArgItem();
+ int n=ArgNum();
+ SetFlag(n,i->it_Perception);
+}
+
+void Act_ForkDump()
+{
+ char *x=TextOf(ArgText());
+ int ct;
+ int pid=fork();
+ if(pid==-1)
+ {
+ Log("Dump failed - bad fork");
+ return;
+ }
+ if(pid!=0)
+ return;
+/*
+ * Child now does some work
+ */
+ ct=0;
+ while(ct<MAXUSER)
+ {
+ if(UserList[ct].us_Item!=NULL)
+ RemoveUser(ct);
+ ct++;
+ }
+ DisintegrateAll();
+ DisintegrateAll();
+ SaveSystem(x);
+ exit(0);
+}
+
+void Act_SetExit()
+{
+ ITEM *from=ArgItem();
+ int dn=ArgNum();
+ ITEM *to=ArgItem();
+ GENEXIT *g=(GENEXIT *)FindSub(from,KEY_GENEXIT);
+ if(g==NULL)
+ {
+ MakeGenExit(from);
+ g=(GENEXIT *)FindSub(from,KEY_GENEXIT);
+ }
+ if(dn<0||dn>11)
+ {
+ Log("Bad Setexit");
+ }
+ LockItem(to);
+ if(g->ge_Dest[dn]!=NULL)
+ UnlockItem(g->ge_Dest[dn]);
+ g->ge_Dest[dn]=to;
+}
+
+void Act_DelExit()
+{
+ ITEM *from=ArgItem();
+ int dn=ArgNum();
+ GENEXIT *g=(GENEXIT *)FindSub(from,KEY_GENEXIT);
+ if(dn<0||dn>11)
+ {
+ Log("Invalid DelExit");
+ return;
+ }
+ if(g==NULL)
+ return;
+ if(g->ge_Dest[dn]!=NULL)
+ {
+ UnlockItem(g->ge_Dest[dn]);
+ g->ge_Dest[dn]=NULL;
+ }
+}
+
+
+int Cnd_ProcDaemon()
+{
+ ITEM *i=ArgItem();
+ int ct=0;
+ while(i!=NULL && ct<20)
+ {
+ if(i->it_DaemonTable)
+ {
+ if(ExecTable(i->it_DaemonTable)==1)
+ return(1);
+ }
+ i=i->it_Superclass;
+ ct++;
+ }
+ return 0;
+}
+
+int Cnd_ProcSubject()
+{
+ ITEM *i=ArgItem();
+ int ct=0;
+ while(i!=NULL && ct<20)
+ {
+ if(i->it_SubjectTable)
+ {
+ if(ExecTable(i->it_SubjectTable)==1)
+ return(1);
+ }
+ i=i->it_Superclass;
+ ct++;
+ }
+ return 0;
+}
+
+int Cnd_ProcObject()
+{
+ ITEM *i=ArgItem();
+ int ct=0;
+ while(i!=NULL && ct<20)
+ {
+ if(i->it_ObjectTable)
+ {
+ if(ExecTable(i->it_ObjectTable)==1)
+ return(1);
+ }
+ i=i->it_Superclass;
+ ct++;
+ }
+ return 0;
+}
+
+
+int Cnd_GetSuper()
+{
+ ITEM *i=ArgItem();
+ int icode=ArgNum();
+ if(i->it_Superclass==NULL)
+ return 0;
+ if(icode==1)
+ Item1=i->it_Superclass;
+ if(icode==2)
+ Item2=i->it_Superclass;
+ return 1;
+}
+
+void Act_SetSuper()
+{
+ ITEM *it=ArgItem();
+ ITEM *i2=ArgItem();
+
+ if(it->it_Superclass!=NULL)
+ UnlockItem(it->it_Superclass);
+ if(it==i2)
+ it->it_Superclass=NULL;
+ else
+ {
+ LockItem(i2);
+ it->it_Superclass=i2;
+ }
+}
+
+int Cnd_Member()
+{
+ ITEM *it=ArgItem();
+ ITEM *cl=ArgItem();
+ int ct=0;
+ while(it->it_Superclass!=NULL && ct<20)
+ {
+ if(it->it_Superclass==cl)
+ return(1);
+ it=it->it_Superclass;
+ ct++;
+ }
+ return(0);
+}
+
diff --git a/NoMalloc.c b/NoMalloc.c
new file mode 100644
index 0000000..f4a4c5e
--- /dev/null
+++ b/NoMalloc.c
@@ -0,0 +1,7 @@
+/*
+ * If you don't use the quick malloc library
+ * or it doesn't work on your host we have to
+ * fake this function
+ */
+
+long MemFree(){return(-1L);}
diff --git a/NoProto.h b/NoProto.h
new file mode 100644
index 0000000..437e947
--- /dev/null
+++ b/NoProto.h
@@ -0,0 +1,855 @@
+/*
+ * If you have full ANSI prototyping this file will help keep everything
+ * as the right form of arguments. All the VARARG cases are identified here
+ * to aid porting, as are any known bugs
+ */
+
+/* SYSTEM.C */
+
+extern long TextMemory;
+extern long ItemMemory;
+extern long SubMemory;
+extern void ErrFunc(char *,char *,char *,int,char *);
+extern void Log();
+extern char *AllocFunc(int,char *,char *,int,char *);
+extern TPTR TextList[2][75];
+extern TPTR AllocText(char *);
+extern TPTR AllocComment(char *);
+extern TPTR QuickAllocText(char *);
+extern long CountTexts(void);
+extern long TextSize(void);
+extern long TextNumber(TPTR);
+extern char *TextOf(TPTR);
+extern void FreeText(TPTR);
+extern void FreeComment(TPTR);
+extern int UnlinkItem(ITEM *);
+extern int LinkItem(ITEM *,ITEM *);
+extern ITEM *ItemList;
+extern ITEM *CreateItem(char *,int,int);
+extern int FreeItem(ITEM *);
+extern void LockItem(ITEM *);
+extern void UnlockItem(ITEM *);
+extern void SetState(ITEM *,short);
+extern void SetVocab(ITEM *,short,short);
+extern int WordMatch(ITEM *,short,short);
+extern int CanSee(short,ITEM *);
+extern ITEM *FindMaster(short,short,short);
+extern ITEM *NextMaster(short,ITEM *,short,short);
+extern ITEM *FindIn(short,ITEM *,short,short);
+extern ITEM *NextIn(short,ITEM *,short,short);
+extern SUB *FindSub(ITEM *,short);
+extern SUB *NextSub(SUB *,short);
+extern SUB *AllocSub(ITEM *,short,short);
+extern void FreeSub(ITEM *,SUB *);
+extern int Contains(ITEM *,ITEM *);
+extern ITEM *FindContains(short,ITEM *,short,short);
+extern ITEM *NextContains(short,ITEM *,ITEM *,short,short);
+extern long MasterNumber(ITEM *);
+extern int ValidItem(ITEM *); /* Used for a nasty hack in daemons
+ (temporary function) */
+extern long CountItems(void);
+extern ITEM *GetNextPointer(void); /* Hacks for DOCLASS */
+extern void SetNextPointer(ITEM *);
+extern ITEM *FindInByClass(short,ITEM *,short);
+extern ITEM *NextInByClass(short,ITEM *,short); /* Hacked about for DOCLASS */
+
+#ifdef CHECK_ITEM
+extern int ICheck(ITEM *,int,char *);
+#endif
+
+#ifdef CHECK_TXT
+extern int TCheck(TPTR,int,char *);
+#endif
+
+/* SYSSUPPORT.C */
+
+extern PLAYER *PlayerOf();
+extern OBJECT *ObjectOf();
+extern ROOM *RoomOf();
+extern USERFLAG *UserFlagOf();
+extern CONTAINER *ContainerOf();
+extern int UserOf();
+extern int IsUser();
+extern int IsRoom();
+extern int IsPlayer();
+extern int IsObject();
+extern void SendItemDirect();
+extern void SendItem(); /* VARARGS */
+extern int IsCalled();
+extern void SetName();
+extern int ArchWizard(); /* OPTION TO READ FROM CONFIG FILE DESIRABLE */
+extern char *NameOf();
+extern char *CNameOf(); /* 128 BYTE LIMIT */
+extern short LevelOf();
+extern void Place();
+extern void XPlace();
+extern void RemoveUser();
+extern void ExitUser();
+extern int CountUsers();
+extern int IsBlind();
+extern int IsDeaf();
+extern void ByeBye();
+extern void DescribeItem();
+extern void DoesAction(); /* VARARGS */
+extern void DoesTo(); /* VARARGS */
+extern void DoesToPlayer(); /* VARARGS */
+/*
+ * CMD_LOOK() and these three functions + Broadcast ought to work
+ * on mobiles which are being snooped.
+ */
+extern ITEM *FindSomething();
+extern void SetPrompt();
+extern ITEM *ExitOf();
+extern ITEM *DoorOf();
+extern void Broadcast();
+extern void SendEdit(); /* VARARGS */
+extern void TimeOut(); /* UNUSED */
+extern void SetUserTitle(); /* VARARG */
+extern void SetUserPicture(); /* VARARG */
+extern int IsLit(); /* Belongs in DarkLight ? */
+extern void MemoryAlert(); /* Not dramatic enough */
+extern int IsUnique();
+extern int ItemNumber();
+
+/* SUBHANDLER.C */
+
+extern int MakeRoom();
+extern int UnRoom();
+extern int MakeObject();
+extern int UnObject();
+extern int MakePlayer();
+extern int UnPlayer();
+extern int MakeGenExit();
+extern int UnGenExit();
+extern CONDEXIT *MakeCondExit();
+extern CONDEXIT *MakeNLCondExit();
+extern int UnCondExit();
+extern CONDEXIT *FindCondExit();
+extern MSGEXIT *MakeMsgExit();
+extern MSGEXIT *MakeNLMsgExit();
+extern int UnMsgExit();
+extern MSGEXIT *FindMsgExit();
+extern int AddChain();
+extern int AddNLChain();
+extern CHAIN *FindChain();
+extern int RemoveChain();
+extern void SynchChain();
+extern CONTAINER *BeContainer();
+extern int UnContainer();
+extern int GetUserFlag();
+extern ITEM *GetUserItem();
+extern void SetUserFlag();
+extern void SetUserItem();
+extern int UnUserFlag();
+extern void InitUserFlag();
+extern int MakeInherit();
+extern int UnInherit();
+extern ITEM *Inheritor();
+extern INOUTHERE *FindIOH();
+extern void KillIOH();
+extern INOUTHERE *GetIOH();
+extern void SetInMsg();
+extern void SetOutMsg();
+extern void SetHereMsg();
+extern char *GetInMsg();
+extern char *GetOutMsg();
+extern char *GetHereMsg();
+extern void SetUText();
+extern TPTR GetUText();
+
+/* ACTIONCODE.C */
+
+extern short ClassMask;
+extern LINE *ClassLine;
+extern short ClassMode1,ClassMode2;
+
+extern void Act_Get();
+extern void Act_Drop();
+extern void Act_Wear();
+extern void Act_Remove();
+extern void Act_Create();
+extern void Act_Destroy();
+extern void Act_Swap();
+extern void Act_Place();
+extern void Act_PutIn();
+extern void Act_TakeOut();
+extern void Act_CopyOF();
+extern void Act_CopyFO();
+extern void Act_CopyFF();
+extern void Act_WhatO();
+extern void Act_GetO();
+extern void Act_Weigh();
+extern void Act_Set();
+extern void Act_Clear();
+extern void Act_PSet();
+extern void Act_PClear();
+extern void Act_Let();
+extern void Act_Add();
+extern void Act_Sub();
+extern void Act_Mul();
+extern void Act_Div();
+extern void Act_Mod();
+extern void Act_AddF();
+extern void Act_SubF();
+extern void Act_MulF();
+extern void Act_DivF();
+extern void Act_ModF();
+extern void Act_Random();
+extern void Act_Move();
+extern void Act_Goto();
+extern void Act_Weight();
+extern void Act_Size();
+extern void Act_OSet();
+extern void Act_OClear();
+extern void Act_RSet();
+extern void Act_RClear();
+extern void Act_CSet();
+extern void Act_CClear();
+extern void Act_PutBy();
+extern void Act_Inc();
+extern void Act_Dec();
+extern void Act_SetState();
+extern void Act_Prompt();
+extern void Act_Print();
+extern void Act_Score();
+extern void Act_Message();
+extern void Act_Msg();
+extern void Act_ListObj();
+extern void Act_ListAt();
+extern void Act_Inven();
+extern void Act_Desc();
+extern void Act_End();
+extern void Act_Done();
+extern void Act_NotDone();
+extern void Act_Ok();
+extern void Act_Abort();
+extern void Act_Save();
+extern void Act_NewText();
+extern void Act_Process();
+extern void Act_DoClass();
+extern void Act_Give();
+extern void Act_DoesAction();
+extern void Act_DoesTo();
+extern void Act_DoesToPlayer();
+extern void Act_PObj();
+extern void Act_PLoc();
+extern void Act_PName();
+extern void Act_PCName();
+extern void Act_Daemon();
+extern void Act_AllDaemon();
+extern void Act_HDaemon();
+extern void Act_When();
+extern void Act_SetName();
+extern void Act_Dup();
+extern void Act_Points();
+extern void Act_Hurt();
+extern void Act_Cured();
+extern void Act_KillOff();
+extern int Act_If1(); /* Should be conditions !!! */
+extern int Act_If2();
+extern void Act_Bug();
+extern void Act_Typo();
+extern int Act_IsMe(); /* Should be condition */
+extern void Act_Broadcast();
+extern int Cnd_IsCalled(); /* Wrong file! */
+extern void Act_SetMe();
+extern void Act_Pronouns();
+extern void Act_Exits();
+extern void Act_PWChange();
+extern void PWVerify();
+extern void PWNew();
+extern void PWNewVerify();
+extern void Act_Snoop();
+extern void Act_UnSnoop();
+extern void Act_Debug();
+extern void Act_GetScore();
+extern void Act_GetStr();
+extern void Act_GetLev();
+extern void Act_SetScore();
+extern void Act_SetStr();
+extern void Act_SetLev();
+extern void Act_Shell(); /* MACHINE DEPENDANT THROUGHOUT */
+extern void Act_TreeDaemon();
+extern void Act_ChainDaemon();
+extern void Act_Means();
+extern void Act_CanGoto();
+extern void Act_CanGoBy();
+extern void Act_GetIFlag();
+extern void Act_SetIFlag();
+extern void Act_ClearIFlag();
+extern void Act_Parse();
+extern void Act_Comment();
+extern void Act_ComVocab();
+extern void Act_Command();
+extern void Act_AutoVerb();
+extern int Cnd_ClassAt(); /* Some migrants who should be in condition */
+extern int Cnd_DupOf();
+extern void Act_MasterOf();
+extern int Cnd_IfDark(); /* More migrants */
+extern void Act_Visibility();
+extern void Act_GetParent();
+extern void Act_GetNext();
+extern void Act_GetChild();
+extern void Act_PExit();
+extern void Act_SetDesc();
+extern void Act_SetLong();
+extern void Act_SetShort();
+extern void Act_GetLong();
+extern void Act_GetShort();
+extern void Act_GetDesc();
+extern void Act_GetName();
+extern void Act_Swat();
+extern void Act_Flat();
+extern void Act_SetIn();
+extern void Act_SetOut();
+extern void Act_SetHere();
+extern void Act_FindMaster();
+extern void Act_NextMaster();
+extern void Act_FindIn();
+extern void Act_NextIn(); /* Same dangers of moving items as with system.c */
+extern void Act_LenText();
+extern void Act_Field();
+extern void Act_GetUText();
+extern void Act_SetUText();
+extern void Act_Cat();
+extern void Act_Cls();
+extern void Act_Become();
+extern void Act_Alias();
+extern void Act_UnAlias();
+extern void Act_Unveil();
+extern int Cnd_SubStr();
+extern void Act_GetIn();
+extern void Act_GetOut();
+extern void Act_GetHere();
+extern void Act_Log();
+extern void Act_SetClass();
+extern void Act_UnSetClass();
+extern void Act_BitClear();
+extern void Act_BitSet();
+extern int Cnd_BitTest();
+
+/*
+ * Unimplemented or Unused
+ */
+
+extern void Act_Distance();
+extern void Act_WhichWay();
+extern void Act_PutO();
+extern void Act_Frig();
+extern void Act_NArg();
+extern void Act_NeedField();
+extern void Act_Mobiles();
+extern void Act_Dir();
+extern void Act_Rooms();
+
+/*
+ * Proposed Rope Logic
+ */
+
+extern void Act_TiedTo();
+extern void Act_PlaceRope();
+extern void Act_RopePrev();
+extern int Cnd_IsRope();
+extern int Cnd_IsTied();
+extern void Act_RopeNext();
+extern void Act_Tie();
+extern void Act_Untie();
+extern void Act_Join();
+extern void Act_CutRope();
+extern int Cnd_CanMoveRope();
+
+
+/* BOOTDAEMON.C */
+
+extern jmp_buf Oops;
+extern short SupercedeFlag;
+extern void IPCMain();
+
+/* COMSERVER.C */
+
+/*
+ * This module is the machine specific IPC binding
+ */
+
+extern int Current_UserList;
+
+extern int WrapUp();
+extern int SendBlock(); /* Needs IPC defs to specify args */
+/*
+ * Sendblock is the machine specific IPC send function. It is a non-blocking
+ * send passed the arguments defining the user by message PORT *, Where
+ * a PORT * can be defined to suit the ipc. A char pointer to a block, and
+ * its length to send. Errors when writing should cause a system failure
+ * if serious. If a users buffer space is full the function TimeOut should
+ * be called for the user in question.
+ */
+extern int SendTPacket();
+extern int SendNPacket();
+extern int GetPacket();
+/*
+ * GetPacket is supplied with a PORT * and a packet to read the data into.
+ * It should copy a complete packet into the buffer supplied, remembering
+ * that packets are variable length (length is supplied in send call).
+ * Serious errors should cause system failure.
+ */
+extern void Handle_Login();
+extern void InterpretPacket();
+extern void ProcessPackets();
+extern int Handle_Output();
+extern int Handle_Command();
+extern int Handle_CommForce();
+
+/*
+ * The module uses the remote functions OpenMPort() which should open
+ * the specified port number/address for read/write, and CloseMPort to
+ * close it. Note that the front end program needs to be able to sense
+ * a CloseMPort.
+ */
+
+/* COMMAND_DRIVER.C */
+
+extern void Command_Driver();
+extern void PermitInput();
+extern char *UserLastLine;
+extern void SendUser(); /* VARARGS */
+extern int NameGot();
+extern int Check_Password();
+extern int SetPlayerSex();
+extern int CreatePersona();
+extern int Run_Command();
+
+/* COMPILETABLE */
+
+extern int RememberToLockItem();
+extern void LockLockList();
+extern void LoadLineBuffer();
+extern int EncodeEntry();
+extern int EncodeTable();
+extern void WipeLine();
+extern void DeleteTable();
+extern long PairArg();
+extern char *NumText();
+extern void Decompress();
+
+/* CONDITIONCODE.C */
+
+extern char *Cnd_Table[];
+extern int FindCnd();
+extern int Cnd_At();
+extern int Cnd_NotAt();
+extern int Cnd_Present();
+extern int Cnd_Absent();
+extern int Cnd_Worn();
+extern int Cnd_NotWorn();
+extern int Cnd_Carried();
+extern int Cnd_NotCarr();
+extern int Cnd_IsAt();
+extern int Cnd_IsNotAt();
+extern int Cnd_IsBy();
+extern int Cnd_Zero();
+extern int Cnd_NotZero();
+extern int Cnd_Eq();
+extern int Cnd_NotEq();
+extern int Cnd_Gt();
+extern int Cnd_Lt();
+extern int Cnd_EqF();
+extern int Cnd_NeF();
+extern int Cnd_LtF();
+extern int Cnd_GtF();
+extern int Cnd_IsIn();
+extern int Cnd_IsNotIn();
+extern int Cnd_Adj1();
+extern int Cnd_Adj2();
+extern int Cnd_Noun1();
+extern int Cnd_Noun2();
+extern int Cnd_Prep();
+extern int Cnd_Chance();
+extern int Cnd_IsPlayer();
+extern int Cnd_IsUser();
+extern int Cnd_IsRoom();
+extern int Cnd_IsObject();
+extern int Cnd_State();
+extern int Cnd_PFlag();
+extern int Cnd_OFlag();
+extern int Cnd_RFlag();
+extern int Cnd_CFlag();
+extern int Cnd_CanPut();
+extern int Cnd_Level();
+extern int Cnd_IfDeaf();
+extern int Cnd_IfBlind();
+extern int Cnd_Arch();
+extern int Cnd_Is();
+extern int Cnd_ChanceLev();
+extern int Cnd_CanSee();
+extern int Cnd_IsClass();
+
+/* CONTAINER.C */
+
+extern int WeighUp();
+extern int WeightOf();
+extern int SizeContents();
+extern int SizeOfRec();
+extern int CanPlace(); /* SEE COMMENTS FOR LIMITS */
+
+/* CONTAINERCOMMANDS.C */
+
+extern void Cmd_ContainerShow();
+extern void Cmd_SetCFlag();
+extern void Cmd_SetVolume();
+
+/* DAEMONS.C */
+
+extern void RunDaemon();
+extern void AllDaemon();
+extern void HDaemon();
+extern void TreeDaemon();
+extern void ChainDaemon();
+
+/* DARKLIGHT.C */
+
+extern int IsDarkFor();
+extern int RecCheckDark();
+
+/* EDITING.C */
+
+extern void Cmd_Exorcise();
+extern void Cmd_Abort();
+extern void Cmd_AddWord();
+extern int FindFreeWord();
+extern void Cmd_AddVerb();
+extern void Cmd_AddNoun();
+extern void Cmd_AddAdj();
+extern void Cmd_AddPrep();
+extern void Cmd_AddPronoun();
+extern void Cmd_AddOrdinate();
+extern void Cmd_ItemInfo();
+extern void Cmd_ListItems();
+extern void Cmd_SetState();
+extern void Cmd_SetPerception();
+extern void Cmd_SetName();
+extern void Cmd_NewItem();
+extern void Cmd_DelItem();
+extern void Cmd_BeRoom();
+extern void Cmd_BeObject();
+extern void Cmd_BePlayer();
+extern void Cmd_BeContainer();
+extern void Cmd_UnRoom();
+extern void Cmd_UnObject();
+extern void Cmd_UnPlayer();
+extern void Cmd_UnContainer();
+extern void Cmd_SaveUniverse();
+extern void Cmd_StatMe();
+extern void Cmd_ListWord();
+extern void Cmd_DelWord();
+extern void Cmd_DelVerb();
+extern void Cmd_DelNoun();
+extern void Cmd_DelPronoun();
+extern void Cmd_DelAdj();
+extern void Cmd_DelPrep();
+extern void Cmd_DelOrdinate();
+extern void Cmd_Rename();
+extern void Cmd_Chain();
+extern void Cmd_UnChain();
+extern void Cmd_UFlagShow();
+extern void Cmd_SetUFlag();
+extern void Cmd_SetUItem();
+extern void Cmd_TestMode();
+extern void Cmd_EditMode();
+extern void Cmd_FreeMode();
+extern void Cmd_ShowFlag();
+extern void Cmd_SetFlag();
+extern void Cmd_SaveGame();
+extern void Cmd_LoadGame();
+extern void Cmd_Share();
+extern void Cmd_UnShare();
+extern void Cmd_Status();
+extern void Cmd_Which();
+
+/* EXITLOGIC.C */
+
+extern int TestCondExit();
+
+/* FLAGCONTROLLER.C */
+
+extern char *FlagName[];
+extern int GetFlagByName();
+extern void SetFlagName();
+extern char *GetFlagName();
+extern void Cmd_NameFlag();
+extern void Cmd_UnNameFlag();
+extern void Cmd_ListFlag();
+
+/* GENERALCOMMANDS.C */
+
+extern void Cmd_Invisible();
+extern void Cmd_Visible();
+extern void Cmd_Say();
+extern void Cmd_Place();
+
+/* INSANDOUTS.C */
+
+extern char *ExitName();
+extern void Cmd_NewExit();
+extern void Cmd_DelExit();
+extern void Cmd_MsgExit();
+extern void Cmd_MoveDirn();
+extern void Cmd_Exits();
+extern int CanGoto();
+extern void Act_WhereTo();
+extern void Act_DoorExit();
+extern int BackExit();
+
+/* OBJECTCOMMANDS.C */
+
+extern void Cmd_ObjectShow();
+extern void Cmd_SetOFlag();
+extern void Cmd_SetDesc();
+extern void Cmd_SetOSize();
+extern void Cmd_SetOWeight();
+extern void Cmd_SetActor();
+extern void Cmd_SetAction();
+
+/* OBJECTEDIT.C */
+
+extern void Cmd_ObjEdit();
+extern void Objedit_1();
+extern void Objedit_2();
+extern void Objedit_3();
+extern void Objedit_4();
+extern void Objedit_5();
+extern void Objedit_6();
+extern void Objedit_7();
+
+/* PLAYERCOMMANDS.C */
+
+extern void Cmd_PlayerShow();
+extern void Cmd_SetPFlag();
+extern void Cmd_SetPSize();
+extern void Cmd_SetPWeight();
+extern void Cmd_SetPStrength();
+extern void Cmd_SetPLevel();
+extern void Cmd_SetPScore();
+extern void Cmd_Users();
+
+/* ROOMCOMMANDS.C */
+
+extern void Cmd_SetShort();
+extern void Cmd_ShowRoom();
+extern void Cmd_SetRFlag();
+extern void Cmd_SetLong();
+extern void Cmd_Look();
+extern void Cmd_Goto();
+extern void Cmd_Brief();
+extern void Cmd_Verbose();
+extern void Cmd_SetPicture();
+
+/* SAVELOAD.C */
+
+extern short *SaveAction();
+extern short *LoadAction();
+extern void LoadLine();
+extern void SaveLine();
+extern void LoadTable();
+extern void SaveTable();
+extern void LoadAllTables();
+extern void SaveAllTable();
+extern int SaveSystem();
+extern int LoadSystem();
+extern ITEM *ItemFind();
+
+/* SNOOP.C */
+
+extern int StartSnoop();
+extern void StopSnoop();
+extern void StopSnoopOn();
+extern void StopAllSnoops();
+extern void StopSnoopsOn();
+extern void SnoopCheckString();
+extern int SnoopCheckRec();
+
+/* TABLECOMMANDS.C */
+
+extern void Cmd_ListTables();
+extern void Cmd_AddTable();
+extern void Cmd_DeleteTable();
+extern void Cmd_NewTable();
+extern void Cmd_ListTables();
+
+/* TABLEDRIVER.C */
+
+extern TABLE *TableList;
+extern TPTR TxtArg;
+extern TPTR TxtArg2;
+extern char TxBuf[];
+extern int System_Debug;
+
+extern void WipeFlags();
+extern int GetFlag();
+extern void SetFlag();
+extern TXT DummyTxt;
+extern ITEM DummyItem;
+extern LINE *CurrentLine;
+extern TABLE *CurrentTable;
+extern ITEM *Item1,*Item2,*Debugger;
+extern int Noun1,Adj1,Noun2,Adj2,Verb,Prep,Ord1,Ord2;
+extern short Traf[4];
+
+extern ITEM *Me();
+extern void SetMe();
+extern ITEM *Actor();
+extern int ArgNum();
+extern int ArgWord();
+extern ITEM *ArgItem();
+extern TPTR ArgText();
+extern void ParseArgs();
+extern int ArgMatch();
+extern int ExecBackground();
+extern int ExecTable();
+extern int RunLine();
+extern ITEM *FindAnItem();
+extern TABLE *FindTable();
+extern TABLE *NewTable();
+extern LINE *NewLine();
+extern LINE *FindLine();
+extern int DeleteLine();
+extern int UserAction();
+extern int UserDaemon();
+extern int RandPerc();
+
+/* TABLEEDITING.C */
+
+extern void Cmd_EditTable();
+extern void Tbl_Quit();
+extern void Tbl_Goto();
+extern void Tbl_Find();
+extern void Tbl_Top();
+extern long CountEntries();
+extern void Tbl_Bottom();
+extern void Tbl_Next();
+extern void Tbl_Previous();
+extern void Tbl_List();
+extern void Tbl_Insert();
+extern void Tbl_Edit();
+extern void Tbl_EditLine();
+extern void Tbl_DeleteLine();
+extern void Tbl_Driver();
+extern void OutLineBlock();
+extern void Cmd_SaveTable();
+
+/* TIMESCHEDULER.C */
+
+extern void AddEvent();
+extern void Scheduler();
+extern void KillEventQueue();
+extern void WipeEventQueue();
+
+/* USERFILE.C */
+
+extern int WriteRecord();
+extern int ReadRecord();
+extern int FindRecord();
+extern FILE *OpenUAF();
+extern void CloseUAF();
+extern int LoadPersona();
+extern int SavePersona();
+extern int FindFreeRecord();
+extern int SaveNewPersona();
+
+/* UTILCOMMAND.C */
+
+extern void Cmd_DoorPair();
+extern void Cmd_ShowAllObjects();
+extern void Cmd_ShowAllRooms();
+extern void Cmd_ShowAllPlayers();
+extern int ShowItemData();
+
+/* CLASS.C */
+
+extern void SetClassTxt();
+extern void SetClassName();
+extern TXT *GetClassTxt();
+extern char *GetClassName();
+extern short WhichClass();
+extern void ClassDescStr();
+extern void Cmd_ListClass();
+extern void Cmd_NameClass();
+extern void Cmd_SetClass();
+extern void Cmd_UnsetClass();
+
+/* DUPLICATOR.C */
+
+extern int Clone_Room();
+extern int Clone_Object();
+extern int Clone_Player();
+extern int Clone_GenExit();
+extern int Clone_MsgExit();
+extern int Clone_Chain();
+extern int Clone_Container();
+extern int Clone_UserFlag();
+extern int Clone_Inherit();
+extern ITEM *Clone_Item();
+extern int Duped();
+extern int Disintegrate();
+extern void DisintegrateAll();
+
+/* MAIN.C */
+
+extern void main();
+
+extern short post_boot;
+
+/* PARSER.C */
+
+extern WLIST *WordList;
+extern PCONTEXT ParserData[];
+extern short ParsingPersona;
+
+extern void SetPersona();
+extern PCONTEXT *GetContext();
+extern void ProLoad();
+extern void SetItData();
+extern long WordMemory;
+extern void AddWord();
+extern int FreeWord();
+extern char *FindWText();
+extern WLIST *FindInList();
+extern char *BreakWord();
+extern char *GetRestOfInput();
+extern char *FNxPhrs();
+extern char *WordPtr;
+extern char WordBuffer[];
+extern WLIST *GetWord();
+extern int GetOrd();
+extern char *GetParsedWord();
+extern void GetAll();
+extern int GetNumber();
+extern int GetThing();
+extern void SkipPrep();
+extern int GetPrep();
+extern int GetVerb();
+extern char *NextPhrase();
+
+/* FLAGNAME.C */
+
+extern char *PBitNames[];
+extern char *OBitNames[];
+extern char *RBitNames[];
+extern char *CBitNames[];
+extern int FindRBit();
+extern int FindPBit();
+extern int FindOBit();
+extern int FindCBit();
+extern char *RBitName();
+extern char *OBitName();
+extern char *PBitName();
+extern char *CBitName();
+extern void Cmd_RBitName();
+extern void Cmd_OBitName();
+extern void Cmd_PBitName();
+extern void Cmd_CBitName();
+extern void Cmd_ListRBits();
+extern void Cmd_ListOBits();
+extern void Cmd_ListPBits();
+extern void Cmd_ListCBits();
+
+/* _THE END_ */
diff --git a/ObjCommand.c b/ObjCommand.c
new file mode 100644
index 0000000..908d231
--- /dev/null
+++ b/ObjCommand.c
@@ -0,0 +1,341 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Commands To Do With Objects
+ *
+ * 1.00 AGC Original Version
+ * 1.01 AGC Updated to 5.06
+ * 1.02 AGC 5.07 user named bit flags added
+ */
+
+#include "System.h"
+
+Module "Object Commands";
+Version "1.02";
+Author "----*(A)";
+
+/* Changed From ShowObject for 8 char significance */
+
+
+void Cmd_ObjectShow(i)
+ITEM *i;
+{
+ int ct=0;
+ ITEM *a;
+ OBJECT *o;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Try EXAMINE.\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ o=ObjectOf(a);
+ if(o==NULL)
+ {
+ SendItem(i,"%s is not an object.\n",CNameOf(a));
+ return;
+ }
+ SendItem(i,"Object Name : %s\n",CNameOf(a));
+ SendItem(i,"Text(0): %s\n",TextOf(o->ob_Text[0]));
+ SendItem(i,"Text(1): %s\n",TextOf(o->ob_Text[1]));
+ SendItem(i,"Text(2): %s\n",TextOf(o->ob_Text[2]));
+ SendItem(i,"Text(3): %s\n",TextOf(o->ob_Text[3]));
+ SendItem(i,"Size : %d Weight : %d\n",
+ o->ob_Size,o->ob_Weight);
+ while(ct<16)
+ {
+ if(o->ob_Flags&(1<<ct))
+ SendItem(i,"%s ",OBitName(ct));
+ else
+ if(strcmp(OBitName(ct),"{unset}"))
+ SendItem(i,"-%s ",OBitName(ct));
+ ct++;
+ }
+ SendItem(i,"\n");
+}
+
+void Cmd_SetOFlag(i)
+ITEM *i;
+{
+ int c=0;
+ ITEM *a;
+ OBJECT *o;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No can do....\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ o=ObjectOf(a);
+ if(o==NULL)
+ {
+ SendItem(i,"%s is not an object.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ while(GetParsedWord())
+ {
+ if(!strlen(WordBuffer))
+ {
+ SendItem(i,"What flag though ?\n");
+ return;
+ }
+ if(*WordBuffer=='-')
+ {
+ c=FindOBit(WordBuffer+1);
+ if(c==-1)
+ {
+ SendItem(i,"Unknown flag %s.\n",WordBuffer+1);
+ return;
+ }
+ o->ob_Flags&=~(1<<c);
+ }
+ else
+ {
+ c=FindOBit(WordBuffer);
+ if(c==-1)
+ {
+ SendItem(i,"Unknown flag %s.\n",WordBuffer);
+ return;
+ }
+ o->ob_Flags|=(1<<c);
+ }
+
+ }
+}
+
+void Cmd_SetDesc(i)
+ITEM *i;
+{
+ int siz;
+ int n;
+ ITEM *a;
+ OBJECT *o;
+ char *BigBuffer;
+ FILE *f;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ o=ObjectOf(a);
+ if(o==NULL)
+ {
+ SendItem(i,"%s is not an object.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Which description number.\n");
+ return;
+ }
+ if((n<0)||(n>3))
+ {
+ SendItem(i,"Description out of range.\n");
+ return;
+ }
+ GetAll();
+ if(!strlen(WordBuffer))
+ {
+ SendEdit(i,"SetDesc #%d %s %d %s",ItemNumber(LevelOf(i),a),
+ CNameOf(a),(int)n,TextOf(o->ob_Text[n]));
+ return;
+ }
+ if(*WordBuffer=='*')
+ {
+ f=fopen(WordBuffer+1,"r");
+ if(f==NULL)
+ {
+ SendItem(i,"Sorry - can't open the file.\n");
+ return;
+ }
+ BigBuffer=malloc(2048);
+ if(BigBuffer==NULL)
+ {
+ SendItem(i,"Not enough memory.\n");
+ return;
+ }
+ if((siz=fread(BigBuffer,1,2048,f))==2048)
+ {
+ fclose(f);
+ free(BigBuffer);
+ SendItem(i,"Entry too large.\n");
+ return;
+ }
+ fclose(f);
+ if(BigBuffer[siz-1]=='\n')
+ BigBuffer[siz-1]=0;
+ BigBuffer[siz]=0; /* Convert data to C string */
+ BigBuffer[2047]=0; /* protection */
+ FreeText(o->ob_Text[n]);
+ o->ob_Text[n]=AllocText(BigBuffer);
+ free(BigBuffer);
+ }
+ else
+ {
+ FreeText(o->ob_Text[n]);
+ o->ob_Text[n]=AllocText(WordBuffer);
+ }
+}
+
+void Cmd_SetOSize(i)
+ITEM *i;
+{
+ int n;
+ ITEM *a;
+ OBJECT *o;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ o=ObjectOf(a);
+ if(o==NULL)
+ {
+ SendItem(i,"%s is not an object.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Bad Size Value.\n");
+ return;
+ }
+ o->ob_Size=n;
+}
+
+void Cmd_SetOWeight(i)
+ITEM *i;
+{
+ int n;
+ ITEM *a;
+ OBJECT *o;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ o=ObjectOf(a);
+ if(o==NULL)
+ {
+ SendItem(i,"%s is not an object.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Bad Weight Value.\n");
+ return;
+ }
+ o->ob_Weight=n;
+}
+
+void Cmd_SetActor(i)
+ITEM *i;
+{
+ ITEM *a;
+ int n;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Pardon ?\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ SkipPrep();
+ if(GetParsedWord()==NULL)
+ {
+ SendItem(i,"Which table ?\n");
+ return;
+ }
+ if(isdigit(*WordBuffer))
+ sscanf(WordBuffer,"%d",&n);
+ else
+ n=FindTableByName(WordBuffer);
+ if(n==-1)
+ {
+ SendItem(i,"No Such Table.\n");
+ return;
+ }
+ a->it_ActorTable=n;
+}
+
+
+void Cmd_SetAction(i)
+ITEM *i;
+{
+ ITEM *a;
+ int n;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Pardon ?\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ SkipPrep();
+ if(GetParsedWord()==NULL)
+ {
+ SendItem(i,"Which table ?\n");
+ return;
+ }
+ if(isdigit(*WordBuffer))
+ sscanf(WordBuffer,"%d",&n);
+ else
+ n=FindTableByName(WordBuffer);
+ if(n==-1)
+ {
+ SendItem(i,"No Such Table.\n");
+ return;
+ }
+ a->it_ActionTable=n;
+}
+
diff --git a/ObjectEdit.c b/ObjectEdit.c
new file mode 100644
index 0000000..b9e6b4a
--- /dev/null
+++ b/ObjectEdit.c
@@ -0,0 +1,305 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * ObjectEdit.c - Prompted Object Edit/Create (New For 5.05)
+ *
+ *
+ * AGC 1.00 Created This File
+ * 1.01 Fixed bug about #2 item, and prevented
+ * crashed if item is unobjected.
+ * 1.02 5.07 release version with bit flag names
+ * 1.03 Asks for desc 0 - restores prompt correctly
+ * on errors.
+ */
+
+#include "System.h"
+#include "User.h"
+
+Module "Object Edit";
+Version "1.03";
+Author "Alan Cox";
+
+extern USER UserList[];
+
+static ITEM *O_Item; /* Thing being edited */
+
+void Cmd_ObjEdit(ITEM *i)
+{
+ register short ct;
+ short u;
+ ITEM *j;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Eh ?\n");
+ return;
+ }
+ u=UserOf(i);
+ if(u==-1)
+ return;
+ ct=0;
+ while(ct<MAXUSER) /* Stop use by 2 at once */
+ {
+ if((UserList[ct].us_State>=AWAIT_OEDIT)&&
+ (UserList[ct].us_State<=AWAIT_OEND))
+ {
+ SendItem(i,"Sorry - Object editing in progress.\n");
+ SendUser(ct,"%s tried to use the object editor.\n",
+ CNameOf(i));
+ return;
+ }
+ ct++;
+ }
+ j=FindSomething(i,O_PARENT(i));
+ if(!j)
+ {
+ SendItem(i,"What is that ?\n");
+ return;
+ }
+ if(!IsObject(j))
+ {
+ SendItem(i,"%s is not an object.\n",CNameOf(j));
+ return;
+ }
+ LockItem(j);
+ SetPrompt(i,"NAME>");
+ SendEdit(i,"%s",NameOf(j));
+ O_Item=j;
+ UserList[u].us_State=AWAIT_OE1;
+}
+
+#define UOF(x) (UserList[x].us_Item)
+#define UST(x,y) (UserList[x].us_State=(y))
+#define UBUMP(x) (UserList[x].us_State++)
+
+void Objedit_1(short u, char *t)
+{
+ ITEM *i=UOF(u);
+ if(strlen(t))
+ {
+ SetName(O_Item,t);
+ }
+ SetPrompt(i,"STATE>");
+ SendEdit(i,"%d",O_STATE(O_Item));
+ UBUMP(u);
+ PermitInput(u);
+}
+
+void Objedit_2(short u, char *t)
+{
+ ITEM *i=UOF(u);
+ int v;
+ if(sscanf(t,"%d",&v))
+ {
+ if((v<0)||(v>3))
+ {
+ SendUser(u,"State out of range.\n");
+ SetPrompt(i,"-}--- ");
+ PermitInput(u);
+ return;
+ }
+ SetState(O_Item,(short)v);
+ }
+ if(!IsObject(O_Item))
+ {
+ SendItem(i,"%s is no longer an object!\n",CNameOf(O_Item));
+ UserList[u].us_State=AWAIT_COMMAND;
+ UnlockItem(O_Item);
+ SetPrompt(i,"-}--- ");
+ PermitInput(u);
+ return;
+ }
+ SetPrompt(i,"EXAMINE>");
+ SendEdit(i,"%s",TextOf(ObjectOf(O_Item)->ob_Text[3]));
+ UBUMP(u);
+ PermitInput(u);
+}
+
+void Objedit_3(short u, char *t)
+{
+ ITEM *i=UOF(u);
+ if(!IsObject(O_Item))
+ {
+ SendItem(i,"%s is no longer an object!\n",CNameOf(O_Item));
+ UserList[u].us_State=AWAIT_COMMAND;
+ SetPrompt(i,"-}--- ");
+ PermitInput(u);
+ UnlockItem(O_Item);
+ return;
+ }
+ if(strlen(t))
+ {
+ FreeText(ObjectOf(O_Item)->ob_Text[3]);
+ ObjectOf(O_Item)->ob_Text[3]=AllocText(t);
+ }
+ SetPrompt(i,"LOCATION>");
+ if(O_PARENT(O_Item))
+ SendEdit(i,"%s",CNameOf(O_PARENT(O_Item)));
+ else
+ SendEdit(i,"NONE");
+ UBUMP(u);
+ PermitInput(u);
+}
+
+void Objedit_4(short u, char *t)
+{
+ ITEM *i=UOF(u);
+ ITEM *j;
+ if(!IsObject(O_Item))
+ {
+ SendItem(i,"%s is no longer an object!\n",CNameOf(O_Item));
+ UserList[u].us_State=AWAIT_COMMAND;
+ SetPrompt(i,"-}--- ");
+ PermitInput(u);
+ UnlockItem(O_Item);
+ return;
+ }
+ if(strlen(t))
+ {
+ if(stricmp(t,"NONE")==0)
+ {
+ Place(O_Item,NULL);
+ }
+ else
+ {
+ WordPtr=t;
+ j=FindSomething(i,O_PARENT(i));
+ if(!j)
+ {
+ SendUser(u,"Unknown Location.\n");
+ SetPrompt(i,"-}--- ");
+ PermitInput(u);
+ return;
+ }
+ Place(O_Item,j);
+ }
+ }
+ SetPrompt(i,"SIZE>");
+ SendEdit(i,"%d",ObjectOf(O_Item)->ob_Size);
+ UBUMP(u);
+ PermitInput(u);
+}
+
+
+void Objedit_5(short u, char *t)
+{
+ ITEM *i=UOF(u);
+ int v;
+ if(!IsObject(O_Item))
+ {
+ SendItem(i,"%s is no longer an object!\n",CNameOf(O_Item));
+ UserList[u].us_State=AWAIT_COMMAND;
+ SetPrompt(i,"-}--- ");
+ PermitInput(u);
+ UnlockItem(O_Item);
+ return;
+ }
+ if(sscanf(t,"%d",&v))
+ {
+ ObjectOf(O_Item)->ob_Size=v;
+ }
+ SetPrompt(i,"WEIGHT>");
+ SendEdit(i,"%d",ObjectOf(O_Item)->ob_Weight);
+ UBUMP(u);
+ PermitInput(u);
+}
+
+char *FlagText(ITEM *i)
+{
+ static char buf[512];
+ int ct=0;
+ OBJECT *o=ObjectOf(i);
+ *buf=0;
+ while(ct<16)
+ {
+ if(o->ob_Flags&(1<<ct))
+ strcat(buf,OBitName(ct));
+ else
+ if(strcmp(OBitName(ct),"{unset}"))
+ {
+ strcat(buf,"-");
+ strcat(buf,OBitName(ct));
+ }
+ strcat(buf," ");
+ ct++;
+ }
+ return(buf);
+}
+
+void Objedit_6(short u, char *t)
+{
+ ITEM *i=UOF(u);
+ int v;
+ if(!IsObject(O_Item))
+ {
+ SendItem(i,"%s is no longer an object!\n",CNameOf(O_Item));
+ UserList[u].us_State=AWAIT_COMMAND;
+ SetPrompt(i,"-}--- ");
+ PermitInput(u);
+ UnlockItem(O_Item);
+ return;
+ }
+ if(sscanf(t,"%d",&v))
+ {
+ ObjectOf(O_Item)->ob_Weight=v;
+ }
+ SetPrompt(i,"FLAGS>");
+ SendEdit(i,"%s",FlagText(O_Item));
+ UBUMP(u);
+ PermitInput(u);
+}
+
+
+
+void Objedit_7(short u, char *t)
+{
+ char bf[300];
+ ITEM *i=UOF(u);
+ if(strlen(t))
+ {
+ sprintf(bf,"#%d %s",ItemNumber(LevelOf(i),O_Item),
+ CNameOf(O_Item));
+ strcat(bf," ");
+ strcat(bf,t);
+ WordPtr=bf;
+ Cmd_SetOFlag(i);
+ }
+ UBUMP(u);
+ SetPrompt(i,"Description 0>");
+ PermitInput(u);
+}
+
+
+void Objedit_8(short u, char *t)
+{
+ OBJECT *o;
+ ITEM *i=UOF(u);
+ if(!IsObject(O_Item))
+ {
+ SendItem(i,"%s is no longer an object!\n",CNameOf(O_Item));
+ UserList[u].us_State=AWAIT_COMMAND;
+ SetPrompt(i,"-}--- ");
+ PermitInput(u);
+ UnlockItem(O_Item);
+ return;
+ }
+ o=ObjectOf(O_Item);
+ UST(u,AWAIT_COMMAND);
+ if(*t)
+ {
+ FreeText(o->ob_Text[0]);
+ o->ob_Text[0]=AllocText(t);
+ }
+ UnlockItem(O_Item);
+ SetPrompt(i,"-}--- ");
+ PermitInput(u);
+}
+
+
diff --git a/Parser.c b/Parser.c
new file mode 100644
index 0000000..d368ee6
--- /dev/null
+++ b/Parser.c
@@ -0,0 +1,536 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Command Parsing Logic
+ *
+ * 1.00 AGC Created File
+ * 1.01 AGC Added ordinates
+ * 1.02 AGC Minor Fixes
+ * 1.03 AGC Fixes (incomplete) for noun,prep,verb of same text
+ * 1.04 AGC Sorted word list
+ * 1.05 AGC Knows / " ' : are one character tokens
+ * 1.06 AGC Buffers fixed to right size, dunno how it ever used to work....
+ * 1.07 AGC Strict ANSIfication
+ */
+
+#include "System.h"
+
+Module "Parser";
+Version "1.07";
+Author "----*(A)";
+
+/*
+ * The parser breaks the user input into words in the form requested
+ * by the user. It can
+ * Break a new word {skipping noise words}
+ * Decode a word
+ * Decode an {adjective}/noun pair {skipping unknowns}
+ * Get the rest of the input (through phrases)
+ * Skip to next phrase [,;. AND THEN define phrases]
+ *
+ */
+
+WLIST *WordList=NULL;
+PCONTEXT ParserData[MAXUSER];
+short ParsingPersona;
+
+/*
+ * Context Managers
+ */
+
+void SetPersona(int x)
+{
+ ParsingPersona=x;
+}
+
+PCONTEXT *GetContext(short u)
+{
+ if(u<0)
+ return(NULL);
+ return(&ParserData[u]);
+}
+
+void ProLoad(short prep, register int *ad, register int *no)
+{
+ switch(prep)
+ {
+ case 1: *ad=Me()->it_Adjective;
+ *no=Me()->it_Noun;
+ break;
+
+ case 2: *ad=ParserData[ParsingPersona].pa_It[0];
+ *no=ParserData[ParsingPersona].pa_It[1];
+ break;
+
+ case 3: *ad=ParserData[ParsingPersona].pa_Them[0];
+ *no=ParserData[ParsingPersona].pa_Them[1];
+ break;
+
+ case 4: *ad=ParserData[ParsingPersona].pa_Him[0];
+ *no=ParserData[ParsingPersona].pa_Him[1];
+ break;
+
+ case 5: *ad=ParserData[ParsingPersona].pa_Her[0];
+ *no=ParserData[ParsingPersona].pa_Her[1];
+ break;
+
+ case 6: *ad=ParserData[ParsingPersona].pa_There[0];
+ *no=ParserData[ParsingPersona].pa_There[1];
+ break;
+ default:
+ *ad=-1;
+ *no=-1;
+ break;
+ }
+}
+
+void SetItData(short u, ITEM *x, short a, short n)
+{
+ if(u==-1)
+ u=ParsingPersona;
+ if((IsPlayer(x))&&(x!=Me()))
+ {
+ ParserData[u].pa_Them[0]=a;
+ ParserData[u].pa_Them[1]=n;
+ if(PlayerOf(x)->pl_Flags&PL_MALE)
+ {
+ ParserData[u].pa_Him[0]=a;
+ ParserData[u].pa_Him[1]=n;
+ return;
+ }
+ if(PlayerOf(x)->pl_Flags&PL_FEMALE)
+ {
+ ParserData[u].pa_Her[0]=a;
+ ParserData[u].pa_Her[1]=n;
+ return;
+ }
+ ParserData[u].pa_It[0]=a;
+ ParserData[u].pa_It[1]=n;
+ return;
+ }
+ if(IsObject(x))
+ {
+ if((ObjectOf(x)->ob_Flags&OB_NOIT)==0)
+ {
+ ParserData[u].pa_It[0]=a;
+ ParserData[u].pa_It[1]=n;
+ }
+ }
+ if(IsRoom(x))
+ {
+ ParserData[u].pa_There[0]=a;
+ ParserData[u].pa_There[1]=n;
+ }
+}
+
+/*
+ * Word Managers
+ */
+
+
+void AddWord(char *name, short code, short type)
+{
+ register WLIST *a=Allocate(WLIST);
+ register WLIST *w,*p;
+ a->wd_Text=malloc(strlen(name)+1);
+ if(a->wd_Text==NULL)
+ Error("Out Of Memory");
+ strcpy(a->wd_Text,name);
+ a->wd_Code=code;
+ a->wd_Type=type;
+/*
+ * Sort word list.. mostly for speed of AddVerb etc
+ */
+ p=NULL;
+ w=WordList;
+ while(w!=NULL)
+ {
+ if(w->wd_Code>code)
+ break;
+ p=w;
+ w=w->wd_Next;
+ }
+ if(p==NULL)
+ {
+ a->wd_Next=WordList;
+ WordList=a;
+ }
+ else
+ {
+ p->wd_Next=a;
+ a->wd_Next=w;
+ }
+}
+
+int FreeWord(char *name, register short type)
+{
+ register WLIST *a,*b;
+ a=WordList;
+ b=NULL;
+ while(a)
+ {
+ if((a->wd_Type==type)&&(stricmp(a->wd_Text,name)==0))
+ {
+ if(b==NULL)
+ {
+ WordList=a->wd_Next;
+ free((char *)a);
+ }
+ else
+ {
+ b->wd_Next=a->wd_Next;
+ free((char *)a);
+ }
+ return(0);
+ }
+ b=a;
+ a=a->wd_Next;
+ }
+ return(-1);
+}
+
+char *FindWText(register int num, register short type)
+{
+ register WLIST *a;
+ a=WordList;
+ if(num==-1)
+ return("ANY");
+ if(num==-2)
+ return("NONE");
+ while(a)
+ {
+ if((a->wd_Type==type)&&(a->wd_Code==num))
+ {
+ return(a->wd_Text);
+ }
+ a=a->wd_Next;
+ }
+ return("<UNSET>");
+}
+
+/*
+ * We work on two word lists Words holds all the words
+ * Noise holds specific words to skip
+ */
+
+WLIST *FindInList(register WLIST *list, register char *word, register short type)
+{
+ if(list==NULL)
+ return(NULL); /* NULL is handle for null list */
+ while(list)
+ {
+ if(((type==0)||(list->wd_Type==type))&&(stricmp(list->wd_Text,word)==0))
+ {
+ return(list);
+ }
+ list=list->wd_Next;;
+ }
+ return(NULL);
+}
+
+char *BreakWord(register char *iptr, register char *fbuf,
+ WLIST *skiplist, short skiptype)
+/* returns next iptr wbuf should be 128 bytes */
+{
+ if((*iptr=='.')||(*iptr==';')||(*iptr==','))
+ return(NULL); /* Phrase end */
+ if((*iptr==':')||(*iptr=='"')||(*iptr=='/')||(*iptr=='\''))
+ {
+ *fbuf++=*iptr++;
+ *fbuf=0;
+ return(iptr);
+ }
+l1: while(*iptr)
+ if(isspace(*iptr))
+ iptr++;
+ else
+ break;
+ if(!*iptr)
+ return(NULL); /* List expired */
+ if((*iptr=='.')||(*iptr==';')||(*iptr==','))
+ return(NULL); /* Phrase end */
+ while(*iptr)
+ if((!isspace(*iptr))&&(*iptr!=',')&&(*iptr!=';')&&(*iptr!='.'))
+ *fbuf++=*iptr++;
+ else
+ break;
+ *fbuf=0;
+ if(stricmp(fbuf,"AND")==0)
+ return(NULL);
+ if(stricmp(fbuf,"THEN")==0)
+ return(NULL);
+ if(FindInList(skiplist,fbuf,skiptype))
+ goto l1;
+ return(iptr);
+}
+
+char *GetRestOfInput(register char *iptr, char *bfr)
+{
+ while(*iptr)
+ if(isspace(*iptr))
+ iptr++;
+ else
+ break;
+ strcpy(bfr,iptr);
+ iptr+=strlen(iptr);
+ return(iptr);
+}
+
+char *FNxPhrs(register char *iptr)
+{
+ static char fb[512];
+ register char *fbuf=fb;
+ if(iptr==NULL)
+ return(NULL);
+l1: while(*iptr)
+ if(isspace(*iptr))
+ iptr++;
+ else
+ break;
+ if(!*iptr)
+ return(NULL); /* List expired */
+ if((*iptr=='.')||(*iptr==';')||(*iptr==','))
+ {
+ iptr++;
+ return(iptr); /* Phrase end */
+ }
+ while(*iptr)
+ if(!isspace(*iptr))
+ *fbuf++=*iptr++;
+ else
+ break;
+ *fbuf=0;
+ if(stricmp(fb,"AND")==0)
+ return(iptr);
+ if(stricmp(fb,"THEN")==0)
+ return(iptr);
+ goto l1;
+}
+
+/*
+ * Globals For Normal Parsing
+ */
+
+char *WordPtr;
+char WordBuffer[514];
+
+WLIST *GetWord(void)
+{
+ WLIST *a;
+ WordPtr=BreakWord(WordPtr,WordBuffer,WordList,WD_NOISE);
+ if(!WordPtr)
+ return((WLIST *)-1);
+ a=FindInList(WordList,WordBuffer,0);
+ return(a);
+}
+
+int GetOrd(void)
+{
+ char *WRem=WordPtr;
+ WLIST *a=GetWord();
+ if(a==NULL)
+ {
+ WordPtr=WRem;
+ return(1);
+ }
+ if(a==(WLIST *)-1)
+ {
+ WordPtr=WRem;
+ return(1);
+ }
+ if(a->wd_Type!=WD_ORDIN)
+ {
+ WordPtr=WRem;
+ return(1);
+ }
+ return(a->wd_Code);
+}
+
+char *GetParsedWord(void)
+{
+ return(WordPtr=BreakWord(WordPtr,WordBuffer,WordList,WD_NOISE));
+}
+
+void GetAll(void)
+{
+ WordPtr=GetRestOfInput(WordPtr,WordBuffer);
+}
+
+int GetNumber(void)
+{
+ int a;
+ WordPtr=BreakWord(WordPtr,WordBuffer,WordList,WD_NOISE);
+ if(!WordPtr)
+ return(-1);
+ if(sscanf(WordBuffer,"%d",&a)==0)
+ return(-1);
+ return(a);
+}
+
+int GetThing(int *ad, int *no)
+{
+ char *a=WordPtr; /* Save of */
+ WLIST *b;
+ WLIST *t;
+ int posnoun=-1;
+ char *backptr;
+ *ad=-1;
+l1: backptr=WordPtr;
+ b=GetWord();
+ if(b==(WLIST *)-1)
+ {
+ WordPtr=a;
+ return(-1);
+ }
+ if(b==NULL)
+ goto l1; /* Dud word */
+ if(FindInList(WordList,WordBuffer,WD_PREP)&&
+ FindInList(WordList,WordBuffer,WD_NOUN))
+ {
+ if(GetWord()==(WLIST *)-1)
+ {
+ WordPtr=backptr;
+ b=GetWord(); /* Use noun */
+ }
+ else
+ {
+ WordPtr=backptr;
+ *no= -1;
+ return(-1);
+ }
+ }
+ t=FindInList(WordList,WordBuffer,WD_PRONOUN);
+ if(t)
+ {
+ ProLoad(t->wd_Code,ad,no);
+ return(0);
+ }
+ if(FindInList(WordList,WordBuffer,WD_ADJ))
+ {
+ t=FindInList(WordList,WordBuffer,WD_ADJ);
+ b=t;
+ }
+ else
+ goto l2;
+ t=FindInList(WordList,WordBuffer,WD_NOUN);
+ if(t)
+ posnoun=t->wd_Code; /* It might still be noun */
+ if(b)
+ *ad=b->wd_Code;
+l3: a=WordPtr;
+ b=GetWord();
+ if(b==(WLIST *)-1)
+ {
+ WordPtr=a;
+ if(posnoun)
+ {
+ *ad=-1;
+ *no=posnoun;
+ return(0);
+ }
+ return(-1);
+ }
+ if(b==NULL)
+ goto l3; /* Dud word */
+l2: if(!(b=FindInList(WordList,WordBuffer,WD_NOUN)))
+ {
+ WordPtr=a;
+ if(posnoun!=-1)
+ {
+ *no=posnoun; /* Adj/Noun clasher - noun form */
+ *ad=-1;
+ return(0);
+ }
+ if(!b)
+ return(-1);
+ }
+ *no=b->wd_Code;
+ return(0);
+}
+
+void SkipPrep(void) /* Skip any preposition which is next word */
+{
+ char *a=WordPtr;
+ WLIST *b=GetWord();
+ if(b==(WLIST *)-1)
+ {
+ WordPtr=a;
+ return;
+ }
+ if(b==NULL)
+ {
+ WordPtr=a;
+ return;
+ }
+ if(b->wd_Type!=WD_PREP)
+ {
+ WordPtr=a;
+ return;
+ }
+}
+
+int GetPrep(void)
+{
+ char *a=WordPtr;
+ register WLIST *b;
+l1: b=GetWord();
+ if(b==(WLIST *)-1)
+ {
+ WordPtr=a;
+ return(-1);
+ }
+ if(b==NULL)
+ goto l1; /* Dud word */
+ if(b->wd_Type!=WD_PREP)
+ {
+ b=FindInList(WordList,WordBuffer,WD_PREP);
+ if(!b)
+ {
+ WordPtr=a;
+ return(-1);
+ }
+ }
+ return(b->wd_Code);
+}
+
+int GetVerb(void)
+{
+ char *a=WordPtr;
+ register WLIST *b;
+ b=GetWord();
+ if(b==(WLIST *)-1)
+ {
+ WordPtr=a;
+ return(-1);
+ }
+ if(b==NULL)
+ {
+ WordPtr=a;
+ return(-1);
+ }
+ if(b->wd_Type!=WD_VERB)
+ {
+ b=FindInList(WordList,WordBuffer,WD_VERB);
+ if(!b)
+ {
+ WordPtr=a;
+ return(-1);
+ }
+ }
+ return(b->wd_Code);
+}
+
+char *NextPhrase(void)
+{
+ WordPtr=FNxPhrs(WordPtr);
+ return(WordPtr);
+}
+
diff --git a/PlyCommand.c b/PlyCommand.c
new file mode 100644
index 0000000..0b21251
--- /dev/null
+++ b/PlyCommand.c
@@ -0,0 +1,334 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Commands To Do With Players
+ *
+ * 1.00 AGC Original Version
+ * 1.01 AGC Upgraded to 5.06
+ * 1.02 AGC 5.07 Version using user defined bitnames
+ * 1.03 AGC Remote Addresses in Users
+ * 1.04 AGC Fixed formatting for >9 users.
+ * 1.05 AGC Added Slot Status Info
+ */
+
+#include "System.h"
+#include "User.h"
+
+extern USER UserList[];
+
+Module "Player Commands";
+Version "1.05";
+Author "Alan Cox";
+
+
+
+void Cmd_PlayerShow(i)
+ITEM *i;
+{
+ ITEM *a;
+ PLAYER *o;
+ int ct=0;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Try EXAMINE.\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ o=PlayerOf(a);
+ if(o==NULL)
+ {
+ SendItem(i,"%s is not a character.\n",CNameOf(a));
+ return;
+ }
+ SendItem(i,"Character Name : %s\n",CNameOf(a));
+ SendItem(i,"UserKey : %d ",o->pl_UserKey);
+ SendItem(i,"Size : %d ",o->pl_Size);
+ SendItem(i,"Weight : %d \n",o->pl_Weight);
+ SendItem(i,"Strength: %d ",o->pl_Strength);
+ SendItem(i,"Level : %d ",o->pl_Level);
+ SendItem(i,"Score : %d\n",o->pl_Score);
+ ct=0;
+ while(ct<16)
+ {
+ if(o->pl_Flags&(1<<ct))
+ SendItem(i,"%s ",PBitName(ct));
+ else
+ if(strcmp(PBitName(ct),"{unset}"))
+ SendItem(i,"-%s ",PBitName(ct));
+ ct++;
+ }
+ SendItem(i,"\n");
+}
+
+void Cmd_SetPFlag(i)
+ITEM *i;
+{
+ int c=0;
+ ITEM *a;
+ PLAYER *o;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No can do....\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ o=PlayerOf(a);
+ if(o==NULL)
+ {
+ SendItem(i,"%s is not a character.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ while(GetParsedWord())
+ {
+ if(!strlen(WordBuffer))
+ {
+ SendItem(i,"What flag though ?\n");
+ return;
+ }
+ if(*WordBuffer=='-')
+ {
+ c=FindPBit(WordBuffer+1);
+ if(c==-1)
+ {
+ SendItem(i,"Unknown flag %s.\n",WordBuffer+1);
+ return;
+ }
+ o->pl_Flags&=~(1<<c);
+ }
+ else
+ {
+ c=FindPBit(WordBuffer);
+ if(c==-1)
+ {
+ SendItem(i,"Unknown flag %s.\n",WordBuffer);
+ return;
+ }
+ o->pl_Flags|=(1<<c);
+ }
+ }
+}
+
+void Cmd_SetPSize(i)
+ITEM *i;
+{
+ int n;
+ ITEM *a;
+ PLAYER *p;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ p=PlayerOf(a);
+ if(p==NULL)
+ {
+ SendItem(i,"%s is not a character.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Bad Size Value.\n");
+ return;
+ }
+ p->pl_Size=n;
+}
+
+void Cmd_SetPWeight(i)
+ITEM *i;
+{
+ int n;
+ ITEM *a;
+ PLAYER *p;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ p=PlayerOf(a);
+ if(p==NULL)
+ {
+ SendItem(i,"%s is not a character.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Bad Weight Value.\n");
+ return;
+ }
+ p->pl_Weight=n;
+}
+
+void Cmd_SetPStrength(i)
+ITEM *i;
+{
+ int n;
+ ITEM *a;
+ PLAYER *p;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ p=PlayerOf(a);
+ if(p==NULL)
+ {
+ SendItem(i,"%s is not a character.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Bad Strength Value.\n");
+ return;
+ }
+ p->pl_Strength=n;
+}
+
+void Cmd_SetPLevel(i)
+ITEM *i;
+{
+ int n;
+ ITEM *a;
+ PLAYER *p;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ p=PlayerOf(a);
+ if(p==NULL)
+ {
+ SendItem(i,"%s is not a character.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Bad Level Value.\n");
+ return;
+ }
+ p->pl_Level=n;
+}
+
+void Cmd_SetPScore(i)
+ITEM *i;
+{
+ long n;
+ ITEM *a;
+ PLAYER *p;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ p=PlayerOf(a);
+ if(p==NULL)
+ {
+ SendItem(i,"%s is not a character.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Bad Score Value.\n");
+ return;
+ }
+ p->pl_Score=n;
+}
+
+void Cmd_Users(i)
+ITEM *i;
+{
+ int a=0;
+ int v=GetNumber();
+ while(a<MAXUSER)
+ {
+ if((UserList[a].us_Port)&&
+ (UserList[a].us_Item)&&
+ (CanSee(LevelOf(i),UserList[a].us_Item)))
+ {
+ if(Arch(i))
+ {
+ SendItem(i,"%-2d) %-20s %-40s (%d)\n",a,
+ UserList[a].us_Name,
+ UserList[a].us_UserName,
+ UserList[a].us_State);
+ }
+ else
+ SendItem(i,"%-40s %s\n",UserList[a].us_Name,
+ UserList[a].us_UserName);
+ }
+ else
+ {
+ if(Arch(i)&&v==1)
+ {
+ SendItem(i,"%-2d) %-20s %-40s (%d)\n",a,
+ "<free slot>","<unset>",
+ UserList[a].us_State);
+ }
+ if(Arch(i)&&v==2)
+ {
+ SendItem(i,"%-2d) %-20s %-40s (%d)\n",a,
+ "<free slot>",isalpha(*UserList[a].us_Name)?UserList[a].us_UserName:"<unset>",
+ UserList[a].us_State);
+ }
+ }
+ a++;
+ }
+}
diff --git a/Properties.c b/Properties.c
new file mode 100644
index 0000000..9345f4f
--- /dev/null
+++ b/Properties.c
@@ -0,0 +1,194 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Arbitary item properties
+ */
+
+#include "System.h" /* System includes and options */
+
+Module "Properties";
+Version "1.00";
+Author "----*(A)";
+
+/*
+ * 1.00 AGC Initial test version
+ */
+
+PropTable *PropertyList;
+
+void FreeAllProperties(i)
+ITEM *i;
+{
+ SHORTPROPLIST *sp=(SHORTPROPLIST *)FindSub(i,KEY_SHORTPROPLIST);
+ ITEMPROPLIST *ip=(ITEMPROPLIST *)FindSub(i,KEY_ITEMPROPLIST);
+ TEXTPROPLIST *tp=(TEXTPROPLIST *)FindSub(i,KEY_TEXTPROPLIST);
+ if(sp!=NULL)
+ {
+ free(sp->Data);
+ FreeSub(i,sp);
+ }
+ if(ip!=NULL)
+ {
+ free(ip->Data);
+ FreeSub(i,ip);
+ }
+ if(tp!=NULL)
+ {
+ free(tp->Data);
+ FreeSub(i,tp);
+ }
+}
+
+SHORTPROPLIST *GetShortPropPointer(i)
+ITEM *i;
+{
+ SHORTPROPLIST *sp=(SHORTPROPLIST *)FindSub(i,KEY_SHORTPROPLIST);
+ if(sp==NULL)
+ {
+ sp=(SHORTPROPLIST *)AllocSub(i,KEY_SHORTPROPLIST,sizeof(SHORTPROPLIST));
+ sp->Size=4; /* Start with 4 then move on */
+ sp->Used=0;
+ sp->Data=(SHORTPROPLIST *)malloc(sizeof(SHORTPROPLIST)*sp->Size);
+ if(sp->Data==NULL)
+ Error("Out of memory allocating a shortprop");
+ }
+ return(sp);
+}
+
+TEXTPROPLIST *GetTextPropPointer(i)
+ITEM *i;
+{
+ TEXTPROPLIST *sp=(TEXTPROPLIST *)FindSub(i,KEY_TEXTPROPLIST);
+ if(sp==NULL)
+ {
+ sp=(TEXTPROPLIST *)AllocSub(i,KEY_TEXTPROPLIST,sizeof(TEXTPROPLIST));
+ sp->Size=4; /* Start with 4 then move on */
+ sp->Used=0;
+ sp->Data=(TEXTPROPLIST *)malloc(sizeof(TEXTPROPLIST)*sp->Size);
+ if(sp->Data==NULL)
+ Error("Out of memory allocating a textprop");
+ }
+ return(sp);
+}
+
+ITEMPROPLIST *GetItemPropPointer(i)
+ITEM *i;
+{
+ ITEMPROPLIST *sp=(ITEMPROPLIST *)FindSub(i,KEY_ITEMPROPLIST);
+ if(sp==NULL)
+ {
+ sp=(ITEMPROPLIST *)AllocSub(i,KEY_ITEMPROPLIST,sizeof(ITEMPROPLIST));
+ sp->Size=4; /* Start with 4 then move on */
+ sp->Used=0;
+ sp->Data=(ITEMPROPLIST *)malloc(sizeof(ITEMPROPLIST)*sp->Size);
+ if(sp->Data==NULL)
+ Error("Out of memory allocating an itemprop");
+ }
+ return(sp);
+}
+
+
+void SetShortProp(i,p,n)
+ITEM *i;
+short p;
+short n;
+{
+ SHORTPROPLIST *sp=GetShortPropPointer(i);
+ int ct=0;
+ while(ct<sp->sp_Used)
+ {
+ if(sp->Data[ct].ps_Ident==p)
+ {
+ sp->Data[ct].ps_Data=n;
+ return;
+ }
+ ct++;
+ }
+ if(sp->sp_Used<sp->sp_Size)
+ {
+ sp->Data[sp->sp_Used].ps_Ident=p;
+ sp->Data[sp->sp_Used++].ps_Data=n;
+ LockPropertyNumber(p);
+ return;
+ }
+ sp->sp_Size*=2;
+ sp->sp_Data=(SHORTPROPLIST *)realloc(sp->sp_Data,sizeof(SHORTPROPLIST)*sp->sp_Size);
+ if(sp->sp_Data==NULL)
+ Error("Out of memory growing shortproplist");
+ sp->Data[sp->sp_Used].ps_Ident=p;
+ sp->Data[sp->sp_Used++].ps_Data=n;
+ LockPropertyNumber(p);
+}
+
+void SetItemProp(i,p,n)
+ITEM *i;
+short p;
+short n;
+{
+ ITEMPROPLIST *sp=GetItemPropPointer(i);
+ int ct=0;
+ while(ct<sp->sp_Used)
+ {
+ if(sp->Data[ct].ps_Ident==p)
+ {
+ sp->Data[ct].ps_Data=n;
+ return;
+ }
+ ct++;
+ }
+ if(sp->sp_Used<sp->sp_Size)
+ {
+ sp->Data[sp->sp_Used].ps_Ident=p;
+ sp->Data[sp->sp_Used++].ps_Data=n;
+ LockPropertyNumber(p);
+ return;
+ }
+ sp->sp_Size*=2;
+ sp->sp_Data=(ITEMPROPLIST *)realloc(sp->sp_Data,sizeof(ITEMPROPLIST)*sp->sp_Size);
+ if(sp->sp_Data==NULL)
+ Error("Out of memory growing itemproplist");
+ sp->Data[sp->sp_Used].ps_Ident=p;
+ sp->Data[sp->sp_Used++].ps_Data=n;
+ LockPropertyNumber(p);
+}
+
+void SetTextProp(i,p,n)
+ITEM *i;
+short p;
+short n;
+{
+ TEXTPROPLIST *sp=GetTextPropPointer(i);
+ int ct=0;
+ while(ct<sp->sp_Used)
+ {
+ if(sp->Data[ct].ps_Ident==p)
+ {
+ sp->Data[ct].ps_Data=n;
+ return;
+ }
+ ct++;
+ }
+ if(sp->sp_Used<sp->sp_Size)
+ {
+ sp->Data[sp->sp_Used].ps_Ident=p;
+ sp->Data[sp->sp_Used++].ps_Data=n;
+ LockPropertyNumber(p);
+ return;
+ }
+ sp->sp_Size*=2;
+ sp->sp_Data=(TEXTPROPLIST *)realloc(sp->sp_Data,sizeof(TEXTPROPLIST)*sp->sp_Size);
+ if(sp->sp_Data==NULL)
+ Error("Out of memory growing textproplist");
+ sp->Data[sp->sp_Used].ps_Ident=p;
+ sp->Data[sp->sp_Used++].ps_Data=n;
+ LockPropertyNumber(p);
+}
+
diff --git a/Prototype.h b/Prototype.h
new file mode 100644
index 0000000..6e4206a
--- /dev/null
+++ b/Prototype.h
@@ -0,0 +1,1001 @@
+/*
+ * If you have full ANSI prototyping this file will help keep everything
+ * as the right form of arguments.
+ */
+
+/* SYSTEM.C */
+
+extern void noreturn ErrFunc(char *,char *,char *,int,char *);
+extern void Log(char *fmt, ...);
+extern char *AllocFunc(int,char *,char *,int,char *);
+extern TPTR AllocText(char *);
+extern TPTR AllocComment(char *);
+extern TPTR QuickAllocText(char *);
+extern long CountTexts(void);
+extern long TextSize(void);
+extern long TextNumber(TPTR); /* Wants speeding up */
+extern char *TextOf(TPTR);
+extern void FreeText(TPTR);
+extern void FreeComment(TPTR);
+extern int UnlinkItem(ITEM *);
+extern int LinkItem(ITEM *,ITEM *);
+extern ITEM *ItemList;
+extern ITEM *CreateItem(char *,int,int);
+extern int FreeItem(ITEM *);
+extern void LockItem(ITEM *);
+extern void UnlockItem(ITEM *);
+extern void SetState(ITEM *,short);
+extern void SetVocab(ITEM *,short,short);
+extern int WordMatch(ITEM *,short,short);
+extern int CanSee(short,ITEM *);
+extern ITEM *FindMaster(short,short,short);
+extern ITEM *NextMaster(short,ITEM *,short,short);
+extern ITEM *FindIn(short,ITEM *,short,short);
+extern ITEM *NextIn(short,ITEM *,short,short); /* Items must not have moved */
+extern SUB *FindSub(ITEM *,short);
+extern SUB *NextSub(SUB *,short);
+extern SUB *AllocSub(ITEM *,short,short);
+extern void FreeSub(ITEM *,SUB *);
+extern int Contains(ITEM *,ITEM *);
+extern ITEM *FindContains(short,ITEM *,short,short);
+extern ITEM *NextContains(short,ITEM *,ITEM *,short,short);
+extern long MasterNumber(ITEM *);
+extern int ValidItem(ITEM *); /* Used for a nasty hack in daemons
+ (temporary function) */
+extern long CountItems(void);
+extern ITEM *GetNextPointer(void); /* Hacks for DOCLASS */
+extern void SetNextPointer(ITEM *);
+extern ITEM *FindInByClass(short,ITEM *,short);
+extern ITEM *NextInByClass(short,ITEM *,short); /* Hacked about for DOCLASS */
+extern void LineDump(void);
+
+#ifdef CHECK_ITEM
+extern int ICheck(ITEM *,int,char *);
+#endif
+
+#ifdef CHECK_TXT
+extern int TCheck(TPTR,int,char *);
+#endif
+
+/* SYSSUPPORT.C */
+
+extern PLAYER *PlayerOf(ITEM *);
+extern OBJECT *ObjectOf(ITEM *);
+extern ROOM *RoomOf(ITEM *);
+extern USERFLAG *UserFlagOf(ITEM *);
+extern USERFLAG *UserFlag2Of(ITEM *);
+extern CONTAINER *ContainerOf(ITEM *);
+extern int UserOf(ITEM *);
+extern int IsUser(ITEM *);
+extern int IsRoom(ITEM *);
+extern int IsPlayer(ITEM *);
+extern int IsObject(ITEM *);
+extern void SendItemDirect(ITEM *,char *);
+extern void SendItem(); /* VARARGS */
+extern int IsCalled(ITEM *,char *);
+extern void SetName(ITEM *,char *);
+extern int ArchWizard(ITEM *); /* OPTION TO READ FROM CONFIG FILE DESIRABLE */
+extern char *NameOf(ITEM *);
+extern char *CNameOf(ITEM *); /* 128 BYTE LIMIT */
+extern short LevelOf(ITEM *);
+extern void Place(ITEM *,ITEM *);
+extern void XPlace(ITEM *,ITEM *);
+extern void RemoveUser(unsigned int);
+extern void ExitUser(unsigned int);
+extern int CountUsers(void);
+extern int IsBlind(ITEM *);
+extern int IsDeaf(ITEM *);
+extern void ByeBye(ITEM *,char *);
+extern void DescribeItem(ITEM *,ITEM *);
+extern void DoesAction(); /* VARARGS */
+extern void DoesTo(); /* VARARGS */
+extern void DoesToPlayer(); /* VARARGS */
+/*
+ * CMD_LOOK() and these three functions + Broadcast ought to work
+ * on mobiles which are being snooped.
+ */
+extern ITEM *FindSomething(ITEM *,ITEM *);
+extern void SetPrompt(ITEM *,char *);
+extern ITEM *ExitOf(ITEM *,unsigned int);
+extern ITEM *DoorOf(ITEM *,unsigned int);
+extern void Broadcast(char *,int);
+extern void SendEdit(); /* VARARGS */
+extern void TimeOut(int); /* UNUSED */
+extern void SetUserTitle(); /* VARARG */
+extern int IsLit(ITEM *); /* Belongs in DarkLight ? */
+extern int IsUnique(short,short,short);
+extern int ItemNumber(short,ITEM *);
+
+/* SUBHANDLER.C */
+
+extern int MakeRoom(ITEM *);
+extern int UnRoom(ITEM *);
+extern int MakeObject(ITEM *);
+extern int UnObject(ITEM *);
+extern int MakePlayer(ITEM *);
+extern int UnPlayer(ITEM *);
+extern int MakeGenExit(ITEM *);
+extern int UnGenExit(ITEM *);
+extern CONDEXIT *MakeCondExit(ITEM *,ITEM *,short,short);
+extern CONDEXIT *MakeNLCondExit(ITEM *,ITEM *,short,short);
+extern int UnCondExit(ITEM *,CONDEXIT *);
+extern CONDEXIT *FindCondExit(ITEM *,short);
+extern MSGEXIT *MakeMsgExit(ITEM *,ITEM *,short,char *);
+extern MSGEXIT *MakeNLMsgExit(ITEM *,ITEM *,short,char *);
+extern int UnMsgExit(ITEM *,MSGEXIT *);
+extern MSGEXIT *FindMsgExit(ITEM *,short);
+extern int AddChain(ITEM *,ITEM *);
+extern int AddNLChain(ITEM *,ITEM *);
+extern CHAIN *FindChain(ITEM *,ITEM *);
+extern int RemoveChain(ITEM *,ITEM *);
+extern void SynchChain(ITEM *);
+extern CONTAINER *BeContainer(ITEM *);
+extern int UnContainer(ITEM *);
+extern int GetUserFlag(ITEM *,int);
+extern ITEM *GetUserItem(ITEM *,int);
+extern void SetUserFlag(ITEM *,int,int);
+extern void SetUserItem(ITEM *,int,ITEM *);
+extern int UnUserFlag(ITEM *);
+extern int UnUserBlock(USERFLAG *,ITEM *);
+extern void InitUserFlag(USERFLAG *);
+extern int MakeInherit(ITEM *,ITEM *);
+extern int UnInherit(ITEM *);
+extern ITEM *Inheritor(ITEM *);
+extern void UnUserText(ITEM *);
+extern void SetUText(ITEM *,int,TPTR);
+extern TPTR GetUText(ITEM *,int);
+extern INOUTHERE *FindIOH(ITEM *);
+extern void KillIOH(ITEM *);
+extern INOUTHERE *GetIOH(ITEM *);
+extern void SetInMsg(ITEM *,char *);
+extern void SetOutMsg(ITEM *,char *);
+extern void SetHereMsg(ITEM *,char *);
+extern char *GetInMsg(ITEM *);
+extern char *GetOutMsg(ITEM *);
+extern char *GetHereMsg(ITEM *);
+
+/* ACTIONCODE.C */
+
+extern short ClassMask;
+extern LINE *ClassLine;
+extern short ClassMode1,ClassMode2;
+
+extern void Act_Get(void);
+extern void Act_Drop(void);
+extern void Act_Wear(void);
+extern void Act_Remove(void);
+extern void Act_Create(void);
+extern void Act_Destroy(void);
+extern void Act_Swap(void);
+extern void Act_Place(void);
+extern void Act_PutIn(void);
+extern void Act_TakeOut(void);
+extern void Act_CopyOF(void);
+extern void Act_CopyFO(void);
+extern void Act_CopyFF(void);
+extern void Act_WhatO(void);
+extern void Act_GetO(void);
+extern void Act_Weigh(void);
+extern void Act_Set(void);
+extern void Act_Clear(void);
+extern void Act_PSet(void);
+extern void Act_PClear(void);
+extern void Act_Let(void);
+extern void Act_Add(void);
+extern void Act_Sub(void);
+extern void Act_Mul(void);
+extern void Act_Div(void);
+extern void Act_Mod(void);
+extern void Act_AddF(void);
+extern void Act_SubF(void);
+extern void Act_MulF(void);
+extern void Act_DivF(void);
+extern void Act_ModF(void);
+extern void Act_Random(void);
+extern void Act_Move(void);
+extern void Act_Goto(void);
+extern void Act_Weight(void);
+extern void Act_Size(void);
+extern void Act_OSet(void);
+extern void Act_OClear(void);
+extern void Act_RSet(void);
+extern void Act_RClear(void);
+extern void Act_CSet(void);
+extern void Act_CClear(void);
+extern void Act_PutBy(void);
+extern void Act_Inc(void);
+extern void Act_Dec(void);
+extern void Act_SetState(void);
+extern void Act_Prompt(void);
+extern void Act_Print(void);
+extern void Act_Score(void);
+extern void Act_Message(void);
+extern void Act_Msg(void);
+extern void Act_ListObj(void);
+extern void Act_ListAt(void);
+extern void Act_Inven(void);
+extern void Act_Desc(void);
+extern void Act_End(void);
+extern void Act_Done(void);
+extern void Act_NotDone(void);
+extern void Act_Ok(void);
+extern void Act_Abort(void);
+extern void Act_Save(void);
+extern void Act_NewText(void);
+extern void Act_Process(void);
+extern void Act_DoClass(void);
+extern void Act_Give(void);
+extern void Act_DoesAction(void);
+extern void Act_DoesTo(void);
+extern void Act_DoesToPlayer(void);
+extern void Act_PObj(void);
+extern void Act_PLoc(void);
+extern void Act_PName(void);
+extern void Act_PCName(void);
+extern void Act_Daemon(void);
+extern void Act_AllDaemon(void);
+extern void Act_HDaemon(void);
+extern void Act_When(void);
+extern void Act_SetName(void);
+extern void Act_Dup(void);
+extern void Act_Points(void);
+extern void Act_Hurt(void);
+extern void Act_Cured(void);
+extern void Act_KillOff(void);
+extern int Act_If1(void); /* Should be conditions !!! */
+extern int Act_If2(void);
+extern void Act_Bug(void);
+extern void Act_Typo(void);
+extern int Act_IsMe(void); /* Should be condition */
+extern void Act_Broadcast(void);
+extern int Cnd_IsCalled(void); /* Wrong file! */
+extern void Act_SetMe(void);
+extern void Act_Pronouns(void);
+extern void Act_Exits(void);
+extern void Act_PWChange(void);
+extern void PWVerify(short,char *);
+extern void PWNew(short,char *);
+extern void PWNewVerify(short,char *);
+extern void Act_Snoop(void);
+extern void Act_UnSnoop(void);
+extern void Act_Debug(void);
+extern void Act_GetScore(void);
+extern void Act_GetStr(void);
+extern void Act_GetLev(void);
+extern void Act_SetScore(void);
+extern void Act_SetStr(void);
+extern void Act_SetLev(void);
+extern void Act_Shell(void); /* MACHINE DEPENDANT THROUGHOUT */
+extern void Act_TreeDaemon(void);
+extern void Act_ChainDaemon(void);
+extern void Act_Means(void);
+extern void Act_CanGoto(void);
+extern void Act_CanGoBy(void);
+extern void Act_GetIFlag(void);
+extern void Act_SetIFlag(void);
+extern void Act_ClearIFlag(void);
+extern void Act_Parse(void);
+extern void Act_Comment(void);
+extern void Act_ComVocab(void);
+extern void Act_Command(void);
+extern void Act_AutoVerb(void);
+extern int Cnd_ClassAt(void); /* Some migrants who should be in condition */
+extern int Cnd_DupOf(void);
+extern void Act_MasterOf(void);
+extern int Cnd_IfDark(void); /* More migrants */
+extern void Act_Visibility(void);
+extern void Act_GetParent(void);
+extern void Act_GetNext(void);
+extern void Act_GetChild(void);
+extern void Act_PExit(void);
+extern void Act_SetDesc(void);
+extern void Act_SetLong(void);
+extern void Act_SetShort(void);
+extern void Act_GetLong(void);
+extern void Act_GetShort(void);
+extern void Act_GetDesc(void);
+extern void Act_GetName(void);
+extern void Act_Swat(void);
+extern void Act_Flat(void);
+extern void Act_SetIn(void);
+extern void Act_SetOut(void);
+extern void Act_SetHere(void);
+extern void Act_FindMaster(void);
+extern void Act_NextMaster(void);
+extern void Act_FindIn(void);
+extern void Act_NextIn(void); /* Same dangers of moving items as with system.c */
+extern void Act_LenText(void);
+extern void Act_Field(void);
+extern void Act_GetUText(void);
+extern void Act_SetUText(void);
+extern void Act_Cat(void);
+extern void Act_Cls(void);
+extern void Act_Become(void);
+extern void Act_Alias(void);
+extern void Act_UnAlias(void);
+extern void Act_Unveil(void);
+extern int Cnd_SubStr(void);
+extern void Act_GetIn(void);
+extern void Act_GetOut(void);
+extern void Act_GetHere(void);
+extern void Act_Log(void);
+extern void Act_SetClass(void);
+extern void Act_UnSetClass(void);
+extern void Act_BitClear(void);
+extern void Act_BitSet(void);
+extern int Cnd_BitTest(void);
+extern void Act_SPrint(void);
+extern void Act_User(void);
+extern void Act_Cls(void);
+extern void Act_GetVis(void);
+
+/*
+ * Unimplemented or Unused
+ */
+
+extern void Act_Distance(void);
+extern void Act_WhichWay(void);
+extern void Act_PutO(void);
+extern void Act_Frig(void);
+extern void Act_NArg(void);
+extern void Act_NeedField(void);
+extern void Act_Mobiles(void);
+extern void Act_Dir(void);
+extern void Act_Rooms(void);
+
+/*
+ * Proposed Rope Logic
+ */
+
+extern void Act_TiedTo(void);
+extern void Act_PlaceRope(void);
+extern void Act_RopePrev(void);
+extern int Cnd_IsRope(void);
+extern int Cnd_IsTied(void);
+extern void Act_RopeNext(void);
+extern void Act_Tie(void);
+extern void Act_Untie(void);
+extern void Act_Join(void);
+extern void Act_CutRope(void);
+extern int Cnd_CanMoveRope(void);
+
+extern int Cnd_IsNotBy(void);
+extern void Act_MessageTo(void);
+extern void Act_MsgTo(void);
+
+/* BOOTDAEMON.C */
+
+extern jmp_buf Oops;
+extern short SupercedeFlag;
+extern short SupercedeFlag;
+extern void IPCMain(void);
+
+/* BSX.c */
+
+BSXImage *BSXAllocate(char *,int);
+BSXImage *BSXFindFirst(void);
+BSXImage *BSXFindNext(BSXImage *);
+BSXImage *BSXFind(char *);
+void BSXDelete(BSXImage *);
+int BSXEncodePair(char *);
+void BSXDecodePair(unsigned char,char *);
+BSXImage *BSXLoadImage(char *,char *);
+void Cmd_DeleteBSX(ITEM *);
+void Cmd_LoadBSX(ITEM *);
+void Cmd_ListBSX(ITEM *);
+void Cmd_ShowBSX(ITEM *);
+void BSXDecompSend(int, BSXImage *);
+void Handle_BSXPacket(int, char *);
+void Act_BSXScene(void);
+void Act_BSXObject(void);
+
+/* COMSERVER.C */
+
+/*
+ * This module is the machine specific IPC binding
+ */
+
+extern int Current_UserList;
+extern short LineFaults(void);
+extern void FixLineFaults(void);
+
+extern int WrapUp(int);
+extern int SendBlock(PORT *, COMTEXT *, int);
+/*
+ * Sendblock is the machine specific IPC send function. It is a non-blocking
+ * send passed the arguments defining the user by message PORT *, Where
+ * a PORT * can be defined to suit the ipc. A char pointer to a block, and
+ * its length to send. Errors when writing should cause a system failure
+ * if serious. If a users buffer space is full the function TimeOut should
+ * be called for the user in question.
+ */
+extern int SendTPacket(PORT *, short, char *);
+extern int SendNPacket(PORT *, short, short, short, short, short);
+extern int GetPacket(PORT *, COMTEXT *);
+/*
+ * GetPacket is supplied with a PORT * and a packet to read the data into.
+ * It should copy a complete packet into the buffer supplied, remembering
+ * that packets are variable length (length is supplied in send call).
+ * Serious errors should cause system failure.
+ */
+extern void Handle_Login(char *);
+extern void InterpretPacket();
+extern void ProcessPackets(void);
+extern int Handle_Output(char *);
+extern int Handle_Command(int,char *);
+extern int Handle_CommForce(int,char *);
+
+/*
+ * The module uses the remote functions OpenMPort() which should open
+ * the specified port number/address for read/write, and CloseMPort to
+ * close it. Note that the front end program needs to be able to sense
+ * a CloseMPort.
+ */
+extern int CloseMPort(PORT *);
+
+/* COMMAND_DRIVER.C */
+
+extern void Command_Driver(int,short,char *);
+extern void PermitInput(int);
+extern char *UserLastLine;
+extern void BufOut(int, char *);
+extern void SendUser(int, char *, ...);
+extern int Name_Got(int,char *);
+extern int Check_Password(int,char *,int);
+extern int SetPlayerSex(int,char *);
+extern int SetPlayerEmail(int, char *);
+extern int CreatePersona(int,char *);
+extern int Run_Command(int,char *);
+
+/* COMPILETABLE */
+
+extern int RememberToLockItem(ITEM *);
+extern void LockLockList(void);
+extern void LoadLineBuffer(char *);
+extern int EncodeEntry(ITEM *,LINE *);
+extern int EncodeTable(ITEM *,TABLE *,FILE *);
+extern void WipeLine(LINE *);
+extern void DeleteTable(TABLE *);
+extern void FreeTableHeader(TABLE *);
+extern unsigned long PairArg(unsigned short *);
+extern char *NumText(int);
+extern void Decompress(LINE *,char *);
+
+/* CONDITIONCODE.C */
+
+extern char *Cnd_Table[];
+extern int FindCnd(char *);
+extern int Cnd_At(void);
+extern int Cnd_NotAt(void);
+extern int Cnd_Present(void);
+extern int Cnd_Absent(void);
+extern int Cnd_Worn(void);
+extern int Cnd_NotWorn(void);
+extern int Cnd_Carried(void);
+extern int Cnd_NotCarr(void);
+extern int Cnd_IsAt(void);
+extern int Cnd_IsNotAt(void);
+extern int Cnd_IsBy(void);
+extern int Cnd_Zero(void);
+extern int Cnd_NotZero(void);
+extern int Cnd_Eq(void);
+extern int Cnd_NotEq(void);
+extern int Cnd_Gt(void);
+extern int Cnd_Lt(void);
+extern int Cnd_EqF(void);
+extern int Cnd_NeF(void);
+extern int Cnd_LtF(void);
+extern int Cnd_GtF(void);
+extern int Cnd_IsIn(void);
+extern int Cnd_IsNotIn(void);
+extern int Cnd_Adj1(void);
+extern int Cnd_Adj2(void);
+extern int Cnd_Noun1(void);
+extern int Cnd_Noun2(void);
+extern int Cnd_Prep(void);
+extern int Cnd_Chance(void);
+extern int Cnd_IsPlayer(void);
+extern int Cnd_IsUser(void);
+extern int Cnd_IsRoom(void);
+extern int Cnd_IsObject(void);
+extern int Cnd_State(void);
+extern int Cnd_PFlag(void);
+extern int Cnd_OFlag(void);
+extern int Cnd_RFlag(void);
+extern int Cnd_CFlag(void);
+extern int Cnd_CanPut(void);
+extern int Cnd_Level(void);
+extern int Cnd_IfDeaf(void);
+extern int Cnd_IfBlind(void);
+extern int Cnd_Arch(void);
+extern int Cnd_Is(void);
+extern int Cnd_ChanceLev(void);
+extern int Cnd_CanSee(void);
+extern int Cnd_IsClass(void);
+
+/* CONTAINER.C */
+
+extern int WeighUp(ITEM *);
+extern int WeightOf(ITEM *);
+extern int SizeContents(ITEM *);
+extern int SizeOfRec(ITEM *,int);
+extern int CanPlace(ITEM *,ITEM *); /* SEE COMMENTS FOR LIMITS */
+
+/* CONTAINERCOMMANDS.C */
+
+extern void Cmd_ContainerShow(ITEM *);
+extern void Cmd_SetCFlag(ITEM *);
+extern void Cmd_SetVolume(ITEM *);
+
+/* DAEMONS.C */
+
+extern void RunDaemon(ITEM *,int,int,int);
+extern void AllDaemon(int,int,int);
+extern void HDaemon(ITEM *,int,int,int);
+extern void TreeDaemon(ITEM *,int,int,int);
+extern void ChainDaemon(ITEM *,int,int,int);
+extern void CDaemon(ITEM *,int,int,int);
+
+/* DARKLIGHT.C */
+
+extern int IsDarkFor(ITEM *);
+extern int RecCheckDark(ITEM *,short);
+
+/* EDITING.C */
+
+extern char CmdBuffer[512];
+extern void Cmd_Exorcise(ITEM *);
+extern void Cmd_Abort(ITEM *);
+extern void Cmd_AddWord(ITEM *,short);
+extern int FindFreeWord(short); /* MUCH TOO SLOW */
+extern void Cmd_AddVerb(ITEM *);
+extern void Cmd_AddNoun(ITEM *);
+extern void Cmd_AddAdj(ITEM *);
+extern void Cmd_AddPrep(ITEM *);
+extern void Cmd_AddPronoun(ITEM *);
+extern void Cmd_AddOrdinate(ITEM *);
+extern char *TabName(int);
+extern void Cmd_ItemInfo(ITEM *);
+extern void Cmd_ListItems(ITEM *);
+extern void Cmd_SetState(ITEM *);
+extern void Cmd_SetPerception(ITEM *);
+extern void Cmd_SetName(ITEM *);
+extern void Cmd_NewItem(ITEM *);
+extern void Cmd_DelItem(ITEM *);
+extern void Cmd_BeRoom(ITEM *);
+extern void Cmd_BeObject(ITEM *);
+extern void Cmd_BePlayer(ITEM *);
+extern void Cmd_BeContainer(ITEM *);
+extern void Cmd_UnRoom(ITEM *);
+extern void Cmd_UnObject(ITEM *);
+extern void Cmd_UnPlayer(ITEM *);
+extern void Cmd_UnContainer(ITEM *);
+extern void Cmd_SaveUniverse(ITEM *);
+extern void Cmd_StatMe(ITEM *);
+extern void Cmd_ListWord(ITEM *);
+extern void Cmd_DelWord(ITEM *,short);
+extern void Cmd_DelVerb(ITEM *);
+extern void Cmd_DelNoun(ITEM *);
+extern void Cmd_DelPronoun(ITEM *);
+extern void Cmd_DelAdj(ITEM *);
+extern void Cmd_DelPrep(ITEM *);
+extern void Cmd_DelOrdinate(ITEM *);
+extern void Cmd_Rename(ITEM *);
+extern void Cmd_Chain(ITEM *);
+extern void Cmd_UnChain(ITEM *);
+extern void Cmd_UFlagShow(ITEM *);
+extern void Cmd_SetUFlag(ITEM *);
+extern void Cmd_SetUItem(ITEM *);
+extern void Cmd_ShowFlag(ITEM *);
+extern void Cmd_SetFlag(ITEM *);
+extern void Cmd_Share(ITEM *);
+extern void Cmd_UnShare(ITEM *);
+extern void Cmd_TrackFlag(ITEM *);
+extern void Cmd_UnTrackFlag(ITEM *);
+extern void Cmd_ListTrack(ITEM *);
+extern void Cmd_Status(ITEM *);
+extern void Cmd_Which(ITEM *);
+extern void Cmd_Debugger(ITEM *);
+extern void Cmd_FindItem(ITEM *);
+extern void Cmd_FindFlag(ITEM *);
+extern void Cmd_Which(ITEM *);
+extern void Cmd_ShowSuperClass(ITEM *);
+extern void Cmd_SetSuperClass(ITEM *);
+
+/* EXITLOGIC.C */
+
+extern int TestCondExit(CONDEXIT *);
+
+/* FLAGCONTROLLER.C */
+
+extern char *FlagName[];
+extern int GetFlagByName(char *);
+extern void SetFlagName(short,char *);
+extern char *GetFlagName(short);
+extern void Cmd_NameFlag(ITEM *);
+extern void Cmd_UnNameFlag(ITEM *);
+extern void Cmd_ListFlags(ITEM *);
+
+/* GENERALCOMMANDS.C */
+
+extern void Cmd_Invisible(ITEM *);
+extern void Cmd_Visible(ITEM *);
+extern void Cmd_Say(ITEM *);
+extern void Cmd_Place(ITEM *);
+
+/* INSANDOUTS.C */
+
+extern char *ExitName(int);
+extern void Cmd_NewExit(ITEM *);
+extern void Cmd_DelExit(ITEM *);
+extern void Cmd_MsgExit(ITEM *);
+extern void Cmd_CondExit(ITEM *);
+extern void Cmd_MoveDirn(ITEM *,int);
+extern void Cmd_Exits(ITEM *,ITEM *);
+extern int CanGoto(ITEM *,ITEM *);
+extern void Act_WhereTo(void);
+extern void Act_DoorExit(void);
+extern int BackExit(int);
+
+/* OBJECTCOMMANDS.C */
+
+extern void Cmd_ObjectShow(ITEM *);
+extern void Cmd_SetOFlag(ITEM *);
+extern void Cmd_SetDesc(ITEM *);
+extern void Cmd_SetOSize(ITEM *);
+extern void Cmd_SetOWeight(ITEM *);
+extern void Cmd_SetActor(ITEM *);
+extern void Cmd_SetAction(ITEM *);
+
+/* OBJECTEDIT.C */
+
+extern void Cmd_ObjEdit(ITEM *);
+extern void Objedit_1(short,char *);
+extern void Objedit_2(short,char *);
+extern void Objedit_3(short,char *);
+extern void Objedit_4(short,char *);
+extern void Objedit_5(short,char *);
+extern void Objedit_6(short,char *);
+extern void Objedit_7(short,char *);
+extern void Objedit_8(short,char *);
+
+/* PLAYERCOMMANDS.C */
+
+extern void Cmd_PlayerShow(ITEM *);
+extern void Cmd_SetPFlag(ITEM *);
+extern void Cmd_SetPSize(ITEM *);
+extern void Cmd_SetPWeight(ITEM *);
+extern void Cmd_SetPStrength(ITEM *);
+extern void Cmd_SetPLevel(ITEM *);
+extern void Cmd_SetPScore(ITEM *);
+extern void Cmd_Users(ITEM *);
+
+/* ROOMCOMMANDS.C */
+
+extern void Cmd_SetShort(ITEM *);
+extern void Cmd_ShowRoom(ITEM *);
+extern void Cmd_SetRFlag(ITEM *);
+extern void Cmd_SetLong(ITEM *);
+extern void Cmd_Look(ITEM *);
+extern void Cmd_Goto(ITEM *);
+extern void Cmd_Brief(ITEM *);
+extern void Cmd_Verbose(ITEM *);
+extern void Cmd_SetPicture(ITEM *);
+
+/* SAVELOAD.C */
+
+extern void SaveAllTable(FILE *);
+extern int SaveSystem(char *);
+extern int LoadSystem(char *);
+
+/* SNOOP.C */
+
+extern int StartSnoop(ITEM *,ITEM *,short);
+extern void StopSnoop(ITEM *,SNOOP *);
+extern void StopSnoopOn(ITEM *,ITEM *);
+extern void StopAllSnoops(ITEM *);
+extern void StopSnoopsOn(ITEM *);
+extern void SnoopCheckString(ITEM *,char *);
+extern int SnoopCheckRec(ITEM *,char *,short);
+
+/* TABLECOMMANDS.C */
+
+extern void Cmd_ListTables(ITEM *);
+extern void Cmd_AddTable(ITEM *);
+extern void Cmd_DeleteTable(ITEM *);
+extern void Cmd_NewTable(ITEM *);
+extern void Cmd_ListTables(ITEM *);
+extern void Cmd_ListTables(ITEM *);
+extern void Cmd_NameTable(ITEM *);
+
+/* TABLEDRIVER.C */
+
+extern TABLE *TableList;
+extern TPTR TxtArg;
+extern TPTR TxtArg2;
+extern char TxBuf[];
+extern int System_Debug;
+extern short Traf[4];
+extern LINE *CurrentLine;
+
+extern TXT DummyTxt;
+extern ITEM DummyItem;
+extern TABLE *CurrentTable;
+extern ITEM *Item1,*Item2,*Debugger;
+extern int Noun1,Adj1,Noun2,Adj2,Verb,Prep,Ord1,Ord2;
+extern short Traf[4];
+
+extern void WipeFlags(void);
+extern int GetFlag(int);
+extern void SetFlag(int,int);
+extern void PCurrentLine(void);
+extern void FPCurrentLine(void);
+extern ITEM *Me(void);
+extern void SetMe(ITEM *);
+extern ITEM *Actor(void);
+extern int ArgNum(void);
+extern unsigned int UArgNum(void);
+extern int ArgWord(void);
+extern ITEM *ArgItem(void);
+extern TPTR ArgText(void);
+extern void ParseArgs(int);
+extern int ArgMatch(LINE *);
+extern int ExecBackground(TABLE *,ITEM *);
+extern int ExecTable(TABLE *);
+extern int RunLine(LINE *);
+extern ITEM *FindAnItem(int,int,int);
+extern int FindTableByName(char *);
+extern TABLE *FindTable(int);
+extern TABLE *NewTable(int,char *);
+extern LINE *NewLine(TABLE *,int);
+extern LINE *FindLine(TABLE *,int);
+extern int DeleteLine(TABLE *,int);
+extern int WipeDeleteLine(TABLE *,int);
+extern int UserAction(ITEM *,int);
+extern int UserDaemon(ITEM *);
+extern int RandPerc(void);
+
+/* TABLEEDITING.C */
+
+extern char *EditingBuffers[];
+
+extern void Cmd_EditTable(ITEM *);
+extern void Cmd_EditOTable(ITEM *);
+extern void Cmd_EditDTable(ITEM *);
+extern void Cmd_EditSTable(ITEM *);
+extern void Tbl_Quit(int,char *);
+extern void Tbl_Goto(int,char *);
+extern void Tbl_Find(int,char *);
+extern void Tbl_Top(int,char *);
+extern long CountEntries(TABLE *);
+extern void Tbl_Bottom(int,char *);
+extern void Tbl_Next(int,char *);
+extern void Tbl_Previous(int,char *);
+extern void Tbl_List(int,char *);
+extern void Tbl_Insert(int,char *);
+extern void Tbl_Edit(int,char *);
+extern void Tbl_EditLine(int,char *);
+extern void Tbl_DeleteLine(int,char *);
+extern void Tbl_Driver(int,char *);
+extern void OutLineBlock(FILE *,char *);
+extern void Cmd_SaveTable(ITEM *);
+
+/* TIMESCHEDULER.C */
+
+extern short Sched_Lock;
+
+extern long CountSchedules(void);
+extern void AddEvent(unsigned long,short);
+extern void Scheduler(void);
+extern void KillEventQueue(ITEM *);
+extern void WipeEventQueue(void);
+
+/* USERFILE.C */
+
+extern void SwapUFFToHost(UFF *);
+extern void SwapHostToNeutral(UFF *);
+extern int WriteRecord(FILE *,UFF *);
+extern int ReadRecord(FILE *,UFF *);
+extern int FindRecord(FILE *,int);
+extern FILE *OpenUAF(void);
+extern void CloseUAF(FILE *);
+extern int LoadPersona(char *,UFF *);
+extern int SavePersona(UFF *,int);
+extern int FindFreeRecord(void);
+extern int SaveNewPersona(UFF *);
+
+/* UTILCOMMAND.C */
+
+extern void Cmd_DoorPair(ITEM *);
+extern void Cmd_ShowAllObjects(ITEM *);
+extern void Cmd_ShowAllRooms(ITEM *);
+extern void Cmd_ShowAllPlayers(ITEM *);
+extern int ShowItemData(ITEM *,ITEM *);
+
+/* CLASS.C */
+
+extern void SetClassTxt(short,TXT *);
+extern void SetClassName(short,char *);
+extern TXT *GetClassTxt(short);
+extern char *GetClassName(short);
+extern short WhichClass(char *);
+extern void ClassDescStr(ITEM *,short);
+extern void Cmd_ListClass(ITEM *);
+extern void Cmd_NameClass(ITEM *);
+extern void Cmd_SetClass(ITEM *);
+extern void Cmd_UnsetClass(ITEM *);
+
+/* DUPLICATOR.C */
+
+extern int Clone_Room(ITEM *,ITEM *);
+extern int Clone_Object(ITEM *,ITEM *);
+extern int Clone_Player(ITEM *,ITEM *);
+extern int Clone_GenExit(ITEM *,ITEM *);
+extern int Clone_MsgExit(ITEM *,MSGEXIT *);
+extern int Clone_Chain(ITEM *,CHAIN *);
+extern int Clone_Container(ITEM *,CONTAINER *);
+extern int Clone_UserFlag(ITEM *,USERFLAG *);
+extern int Clone_UserText(ITEM *,ITEM *);
+extern int Clone_Inherit(ITEM *,INHERIT *);
+extern ITEM *Clone_Item(ITEM *,short);
+extern int Duped(ITEM *);
+extern int Disintegrate(ITEM *);
+extern void DisintegrateAll(void);
+
+/* MAIN.C */
+
+extern void SegV();
+extern void Bus();
+extern void Div0();
+
+extern int main(int,char *[]);
+
+extern short post_boot;
+
+/* PARSER.C */
+
+extern WLIST *WordList;
+extern PCONTEXT ParserData[];
+extern short ParsingPersona;
+
+extern void SetPersona(int);
+extern PCONTEXT *GetContext(short);
+extern void ProLoad(short,int *,int *);
+extern void SetItData(short,ITEM *,short,short);
+extern void AddWord(char *,short,short);
+extern int FreeWord(char *,short);
+extern char *FindWText(int,short);
+extern WLIST *FindInList(WLIST *,char *,short);
+extern char *BreakWord(char *,char *,WLIST *,short);
+extern char *GetRestOfInput(char *,char *);
+extern char *FNxPhrs(char *);
+extern char *WordPtr;
+extern char WordBuffer[];
+extern WLIST *GetWord(void);
+extern int GetOrd(void);
+extern char *GetParsedWord(void);
+extern void GetAll(void);
+extern int GetNumber(void);
+extern int GetThing(int *,int *);
+extern void SkipPrep(void);
+extern int GetPrep(void);
+extern int GetVerb(void);
+extern char *NextPhrase(void);
+
+/* FLAGNAME.C */
+
+extern char *PBitNames[];
+extern char *OBitNames[];
+extern char *RBitNames[];
+extern char *CBitNames[];
+extern int FindRBit(char *);
+extern int FindPBit(char *);
+extern int FindOBit(char *);
+extern int FindCBit(char *);
+extern char *RBitName(int);
+extern char *OBitName(int);
+extern char *PBitName(int);
+extern char *CBitName(int);
+extern void Cmd_RBitName(ITEM *);
+extern void Cmd_OBitName(ITEM *);
+extern void Cmd_PBitName(ITEM *);
+extern void Cmd_CBitName(ITEM *);
+extern void Cmd_ListRBits(ITEM *);
+extern void Cmd_ListOBits(ITEM *);
+extern void Cmd_ListPBits(ITEM *);
+extern void Cmd_ListCBits(ITEM *);
+
+/* NewCmd.c */
+
+extern void Act_SetI(void);
+extern void Act_CDaemon(void);
+extern int Cnd_Delete(void);
+extern int Cnd_ULoad(void);
+extern int Cnd_USave(void);
+extern int Cnd_FLoad(void);
+extern int Cnd_FSave(void);
+extern void Act_Getvis(void);
+extern void Act_ForkDump(void);
+extern void Act_SetExit(void);
+extern void Act_DelExit(void);
+extern int Cnd_ProcDaemon(void);
+extern int Cnd_ProcSubject(void);
+extern int Cnd_ProcObject(void);
+extern int Cnd_GetSuper(void);
+extern void Act_SetSuper(void);
+extern int Cnd_Member(void);
+
+/* AberRWho.c */
+
+extern void Act_RwhoDeclareUp(void);
+extern void Act_RwhoDeclareDown(void);
+extern void Act_RwhoLogin(void);
+extern void Act_RwhoLogout(void);
+extern void Act_RwhoDeclareAlive(void);
+
+/* UserVector.c */
+
+void UserVector(short,short,short,ITEM *,ITEM *,TPTR);
+
+/* LibRWho.c */
+
+int rwhocli_setup(char *,char *,char *,char *);
+int rwhocli_shutdown(void);
+int rwhocli_pingalive(void);
+int rwhocli_userlogin(char *,char *,time_t);
+int rwhocli_userlogout(char *);
+
+/* AnsiBits.c */
+
+extern int stricmp(const char *, const char *);
+extern char *strtok2(char *,char *,char *);
+
+/* LookFor.c */
+
+extern void CheckLineFor(LINE *,ITEM *,int);
+extern void CheckTableFor(TABLE *,ITEM *,int);
+extern void CheckAllFor(ITEM *,ITEM *,int);
+
+/* IPCDirect.c */
+
+extern int IsBSX(int);
+extern int FindUserFD(int);
+extern int IsUserFD(int);
+extern int ReadBlock(int, COMTEXT *);
+extern void SnoopPut(int, char);
+extern void SnoopFlush(int, int);
+extern void SnoopCharPut(int, char);
+extern void CharPut(int, char);
+extern void LinePut(int, char);
+extern void LineFlush(int, char);
+extern void FieldShift(int, int);
+extern PORT *Bind_Port(int, int);
+extern PORT *CreateMPort(int);
+extern PORT *OpenMPort(PORT *);
+extern int CloseMPort(PORT *);
+extern void BlockOn(PORT *);
+extern void BlockOff(PORT *);
+extern int WriteMPort(PORT *, COMTEXT *, int);
+extern int DeleteMPort(PORT *);
+extern int AssignService(char *, PORT *);
+extern int DeAssignService(char *);
+extern PORT *FindService(char *);
+extern int ReadMPort(PORT *, COMTEXT *);
+extern int Silo(PORT *, char *, int);
+extern int SiloFlush(PORT *);
+extern int WriteSocket(int, char *, int);
+extern int WriteSocketText(int, char *, int);
+extern void WriteFlush(int u);
+extern char *NetName(unsigned long);
+extern int can_play_now(void);
+extern int MakeConnection(int, COMTEXT *);
+
+/* LibSocket.c */
+
+int Make_Socket(int);
+
+/* ValidLogic.c */
+
+int MaxSlot(void);
+
+/* _THE END_ */
diff --git a/README-5.30 b/README-5.30
new file mode 100644
index 0000000..a89ab90
--- /dev/null
+++ b/README-5.30
@@ -0,0 +1,129 @@
+This is the 'official' 5.30 AberMUD driver release 0
+
+o Extensive ANSI cleanups
+
+o Fixed prototypes to be ANSI in most places
+
+o Fixed problems with promotion rule variance between K&R and ANSI C
+
+o Cleaned up the Makefile a little
+
+o Cleaned up the client massively. Now expects a modern XPG type
+ curses library
+
+o Now passes gcc -pedantic -Wall cleanly
+
+This is the 'official' 5.21 AberMUD driver release 5
+
+o BSX has its own motd which can contain BSX graphics
+ directives.
+
+o Returns tidied up, Prototypes updated
+
+o Faulty function parameters cleaned up
+
+o Missing prompt clear on connect added
+
+o NARG implemented
+
+o AmiTCP support added, the Amiga version can now sit
+ on the internet like the Linux/Unix versions.
+
+
+Release 5.21 BETA 4 Changes:
+
+o Long names don't lose caller address information
+
+o Containers now use the NameCFlag etc fields instead of
+ hardcoded field names.
+
+o Sections of the manual now completed.
+
+o BSX supports @RMO to remove objects from scenes
+
+o File descriptor leak printing the motd is fixed.
+
+o BSX mode input formatting is much better. BSX output
+ formatting doesn't generate stray newlines. BSX
+ seems ready for real use.
+
+o Output formatting now uses \r\n everywhere.
+
+o Linux testing now with 0.99.10 and the improved networking
+ software. It's got a couple of small quirks still but its now
+ plenty solid enough as a good MUD platform.
+
+
+
+
+Release 5.21 BETA 3 Changes:
+
+o Snoop shows commands that are typed
+
+o New actions PROCDAEMON PROCSUBJECT PROCOBJECT SETSUPER GETSUPER
+
+o BSX fixes to send extra @RFS
+
+o Doesn't send @TMS when it shouldn't
+
+o @PUR purge sent to all BSX clients when a BSX object is loaded
+
+o Ported Client to Linux and 'old' curses.
+
+o Communications.h is now Comms.h for 14 character file name machines
+
+o Object editing includes setting description 0
+
+
+
+Release 5.21 BETA 2 Changes:
+
+Changes:
+
+o Clone now handles the inheritance properties. Because building
+ a lot of clones with tables would be slow and use a lot of memory
+ clones of an item use the original as the superclass, and have
+ blank tables.
+
+o Deletion tidies up tables which could otherwise get stuck, and
+ invalidate lock counters.
+
+
+Release 5.21 BETA 1 Changes:
+
+o Removal of all code written while I worked for Horrorsoft, so its
+ no longer arguably not all mine.
+
+o Removal of AmigaDOS support: It was too much work to keep it in and
+ sort it all out so I've dropped it. In theory there should be no
+ problem merging the new driver with the old amiga comms. A little
+ tweaking might be needed for BSX however.
+
+o Linux support. This has meant squashing a few bugs in the comms
+ layer. Linux tcp/ip isn't yet really up to a full time game driver,
+ It's close and I think in one or two more releases (ie about 0.99.7)
+ Linux will do the job well.
+
+o Class inheritance support
+
+o Quite a few bugs have been splatted including some comms layer ones
+ which could (and did occasionally) crash the daemon.
+
+o Long motd messages work on all machines. The motd is now queued
+ like all normal text output, and doesn't rely on an initial
+ buffer that might not actually exist.
+
+o Registration support, so you can write registration only, some
+ commands only available to the registered and similar styles of game.
+
+o Dying does not delete the persona, only blanks it, so you can't kill
+ someone and steal the name.
+
+o BSXmud graphics support is now in prototype form.
+
+o Client mode bug from 5.20 BETA 2 is fixed.
+
+o SaveUniverse no longer reports spurious errors
+
+WARNING: 5.21 generates a newer database format than 5.20, to allow for the BSX graphics elements.
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..82dc395
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# AberMUD
diff --git a/Reg.c b/Reg.c
new file mode 100644
index 0000000..db69c88
--- /dev/null
+++ b/Reg.c
@@ -0,0 +1,41 @@
+
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+
+int main(int argc,char *argv[])
+{
+ short ct=1;
+ UFF u;
+ while(argv[ct])
+ {
+ int pos;
+ if((pos=LoadPersona(argv[ct],&u))==-1)
+ printf("%s: Not found.\n",argv[ct]);
+ else
+ {
+ u.uff_Flag[9]=1;
+ printf("%s: Registered.\n",argv[ct]);
+ SavePersona(&u,pos);
+ }
+
+ ct++;
+ }
+ exit(0);
+}
+
+void Log(char *x, ...){;}
+
+void ErrFunc(char *x, char *y, char *z, int a, char *b)
+{
+ fprintf(stderr,"%s %s %s %d %s\n",x,y,z,a,b);
+ exit(1);
+}
diff --git a/RoomCommands.c b/RoomCommands.c
new file mode 100644
index 0000000..aa284e6
--- /dev/null
+++ b/RoomCommands.c
@@ -0,0 +1,413 @@
+
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+#include "User.h"
+
+extern USER UserList[];
+
+Module "Room Commands";
+Version "1.06";
+Author "----*(A)";
+
+/*
+ * 1.00 AGC Created This File
+ * 1.01 AGC Stopped SetLong free()ing extra memory by mistake
+ * 1.02 AGC Made Cmd_Look understand SetHere
+ * 1.03 AGC Made * strip out embedded controls
+ * 1.04 AGC 5.07 version - with bitflag names
+ * 1.05 AGC Fixed so it uses right flag names
+ * 1.06 AGC Cmd_Look now does brief mode correctly for no title
+ */
+
+
+void Cmd_SetShort(i)
+ITEM *i;
+{
+ ITEM *a;
+ ROOM *r;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Sorry no name changing round here.\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ r=RoomOf(a);
+ if(r==NULL)
+ {
+ SendItem(i,"%s is not a room.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ GetAll();
+ if(!strlen(WordBuffer))
+ {
+ SendEdit(i,"SetShort #%d %s %s",ItemNumber(LevelOf(i),a),
+ CNameOf(a),TextOf(r->rm_Short));
+ return;
+ }
+ FreeText(r->rm_Short);
+ r->rm_Short=AllocText(WordBuffer);
+}
+
+void Cmd_ShowRoom(i)
+ITEM *i;
+{
+ int ct=0;
+ ITEM *a;
+ ROOM *r;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Try LOOK.\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ r=RoomOf(a);
+ if(r==NULL)
+ {
+ SendItem(i,"%s is not a room.\n",CNameOf(a));
+ return;
+ }
+ SendItem(i,"Room Name : %s\n",CNameOf(a));
+ SendItem(i,"Picture : %d\n",(int)GETPICTURE(r->rm_Flags));
+ SendItem(i,"Short Text: %s\n",TextOf(r->rm_Short));
+ SendItem(i,"Long Text :\n%s\n",TextOf(r->rm_Long));
+ while(ct<16)
+ {
+ if(r->rm_Flags&(1<<ct))
+ SendItem(i,"%s ",RBitName(ct));
+ else
+ if(strcmp(RBitName(ct),"{unset}"))
+ SendItem(i,"-%s ",RBitName(ct));
+ ct++;
+ }
+ SendItem(i,"\n");
+}
+
+void Cmd_SetRFlag(i)
+ITEM *i;
+{
+ int c;
+ ITEM *a;
+ ROOM *r;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No can do....\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ r=RoomOf(a);
+ if(r==NULL)
+ {
+ SendItem(i,"%s is not a room.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ while(GetParsedWord())
+ {
+ if(!strlen(WordBuffer))
+ {
+ SendItem(i,"What flag though ?\n");
+ return;
+ }
+ if(*WordBuffer=='-')
+ {
+ c=FindRBit(WordBuffer+1);
+ if(c==-1)
+ {
+ SendItem(i,"Unknown flag %s.\n",WordBuffer+1);
+ return;
+ }
+ r->rm_Flags&=~(1<<c);
+ }
+ else
+ {
+ c=FindRBit(WordBuffer);
+ if(c==-1)
+ {
+ SendItem(i,"Unknown flag %s.\n",WordBuffer);
+ return;
+ }
+ r->rm_Flags|=(1<<c);
+ }
+
+ }
+}
+
+void Cmd_SetLong(i)
+ITEM *i;
+{
+ int siz;
+ int bbp;
+ int c;
+ ITEM *a;
+ ROOM *r;
+ char *BigBuffer;
+ FILE *f;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"No!\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ r=RoomOf(a);
+ if(r==NULL)
+ {
+ SendItem(i,"%s is not a room.\n",CNameOf(a));
+ return;
+ }
+ SkipPrep();
+ GetAll();
+ if(!strlen(WordBuffer))
+ {
+ SendEdit(i,"SetLong #%d %s %s",ItemNumber(LevelOf(i),a),
+ CNameOf(a),TextOf(r->rm_Long));
+ return;
+ }
+ if(*WordBuffer!='*')
+ {
+ BigBuffer=WordBuffer;
+ goto l1;
+ }
+ f=fopen(WordBuffer+1,"r");
+ if(f==NULL)
+ {
+ SendItem(i,"Sorry - can't open the file.\n");
+ return;
+ }
+ BigBuffer=malloc(2048);
+ if(BigBuffer==NULL)
+ {
+ SendItem(i,"Not enough memory.\n");
+ return;
+ }
+ bbp=0;
+ while((c=fgetc(f))!=EOF)
+ {
+ if(c=='\n') c=' ';
+ if(c>31) /* Strip controls */
+ BigBuffer[bbp++]=c;
+ if(bbp>2047)
+ {
+ fclose(f);
+ free(BigBuffer);
+ SendItem(i,"Entry too large.\n");
+ return;
+ }
+ }
+ BigBuffer[bbp]=0;
+ siz=bbp;
+ fclose(f);
+ if(BigBuffer[siz-1]=='\n')
+ BigBuffer[siz-1]=0;
+ BigBuffer[siz]=0; /* Convert data to C string */
+l1: FreeText(r->rm_Long);
+ r->rm_Long=AllocText(BigBuffer);
+ if(BigBuffer!=WordBuffer)
+ free(BigBuffer);
+}
+
+
+void Cmd_Look(i)
+ITEM *i;
+{
+ ROOM *r;
+ OBJECT *o;
+ ITEM *l;
+ PLAYER *p;
+ TABLE *t;
+ t=FindTable(103);
+ if(t)
+ {
+ if(ExecBackground(t,i)==-1)
+ return; /* NOTDONE stops describe */
+ }
+ if(O_PARENT(i)==NULL)
+ {
+ SetUserTitle(i,"The Void");
+ SendItem(i,"You are floating in the void.\n");
+ return;
+ }
+ if(PlayerOf(i)==NULL)
+ return; /* Only Players Can LOOK! */
+ r=RoomOf(O_PARENT(i));
+ o=ObjectOf(O_PARENT(i));
+ p=PlayerOf(O_PARENT(i));
+ if(r)
+ {
+ if(r->rm_Flags&RM_DEATH)
+ goto l2;
+ }
+ if(CanSee(LevelOf(i),O_PARENT(i))==0)
+ {
+ SendItem(i,"\
+You are lost in an incomprehensible haze of unidentifiable images.\n");
+ SetUserTitle(i,"Lost");
+ return;
+ }
+ if(IsBlind(i))
+ {
+ SendItem(i,"You can't see, you are blind.\n");
+ SetUserTitle(i,"Blind");
+ return;
+ }
+ if(IsDarkFor(i))
+ {
+ SetUserTitle(i,"Dark");
+ SendItem(i,"It is dark.\n");
+ return;
+ }
+
+ if((r)&&(PlayerOf(i)->pl_Flags&PL_BRIEF))
+ {
+ SendItem(i,"%s\n",TextOf(r->rm_Short));
+/* SetUserTitle(i,"%s",TextOf(r->rm_Short))*/;
+ }
+ else if((o)&&(!r))
+ {
+ SendItem(i,"You are in %s\n",NameOf(O_PARENT(i)));
+ SetUserTitle(i,"In the %s",NameOf(O_PARENT(i)));
+ }
+ else if(p)
+ {
+ SendItem(i,"You are being carried by %s\n",
+ NameOf(O_PARENT(i)));
+ SetUserTitle(i,"Carried by %s",
+ NameOf(O_PARENT(i)));
+ }
+
+ if(PlayerOf(i)->pl_Flags&PL_BRIEF)
+ goto l1;
+l2: if(r)
+ {
+ SetUserTitle(i,"%s",TextOf(r->rm_Short));
+ SendItem(i,"%s",TextOf(r->rm_Long));
+ }
+ l=O_CHILDREN(O_PARENT(i));
+ while(l)
+ {
+ if(CanSee(LevelOf(i),l))
+ {
+ if(ObjectOf(l))
+ {
+ if(ObjectOf(l)->ob_Flags&OB_FLANNEL)
+ SendItem(i,"%s",
+ TextOf(ObjectOf(l)->ob_Text[O_STATE(l)]));
+ }
+ }
+ l=O_NEXT(l);
+ }
+ if((r)&&(r->rm_Flags&RM_MERGE)&&(O_PARENT(O_PARENT(i)))&&
+ (RoomOf(O_PARENT(O_PARENT(i))))&&
+ (RoomOf(O_PARENT(O_PARENT(i)))->rm_Flags&RM_JOIN))
+ {
+ SendItem(i,"%s",TextOf(RoomOf(O_PARENT(O_PARENT(i)))->rm_Long));
+ }
+ SendItem(i,"\n");
+ t=FindTable(104);
+ if(t)
+ {
+ ExecBackground(t,i);
+ }
+ if(r&&r->rm_Flags&RM_DEATH)
+ goto ldie;
+l1: l=O_CHILDREN(O_PARENT(i));
+ while(l)
+ {
+ if(l!=i)
+ DescribeItem(i,l);
+ l=O_NEXT(l);
+ }
+ SendItem(i,"\n");
+ t=FindTable(105);
+ if(t)
+ {
+ ExecBackground(t,i);
+ }
+ldie: if(r)
+ {
+ if((r->rm_Flags&RM_DEATH)&&(LevelOf(i)<10000))
+ {
+ if(UserOf(i)!=-1)
+ {
+ SendTPacket(UserList[UserOf(i)].us_Port,
+ PACKET_CLEAR,"");
+ RemoveUser(UserOf(i));
+ }
+ else
+ SendItem(i,"[You would die here if mortal]\n");
+ }
+ }
+}
+
+void Cmd_Goto(i)
+ITEM *i;
+{
+ ITEM *a;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Yes, so give me the route.\n");
+ return;
+ }
+ a=FindSomething(i,O_PARENT(i));
+ if(a==NULL)
+ {
+ SendItem(i,"I don't know what that is.\n");
+ return;
+ }
+ DoesAction(i,4,"vanishes in a haze of multihued light.\n");
+ Place(i,a);
+ DoesAction(i,4,"appears amidst a puff of greenish smoke.\n");
+ Cmd_Look(i);
+}
+
+void Cmd_Brief(i)
+ITEM *i;
+{
+ PlayerOf(i)->pl_Flags|=PL_BRIEF;
+}
+
+void Cmd_Verbose(i)
+ITEM *i;
+{
+ PlayerOf(i)->pl_Flags&=~PL_BRIEF;
+}
+
+void Cmd_SetPicture(i)
+ITEM *i;
+{
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"What ?\n");
+ return;
+ }
+ SendItem(i,"Obsolete command.\n");
+}
diff --git a/Run_Aber.c b/Run_Aber.c
new file mode 100644
index 0000000..fb99e1f
--- /dev/null
+++ b/Run_Aber.c
@@ -0,0 +1,56 @@
+#include <stdio.h>
+#include <fcntl.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+
+/*
+ * AberMUD boot up program.
+ *
+ * 1.00 AGC Prehistory Original boot up program
+ * 1.01 AGC 27/02/93 Passes arguments on
+ *
+ */
+
+int main(int argc,char *argv[])
+{
+ long t,t2;
+ int pid;
+ printf("Aberystwyth Multi-User Dungeon (Revision 5.21 BETA 5)\n\
+(c) Copyright 1987-1993, Alan Cox\n\
+\n");
+ close(0);
+ close(1);
+ ioctl(2,TIOCNOTTY,0);
+ close(2);
+ setpgrp();
+ if(fork()!=0)
+ exit(1);
+ open("server_log",O_WRONLY|O_CREAT|O_APPEND,0600);
+ dup(0);
+ dup(0);
+ while(1)
+ {
+ time(&t);
+ argv[0]="AberMUD 5.21 Beta1";
+ pid=fork();
+ if(pid==0)
+ {
+ execvp("./server",&argv[0]);
+ perror("./server");
+ exit(1);
+ }
+ else
+ if(pid!= -1)
+ wait(NULL);
+ time(&t2);
+ if(t2-t<10)
+ {
+ printf("Spawning too fast - error ??\n");
+ exit(1);
+ }
+ }
+}
diff --git a/SaveLoad.c b/SaveLoad.c
new file mode 100644
index 0000000..ca8de2d
--- /dev/null
+++ b/SaveLoad.c
@@ -0,0 +1,1270 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+
+/*
+ * Disk Save/Load functions
+ *
+ * 1.00 AGC First Version
+ * 1.01 AGC Saves substructures
+ * 1.02 AGC Table saving code
+ * 1.03-1.06 AGC Various tweaks, and substructure adds
+ * 1.07 AGC Saves flag names
+ * 1.08 AGC Runtime file format stuff
+ * 1.09 AGC Hashed text lists
+ * 1.10 AGC Register Optimisations
+ * 1.11 AGC Setin Setout Sethere
+ * 1.12 AGC UserTexts and frees texts right on Setin etc
+ * 1.13 AGC Bug Fixes For 5.06 Release
+ * 1.14 AGC Added Named table support
+ * 1.15 AGC Added 5.08 Item table support
+ * 1.16 AGC Fixed bug if you have single occurance of ""
+ * 1.17 AGC Fixed Unix errno problem.
+ * 1.18 AGC Fixed Unix errno problem properly
+ * 1.19 AGC Taught it about USERFLAG2 and CONDEXIT
+ * 1.20 AGC Tidied warnings out for 5.20
+ * 1.21 AGC Loads superclass and daemontable fields.
+ * 1.22 AGC Fixed SaveUniverse error that isnt bug
+ * 1.23 AGC Saves BSX pictures
+ * 1.25 AGC BSX save/load name bugfix
+ */
+
+Module "DiskIO";
+Version "1.24";
+Author "----*(A)";
+
+extern int errno;
+extern ITEM *ItemList;
+/*
+ * Items are saved by direct ordered dump, all text dumped is done
+ * literally at present, not through the text list.
+ *
+ * Item links are converted to itemnumber in the master list
+ * save for ->masternext which is unsaved as it is implied
+ *
+ * For loading an initial value gives the number of items to load
+ * the items are allocated (but not substructs) into a linked list
+ * and an array of their pointers kept for conversions. Each item
+ * is loaded, then the whole array is freed
+ */
+
+
+/* Global Declarations */
+
+static void SaveShort();
+static unsigned short LoadShort();
+static void SaveLong();
+static unsigned long LoadLong();
+static void SaveItem();
+static ITEM *LoadItem();
+static void SaveString();
+static TPTR LoadString();
+static void SaveBSX();
+static BSXImage *LoadBSX();
+static void SaveWord();
+static int LoadWord();
+static void SaveVocab();
+static void LoadVocab();
+static void WriteHeader();
+static long ReadHeader();
+static void SaveSub();
+static void LoadSub();
+static void LoadObject();
+static void SaveObject();
+static void SetTwo();
+static long GetTwo();
+static unsigned short *SaveAction();
+static short *LoadAction();
+static void LoadLine();
+static void SaveLine();
+static void LoadTable();
+static void SaveTable();
+static void LoadAllTables();
+static void SaveAllTables();
+static TABLE *LoadItemTable();
+static void SaveItemTable();
+
+static ITEM **ItemArray; /* Used for item loaders */
+static long Load_Format=-1;
+static int Load_Error=0;
+
+static void SetTwo(x,v)
+unsigned short *x;
+register char *v;
+{
+ x[1]=((unsigned long)v)%65536; /* Safe -we never extract this pointer */
+ x[0]=((unsigned long)v)/65536; /* directly so little endians should */
+ /* be just fine.... CHANGE TO HTONS?? */
+}
+
+static long GetTwo(x)
+register unsigned short *x;
+{
+ return(x[1]+65536L*x[0]);
+}
+
+static void SaveShort(file,v)
+FILE *file;
+register unsigned short v;
+{
+ unsigned char x[3];
+/* Assumes 16 bit short - they are used as such even if bigger so is ok */
+ x[0]=v/256;
+ x[1]=v%256;
+ if(fwrite(x,2,1,file)!=1)
+ Load_Error=errno;
+}
+
+static unsigned short LoadShort(x)
+FILE *x;
+{
+ unsigned char a[3];
+ if(fread(a,2,1,x)!=1)
+ Load_Error=errno;
+ return((unsigned short)(256L*a[0]+a[1]));
+}
+
+static void SaveLong(file,x)
+FILE *file;
+register unsigned long x;
+{
+/*
+ * Assumes 32 bits - see notes above
+ */
+ SaveShort(file,(unsigned short)(x/65536));
+ SaveShort(file,(unsigned short)(x%65536));
+}
+
+static unsigned long LoadLong(f)
+FILE *f;
+{
+ unsigned short a=LoadShort(f);
+ return((unsigned long)(a*65536L+LoadShort(f)));
+}
+
+static void SaveItem(file,i)
+FILE *file;
+ITEM *i;
+{
+ if(i==NULL)
+ SaveLong(file,-1L);
+ else
+ {
+ SaveLong(file,MasterNumber(i));
+ }
+}
+
+static ITEM *LoadItem(file)
+FILE *file;
+{
+ register long x=LoadLong(file);
+ if(x==-1)
+ return(NULL);
+ return(ItemArray[x]);
+}
+
+static void SaveString(file,s)
+FILE *file;
+TPTR s;
+{
+ register char *str=TextOf(s);
+ register long v=strlen(str);
+ if(s->te_Users==1)
+ v|=65536;
+ SaveLong(file,v);
+ if(fwrite(str,strlen(str),1,file)!=1)
+ Load_Error=errno;
+}
+
+static TPTR LoadString(file)
+FILE *file;
+{
+ register char *a;
+ register long v=LoadLong(file);
+ register TPTR t;
+ register short f=0;
+ if(v>=65536)
+ {
+ f=1;
+ v-=65536;
+ }
+ a=malloc(v+1);
+ if(!a)
+ {
+ Error("Out Of Memory");
+ }
+ if(fread(a,v,1,file)!=1)
+ {
+ Load_Error=errno;
+ }
+ a[v]=0;
+ if(f)
+ t=QuickAllocText(a);
+ else
+ t=AllocText(a);
+ free(a);
+ return(t);
+}
+
+static TPTR LoadComment(file)
+FILE *file;
+{
+ register char *a;
+ register long v=LoadLong(file);
+ register TPTR t;
+ if(v>65536)
+ {
+ v-=65536;
+ }
+ a=malloc(v+1);
+ if(!a)
+ Error("Out Of Memory");
+ if(fread(a,v,1,file)!=1)
+ {
+ Load_Error=errno;
+ }
+ a[v]=0;
+ t=AllocComment(a);
+ free(a);
+ return(t);
+}
+
+static void SaveBSX(file,i)
+FILE *file;
+BSXImage *i;
+{
+ int v=strlen(i->bsx_Identifier);
+ SaveLong(file,v);
+ SaveLong(file,i->bsx_DataSize);
+ if(fwrite(i->bsx_Identifier,v,1,file)!=1)
+ Load_Error=errno;
+ if(fwrite(i->bsx_Data,i->bsx_DataSize,1,file)!=1)
+ Load_Error=errno;
+}
+
+static BSXImage *LoadBSX(file)
+FILE *file;
+{
+ extern BSXImage *BSXAllocate();
+ BSXImage *i;
+ char buf[128];
+ long v=LoadLong(file);
+ long d=LoadLong(file);
+ if(fread(buf,v,1,file)!=1)
+ {
+ Load_Error=errno;
+ return(NULL);
+ }
+ buf[v]=0;
+ i=BSXAllocate(buf,d);
+ if(fread(i->bsx_Data,d,1,file)!=1)
+ {
+ Load_Error=errno;
+ BSXDelete(i);
+ return(NULL);
+ }
+ return(i);
+}
+
+static void SaveWord(file,x)
+FILE *file;
+register WLIST *x;
+{
+/* NOTE: Words aren't allowed to contain spaces - THIS RELIES ON IT !!! */
+ fprintf(file,"%s %d %d.",x->wd_Text,x->wd_Code,x->wd_Type);
+}
+
+static int LoadWord(file)
+FILE *file;
+{
+ static char x[128];
+ int a,b;
+ if(fscanf(file,"%s %d %d.",x,&a,&b)!=3)
+ Error("LoadWord: Corruption In Database File");
+ if(strcmp(x,";END")==0) /*; not legal in word either! */
+ return(0);
+ AddWord(x,(short)a,(short)b);
+ return(1);
+}
+
+static void SaveVocab(file)
+FILE *file;
+{
+ register WLIST *a=WordList;
+ while(a)
+ {
+ SaveWord(file,a);
+ a=a->wd_Next;
+ }
+ fprintf(file,";END 0 0.");
+}
+
+static void LoadVocab(file)
+FILE *file;
+{
+ while(LoadWord(file));
+}
+
+static void WriteHeader(file)
+FILE *file;
+{
+ long header[4];
+ header[0]=CountItems();
+ header[1]=10; /* Format Identifier */
+/*
+ * FORMATS: 0: Original (no longer supported)
+ * 1: 5.04 no flag names
+ * 2: 5.04 flag names
+ * 3: 5.05 vocab seek & classes
+ * 4: 5.06 with text speed flags
+ * 5: 5.07 with named tables
+ * 6: 5.08 with item bound tables
+ * 7: 5.11 USERFLAG2 and CONDEXITs
+ * 8: 5.14
+ * 9: 5.20 superclass and daemon table
+ * 10: 5.21 BSX picture data
+ */
+ time(&(header[2])); /* Save time */
+ header[3]=0; /* Reserved for vocab seek*/
+ SaveLong(file,header[0]);
+ SaveLong(file,header[1]);
+ SaveLong(file,header[2]);
+ SaveLong(file,header[3]);
+}
+
+
+static long ReadHeader(file)
+FILE *file;
+{
+ long v[4];
+ register long ct;
+ v[0]=LoadLong(file);
+ v[1]=LoadLong(file);
+ v[2]=LoadLong(file);
+ v[3]=LoadLong(file);
+ Load_Format=v[1];
+ if(Load_Format<1)
+ {
+ fprintf(stderr,
+"This database format is too old.\n");
+ exit(0);
+ }
+ if(Load_Format>10)
+ {
+ fprintf(stderr,
+"This database format is beyond my knowledge, you need a newer SERVER.\n");
+ exit(0);
+ }
+ Log("Header Read: %ld Items",v[0]);
+ ct=0;
+/*
+ * The +1 here stops a 0 sized malloc, which upsets some machines
+ */
+ ItemArray=(ITEM **)malloc(v[0]*sizeof(ITEM *)+1);
+ if(ItemArray==NULL)
+ Error("Out Of Memory");
+ while(ct<v[0])
+ {
+ ItemArray[ct]=Allocate(ITEM);
+ ItemArray[ct]->it_MasterNext=NULL;
+ if(ct)
+ ItemArray[ct-1]->it_MasterNext=ItemArray[ct];
+ else
+ ItemList=ItemArray[ct];
+ ct++;
+ }
+ ItemArray[ct-1]->it_MasterNext=NULL;
+/*
+ * The above creates a correctly ordered linked set of trash items
+ */
+ return(v[0]);
+}
+
+static void SaveSub(file,s)
+FILE *file;
+register SUB *s;
+{
+ SaveShort(file,s->pr_Key);
+ switch(s->pr_Key)
+ {
+ case KEY_INOUTHERE:
+ SaveString(file,((INOUTHERE *)s)->io_InMsg);
+ SaveString(file,((INOUTHERE *)s)->io_OutMsg);
+ SaveString(file,((INOUTHERE *)s)->io_HereMsg);
+ break;
+ case KEY_USERFLAG2:
+ case KEY_USERFLAG:
+ SaveShort(file,((USERFLAG *)s)->uf_Flags[0]);
+ SaveShort(file,((USERFLAG *)s)->uf_Flags[1]);
+ SaveShort(file,((USERFLAG *)s)->uf_Flags[2]);
+ SaveShort(file,((USERFLAG *)s)->uf_Flags[3]);
+ SaveShort(file,((USERFLAG *)s)->uf_Flags[4]);
+ SaveShort(file,((USERFLAG *)s)->uf_Flags[5]);
+ SaveShort(file,((USERFLAG *)s)->uf_Flags[6]);
+ SaveShort(file,((USERFLAG *)s)->uf_Flags[7]);
+ SaveItem(file,((USERFLAG *)s)->uf_Items[0]);
+ SaveItem(file,((USERFLAG *)s)->uf_Items[1]);
+ SaveItem(file,((USERFLAG *)s)->uf_Items[2]);
+ SaveItem(file,((USERFLAG *)s)->uf_Items[3]);
+ SaveItem(file,((USERFLAG *)s)->uf_Items[4]);
+ SaveItem(file,((USERFLAG *)s)->uf_Items[5]);
+ SaveItem(file,((USERFLAG *)s)->uf_Items[6]);
+ SaveItem(file,((USERFLAG *)s)->uf_Items[7]);
+ break;
+ case KEY_CONTAINER:
+ SaveShort(file,((CONTAINER *)s)->co_Volume);
+ SaveShort(file,((CONTAINER *)s)->co_Flags);
+ break;
+ case KEY_CHAIN:
+ SaveItem(file,((CHAIN *)s)->ch_Chained);
+ break;
+ case KEY_ROOM:
+ SaveString(file,((ROOM *)s)->rm_Short);
+ SaveString(file,((ROOM *)s)->rm_Long);
+ SaveShort(file,((ROOM *)s)->rm_Flags);
+ break;
+ case KEY_OBJECT:
+ SaveString(file,((OBJECT *)s)->ob_Text[0]);
+ SaveString(file,((OBJECT *)s)->ob_Text[1]);
+ SaveString(file,((OBJECT *)s)->ob_Text[2]);
+ SaveString(file,((OBJECT *)s)->ob_Text[3]);
+ SaveShort(file,((OBJECT *)s)->ob_Size);
+ SaveShort(file,((OBJECT *)s)->ob_Weight);
+ SaveShort(file,((OBJECT *)s)->ob_Flags);
+ break;
+ case KEY_PLAYER:
+ SaveShort(file,((PLAYER *)s)->pl_UserKey);
+ SaveShort(file,((PLAYER *)s)->pl_Size);
+ SaveShort(file,((PLAYER *)s)->pl_Weight);
+ SaveShort(file,((PLAYER *)s)->pl_Strength);
+ SaveShort(file,((PLAYER *)s)->pl_Flags);
+ SaveShort(file,((PLAYER *)s)->pl_Level);
+ SaveLong(file,((PLAYER *)s)->pl_Score);
+ break;
+ case KEY_GENEXIT:
+ SaveItem(file,((GENEXIT *)s)->ge_Dest[0]);
+ SaveItem(file,((GENEXIT *)s)->ge_Dest[1]);
+ SaveItem(file,((GENEXIT *)s)->ge_Dest[2]);
+ SaveItem(file,((GENEXIT *)s)->ge_Dest[3]);
+ SaveItem(file,((GENEXIT *)s)->ge_Dest[4]);
+ SaveItem(file,((GENEXIT *)s)->ge_Dest[5]);
+ SaveItem(file,((GENEXIT *)s)->ge_Dest[6]);
+ SaveItem(file,((GENEXIT *)s)->ge_Dest[7]);
+ SaveItem(file,((GENEXIT *)s)->ge_Dest[8]);
+ SaveItem(file,((GENEXIT *)s)->ge_Dest[9]);
+ SaveItem(file,((GENEXIT *)s)->ge_Dest[10]);
+ SaveItem(file,((GENEXIT *)s)->ge_Dest[11]);
+ break;
+ case KEY_CONDEXIT:
+ SaveItem(file,((CONDEXIT *)s)->ce_Dest);
+ SaveShort(file,(short)((CONDEXIT *)s)->ce_Table);
+ SaveShort(file,(short)((CONDEXIT *)s)->ce_ExitNumber);
+ break;
+ case KEY_MSGEXIT:
+ SaveItem(file,((MSGEXIT *)s)->me_Dest);
+ SaveString(file,((MSGEXIT *)s)->me_Text);
+ SaveShort(file,((MSGEXIT *)s)->me_ExitNumber);
+ break;
+ case KEY_INHERIT:
+ SaveItem(file,((INHERIT *)s)->in_Master);
+ break;
+ case KEY_DUPED:
+ SaveItem(file,((DUP *)s)->du_Master);
+ break;
+ case KEY_USERTEXT:
+ SaveString(file,((USERTEXT *)s)->ut_Text[0]);
+ SaveString(file,((USERTEXT *)s)->ut_Text[1]);
+ SaveString(file,((USERTEXT *)s)->ut_Text[2]);
+ SaveString(file,((USERTEXT *)s)->ut_Text[3]);
+ SaveString(file,((USERTEXT *)s)->ut_Text[4]);
+ SaveString(file,((USERTEXT *)s)->ut_Text[5]);
+ SaveString(file,((USERTEXT *)s)->ut_Text[6]);
+ SaveString(file,((USERTEXT *)s)->ut_Text[7]);
+ break;
+ default:Error("Unknown Subtype");
+ }
+}
+
+static void LoadSub(file,item,type)
+FILE *file;
+ITEM *item;
+short type;
+{
+ TPTR xt;
+ switch(type)
+ {
+ case KEY_INOUTHERE:
+ {
+ SetInMsg(item,TextOf(xt=LoadString(file)));
+ FreeText(xt);
+ SetOutMsg(item,TextOf(xt=LoadString(file)));
+ FreeText(xt);
+ SetHereMsg(item,TextOf(xt=LoadString(file)));
+ FreeText(xt);
+ break;
+ }
+ case KEY_USERTEXT:
+ {
+ SetUText(item,0,(xt=LoadString(file)));
+ FreeText(xt);
+ SetUText(item,1,(xt=LoadString(file)));
+ FreeText(xt);
+ SetUText(item,2,(xt=LoadString(file)));
+ FreeText(xt);
+ SetUText(item,3,(xt=LoadString(file)));
+ FreeText(xt);
+ SetUText(item,4,(xt=LoadString(file)));
+ FreeText(xt);
+ SetUText(item,5,(xt=LoadString(file)));
+ FreeText(xt);
+ SetUText(item,6,(xt=LoadString(file)));
+ FreeText(xt);
+ SetUText(item,7,(xt=LoadString(file)));
+ FreeText(xt);
+ break;
+ }
+ case KEY_CONTAINER:
+ {
+ register CONTAINER *c=BeContainer(item);
+ c->co_Volume=LoadShort(file);
+ c->co_Flags=LoadShort(file);
+ break;
+ }
+ case KEY_USERFLAG:
+ case KEY_USERFLAG2:
+ {
+ register USERFLAG *u;
+ int x=0;
+ if(type==KEY_USERFLAG2)
+ x=8;
+ SetUserFlag(item,0+x,LoadShort(file));
+ SetUserFlag(item,1+x,LoadShort(file));
+ SetUserFlag(item,2+x,LoadShort(file));
+ SetUserFlag(item,3+x,LoadShort(file));
+ SetUserFlag(item,4+x,LoadShort(file));
+ SetUserFlag(item,5+x,LoadShort(file));
+ SetUserFlag(item,6+x,LoadShort(file));
+ SetUserFlag(item,7+x,LoadShort(file));
+ if(type==KEY_USERFLAG)
+ u=UserFlagOf(item);
+ else
+ u=UserFlag2Of(item);
+ u->uf_Items[0]=LoadItem(file);
+ u->uf_Items[1]=LoadItem(file);
+ u->uf_Items[2]=LoadItem(file);
+ u->uf_Items[3]=LoadItem(file);
+ if(Load_Format>7)
+ {
+ u->uf_Items[4]=LoadItem(file);
+ u->uf_Items[5]=LoadItem(file);
+ u->uf_Items[6]=LoadItem(file);
+ u->uf_Items[7]=LoadItem(file);
+ }
+ break;
+ }
+ case KEY_CHAIN:
+ {
+ ITEM *x=LoadItem(file);
+ AddNLChain(item,x);
+ break;
+ }
+ case KEY_ROOM:
+ {
+ register ROOM *a;
+ MakeRoom(item);
+ a=(ROOM *)FindSub(item,KEY_ROOM);
+ FreeText(a->rm_Short);
+ FreeText(a->rm_Long);
+ a->rm_Short=LoadString(file);
+ a->rm_Long=LoadString(file);
+ a->rm_Flags=LoadShort(file);
+ break;
+ }
+ case KEY_OBJECT:
+ {
+ register OBJECT *o;
+ MakeObject(item);
+ o=(OBJECT *)FindSub(item,KEY_OBJECT);
+ FreeText(o->ob_Text[0]);
+ FreeText(o->ob_Text[1]);
+ FreeText(o->ob_Text[2]);
+ FreeText(o->ob_Text[3]);
+ o->ob_Text[0]=LoadString(file);
+ o->ob_Text[1]=LoadString(file);
+ o->ob_Text[2]=LoadString(file);
+ o->ob_Text[3]=LoadString(file);
+ o->ob_Size=LoadShort(file);
+ o->ob_Weight=LoadShort(file);
+ o->ob_Flags=LoadShort(file);
+ break;
+ }
+ case KEY_PLAYER:
+ {
+ register PLAYER *p;
+ MakePlayer(item);
+ p=(PLAYER *)FindSub(item,KEY_PLAYER);
+ p->pl_UserKey=LoadShort(file);
+ p->pl_Size=LoadShort(file);
+ p->pl_Weight=LoadShort(file);
+ p->pl_Strength=LoadShort(file);
+ p->pl_Flags=LoadShort(file);
+ p->pl_Level=LoadShort(file);
+ p->pl_Score=LoadLong(file);
+ break;
+ }
+ case KEY_GENEXIT:
+ {
+ register GENEXIT *g;
+ MakeGenExit(item);
+ g=(GENEXIT *)FindSub(item,KEY_GENEXIT);
+ g->ge_Dest[0]=LoadItem(file);
+ g->ge_Dest[1]=LoadItem(file);
+ g->ge_Dest[2]=LoadItem(file);
+ g->ge_Dest[3]=LoadItem(file);
+ g->ge_Dest[4]=LoadItem(file);
+ g->ge_Dest[5]=LoadItem(file);
+ g->ge_Dest[6]=LoadItem(file);
+ g->ge_Dest[7]=LoadItem(file);
+ g->ge_Dest[8]=LoadItem(file);
+ g->ge_Dest[9]=LoadItem(file);
+ g->ge_Dest[10]=LoadItem(file);
+ g->ge_Dest[11]=LoadItem(file);
+ break;
+ }
+ case KEY_CONDEXIT:
+ {
+ register ITEM *a;
+ short c,d;
+ a=LoadItem(file);
+ c=LoadShort(file);
+ d=LoadShort(file);
+ /* MakeCond... sets its own locks */
+ MakeNLCondExit(item,a,c,d);
+ break;
+ }
+ case KEY_MSGEXIT:
+ {
+ ITEM *a;
+ TPTR b;
+ short c;
+ a=LoadItem(file);
+ b=LoadString(file);
+ c=LoadShort(file);
+ MakeNLMsgExit(item,a,c,TextOf(b));
+ FreeText(b);
+ break;
+ }
+ case KEY_INHERIT:
+ {
+ ITEM *a=LoadItem(file);
+ register INHERIT *d=(INHERIT *)AllocSub(item,KEY_INHERIT,
+ sizeof(INHERIT));
+ d->in_Master=a;
+ break;
+ }
+ case KEY_DUPED:
+ {
+ ITEM *a=LoadItem(file);
+ register DUP *d=(DUP *)AllocSub(item,KEY_DUPED,sizeof(DUP));
+ d->du_Master=a;
+ break;
+ }
+ default:Log("Subtype %d found!",type);
+ Error("Unknown Subtype");
+ }
+}
+
+static void LoadObject(file,i)
+register FILE *file;
+register ITEM *i;
+{
+ register long n;
+ i->it_Name=LoadString(file);
+/* printf("%s\n",TextOf(i->it_Name)); */
+ i->it_Adjective=LoadShort(file);
+ i->it_Noun=LoadShort(file);
+ i->it_State=LoadShort(file);
+ i->it_Perception=LoadShort(file);
+ i->it_Next=LoadItem(file);
+ i->it_Children=LoadItem(file);
+ i->it_Parent=LoadItem(file);
+ i->it_ActorTable=LoadShort(file);
+ i->it_ActionTable=LoadShort(file);
+ i->it_Users=LoadShort(file);
+ i->it_Class=LoadShort(file);
+ if(Load_Format>8)
+ {
+ if(LoadShort(file))
+ i->it_Superclass=LoadItem(file);
+ else
+ i->it_Superclass=NULL;
+ }
+ i->it_Properties=NULL;
+ n=LoadLong(file); /* props */
+ if(n==0)
+ return;
+ while(n)
+ {
+ n=LoadShort(file);
+ if(n)
+ LoadSub(file,i,(short)n);
+ }
+ if(Load_Format>5)
+ {
+ i->it_ObjectTable=LoadItemTable(file);
+ i->it_SubjectTable=LoadItemTable(file);
+ if(Load_Format>8)
+ i->it_DaemonTable=LoadItemTable(file);
+ else
+ i->it_DaemonTable=NULL;
+ }
+ else
+ {
+ i->it_ObjectTable=NULL;
+ i->it_SubjectTable=NULL;
+ }
+}
+
+static void SaveObject(file,i)
+register FILE *file;
+register ITEM *i;
+{
+ SUB *n;
+ KillEventQueue(i);
+ SaveString(file,i->it_Name);
+ SaveShort(file,i->it_Adjective);
+ SaveShort(file,i->it_Noun);
+ SaveShort(file,i->it_State);
+ SaveShort(file,i->it_Perception);
+ SaveItem(file,i->it_Next);
+ SaveItem(file,i->it_Children);
+ SaveItem(file,i->it_Parent);
+ SaveShort(file,i->it_ActorTable);
+ SaveShort(file,i->it_ActionTable);
+ SaveShort(file,i->it_Users);
+ SaveShort(file,i->it_Class);
+ if(i->it_Superclass)
+ {
+ SaveShort(file,1);
+ SaveItem(file,i->it_Superclass);
+ }
+ else
+ SaveShort(file,0);
+ SaveLong(file,(unsigned long)i->it_Properties);
+ n=i->it_Properties;
+ if(n==0)
+ return;
+ while(n)
+ {
+ SaveSub(file,n);
+ n=n->pr_Next;
+ }
+ SaveShort(file,0); /* Prop end marker */
+ SaveItemTable(file,i->it_ObjectTable);
+ SaveItemTable(file,i->it_SubjectTable);
+ SaveItemTable(file,i->it_DaemonTable);
+}
+
+unsigned short *SaveAction(file,c)
+FILE *file;
+register unsigned short *c;
+{
+ int cc=*c;
+ TPTR t;
+ ITEM *i;
+ register char *ptr;
+ SaveShort(file,*c++);
+ ptr=Cnd_Table[cc];
+ while(*ptr!=' ')
+ {
+ switch(*ptr++)
+ {
+ case '$':;
+ case 'T':t=(TPTR )GetTwo(c);
+ c+=2;
+ if(t==(TPTR )1)
+ SaveShort(file,0);
+ else
+ {
+ if(t==(TPTR)3)
+ SaveShort(file,3);
+ else
+ {
+ SaveShort(file,1);
+ SaveString(file,t);
+ }
+ }
+ break;
+ case 'I':i=(ITEM *)GetTwo(c);
+ c+=2;
+ if(i==(ITEM *)1)
+ {
+ SaveShort(file,1);
+ break;
+ }
+ if(i==(ITEM *)3)
+ {
+ SaveShort(file,3);
+ break;
+ }
+ if(i==(ITEM *)5)
+ {
+ SaveShort(file,5);
+ break;
+ }
+ if(i==(ITEM *)7)
+ {
+ SaveShort(file,7);
+ break;
+ }
+ if(i==(ITEM *)9)
+ {
+ SaveShort(file,9);
+ break;
+ }
+ SaveShort(file,0);
+ SaveItem(file,i);
+ break;
+ case 'C':;
+ case 'R':;
+ case 'O':;
+ case 'P':;
+ case 'c':;
+ case 'B':;
+ case 'F':;
+ case 'v':;
+ case 'p':;
+ case 'n':;
+ case 'a':;
+ case 't':;
+ case 'N':SaveShort(file,*c++);
+ break;
+ default:Error("Save: Bad Cnd_Table Entry");
+ }
+ }
+ return(c);
+}
+
+short *LoadAction(file,c)
+FILE *file;
+register short *c;
+{
+ short cc=*c++;
+ ITEM *i;
+ TPTR t;
+ register char *ptr=Cnd_Table[cc];
+ while(*ptr!=' ')
+ {
+ switch(*ptr++)
+ {
+ case '$':switch(LoadShort(file))
+ {
+ case 0:t=(TPTR)1;break;
+ case 3:t=(TPTR)3;break;
+ default:t=LoadComment(file);
+ }
+ SetTwo(c,(char *)t);
+ c+=2;
+ break;
+ case 'T':switch(LoadShort(file))
+ {
+ case 0:t=(TPTR )1;break;
+ case 3:t=(TPTR) 3;break;
+ default:t=LoadString(file);
+ }
+ SetTwo(c,(char *)t);
+ c+=2;
+ break;
+ case 'I':switch(LoadShort(file))
+ {
+ case 1:i=(ITEM *)1;break;
+ case 3:i=(ITEM *)3;break;
+ case 5:i=(ITEM *)5;break;
+ case 7:i=(ITEM *)7;break;
+ case 9:i=(ITEM *)9;break;
+ default:i=LoadItem(file);
+ }
+ SetTwo(c,(char *)i);
+ c+=2;
+ break;
+ case 'B':;
+ case 'C':;
+ case 'c':;
+ case 'R':;
+ case 'O':;
+ case 'P':;
+ case 'F':;
+ case 'v':;
+ case 'p':;
+ case 'n':;
+ case 'a':;
+ case 't':;
+ case 'N':*c++=LoadShort(file);
+ break;
+ default:Error("Load: Bad Cnd_Table Entry");
+ }
+ }
+ return(c);
+}
+
+void LoadLine(file,l)
+FILE *file;
+register LINE *l;
+{
+ short *a=(short *)malloc(1024);
+ register short *b=a;
+ if(a==NULL)
+ Error("Out Of Memory");
+ l->li_Verb=LoadShort(file);
+ l->li_Noun1=LoadShort(file);
+ l->li_Noun2=LoadShort(file);
+ while((*b=LoadShort(file))!=CMD_EOL)
+ {
+ b=LoadAction(file,b);
+ }
+ free(l->li_Data);
+ l->li_Data=(unsigned short *)malloc(sizeof(short)*(b-a+2));
+ memcpy((char *)l->li_Data,(char *)a,sizeof(short)*(b-a+2));
+ free((char *)a);
+}
+
+void SaveLine(file,l)
+FILE *file;
+LINE *l;
+{
+ unsigned short *a=l->li_Data;
+ SaveShort(file,l->li_Verb);
+ SaveShort(file,l->li_Noun1);
+ SaveShort(file,l->li_Noun2);
+ while(*a!=CMD_EOL)
+ {
+ a=SaveAction(file,a);
+ }
+ SaveShort(file,CMD_EOL);
+}
+
+TABLE *LoadItemTable(file)
+FILE *file;
+{
+ TABLE *t;
+ int x=LoadShort(file);
+ if(x==0)
+ return(NULL);
+ t=Allocate(TABLE);
+ LoadShort(file);
+ LoadTable(file,t);
+ return(t);
+}
+
+void SaveItemTable(file,t)
+FILE *file;
+TABLE *t;
+{
+ if(t==NULL)
+ {
+ SaveShort(file,0);
+ }
+ else
+ {
+ SaveShort(file,1);
+ SaveTable(file,t);
+ }
+}
+
+void LoadTable(file,t)
+FILE *file;
+TABLE *t;
+{
+ register LINE *l;
+ if(Load_Format>4)
+ t->tb_Name=LoadString(file);
+ else
+ t->tb_Name=AllocText("(unset)");
+ while(LoadShort(file)==0)
+ {
+ l=NewLine(t,65535);
+ LoadLine(file,l);
+ }
+}
+
+void SaveTable(file,t)
+FILE *file;
+TABLE *t;
+{
+ register LINE *l=t->tb_First;
+ SaveShort(file,t->tb_Number);
+ SaveString(file,t->tb_Name);
+ while(l)
+ {
+ SaveShort(file,0);
+ SaveLine(file,l);
+ l=l->li_Next;
+ }
+ SaveShort(file,1);
+}
+
+void LoadAllTables(file)
+FILE *file;
+{
+ register TABLE *t;
+ while(LoadShort(file)==0)
+ {
+ t=NewTable(LoadShort(file),NULL);
+ LoadTable(file,t);
+ }
+}
+
+void SaveAllTables(file)
+FILE *file;
+{
+ register TABLE *t=TableList;
+ while(t)
+ {
+ SaveShort(file,0);
+ SaveTable(file,t);
+ t=t->tb_Next;
+ }
+ SaveShort(file,1);
+}
+
+extern char *FlagName[];
+
+static void SaveFlag(file,s)
+FILE *file;
+short s;
+{
+ register char *str=FlagName[s];
+ short v;
+ if(str==NULL)
+ SaveShort(file,0);
+ else
+ {
+ v=strlen(str);
+/* printf("%d %ld\n",(int)s,v); */
+ SaveShort(file,v);
+ if(fwrite(str,strlen(str),1,file)!=1)
+ Load_Error=errno;
+ }
+}
+
+
+void LoadFlag(file,n)
+FILE *file;
+register short n;
+{
+ register char *a;
+ long v=LoadShort(file);
+/* printf("FLAG %d V=%ld",(int)n,v); */
+ if(v==0)
+ {
+ SetFlagName(n,NULL);
+ }
+ else
+ {
+ a=malloc(v+1);
+ if(!a)
+ Error("Out Of Memory");
+ if(fread(a,v,1,file)!=1)
+ Load_Error=errno;
+ a[v]=0;
+ SetFlagName(n,a);
+ free(a);
+ }
+}
+
+static void LoadClass(a,c)
+FILE *a;
+short c;
+{
+ if(LoadShort(a))
+ SetClassTxt(c,LoadString(a));
+ else
+ SetClassName(c,NULL);
+}
+
+static void SaveClass(a,c)
+FILE *a;
+short c;
+{
+ if(GetClassTxt(c))
+ {
+ SaveShort(a,1);
+ SaveString(a,GetClassTxt(c));
+ }
+ else
+ SaveShort(a,0);
+}
+
+void SaveBitFlags(f)
+FILE *f;
+{
+ int ct=0;
+ while(ct<16)
+ {
+ fprintf(f,"%s\001",RBitName(ct));
+ fprintf(f,"%s\001",OBitName(ct));
+ fprintf(f,"%s\001",PBitName(ct));
+ fprintf(f,"%s\001",CBitName(ct));
+ ct++;
+ }
+}
+
+static char *LoadDupStr(x)
+char *x;
+{
+ char *a=strdup(x);
+ if(!a)
+ {
+ fprintf(stderr,"Out Of Memory");
+ exit(0);
+ }
+ return(a);
+}
+
+void LodBuf(f,x)
+FILE *f;
+char *x;
+{
+ while((*x=fgetc(f))!='\001')
+ x++;
+ *x=0;
+}
+
+void LoadBitFlags(f)
+FILE *f;
+{
+ int ct=0;
+ char buf[256];
+ while(ct<16)
+ {
+ LodBuf(f,buf);
+ RBitNames[ct]=LoadDupStr(buf);
+ LodBuf(f,buf);
+ OBitNames[ct]=LoadDupStr(buf);
+ LodBuf(f,buf);
+ PBitNames[ct]=LoadDupStr(buf);
+ LodBuf(f,buf);
+ CBitNames[ct]=LoadDupStr(buf);
+ ct++;
+ }
+}
+
+void SaveBSXImages(file)
+FILE *file;
+{
+ extern BSXImage *BSXFindFirst(),*BSXFindNext();
+ BSXImage *i=BSXFindFirst();
+ while(i!=NULL)
+ {
+ SaveShort(file,1);
+ SaveBSX(file,i);
+ i=BSXFindNext(i);
+ }
+ SaveShort(file,0);
+}
+
+void LoadBSXImages(file)
+FILE *file;
+{
+ int i;
+ i=LoadShort(file);
+ while(i!=0)
+ {
+ LoadBSX(file);
+ i=LoadShort(file);
+ }
+}
+
+int SaveSystem(n)
+char *n;
+{
+ register ITEM *i;
+ static char b[140]; /* Max file name length =128 */
+ FILE *a=fopen(n,"r");
+ register short c=0;
+ sprintf(b,"%s.bak",n);
+ if(a)
+ {
+ fclose(a);
+ unlink(b); /* Can't rename over another file */
+ if(rename(n,b)==-1)
+ {
+ return(-1);
+ } /* TRY LINK(a,b) ON UNIX - OR
+ SEE /usr/src/bin/passwd.c FOR YOUR CLONE. ANYWAY
+ RENAME IS ANSI ...*/
+ }
+/* Now to save */
+ a=fopen(n,"w");
+ if(a==NULL)
+ return(-2);
+ Load_Error=0;
+ WriteHeader(a);
+ i=ItemList;
+ while(i)
+ {
+ SaveObject(a,i);
+ i=i->it_MasterNext;
+ }
+ SaveAllTables(a);
+ SaveVocab(a);
+ while(c<512)
+ SaveFlag(a,c++);
+ c=0;
+ while(c<16)
+ SaveClass(a,c++);
+ SaveBitFlags(a);
+ SaveBSXImages(a);
+ if(ferror(a)&&Load_Error==0)
+ Load_Error=errno;
+ fclose(a);
+ return(Load_Error);
+}
+
+
+int LoadSystem(n)
+char *n;
+{
+ FILE *a=fopen(n,"r");
+ register long ct=0;
+ long v,c=0;
+ if(a==NULL)
+ return(-1);
+ Load_Error=0;
+ v=ReadHeader(a); /* Set up items */
+ while(ct<v)
+ {
+ LoadObject(a,ItemArray[ct]);
+ ct++;
+ }
+ LoadAllTables(a);
+ free((char *)ItemArray); /* Free Reloc Info */
+ LoadVocab(a);
+ if(Load_Format>1) /* If new format database.. */
+ while(c<512)
+ LoadFlag(a,c++);
+ if(Load_Format>2) /* If 5.05 dbm load classes */
+ {
+ c=0;
+ while(c<16)
+ LoadClass(a,c++);
+ }
+ if(Load_Format>4) /* 5.07 load bit flags too */
+ LoadBitFlags(a);
+ if(Load_Format>9)
+ LoadBSXImages(a);
+ fclose(a);
+ Log("Load Read Completed");
+ return(Load_Error);
+}
+
+
+
diff --git a/Snoop.c b/Snoop.c
new file mode 100644
index 0000000..d33a4b3
--- /dev/null
+++ b/Snoop.c
@@ -0,0 +1,119 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+
+/*
+ * Snoop handlers
+ *
+ * 1.00 Initial release
+ * 1.01 Strict ANSIfication
+ */
+
+Module "Snooping";
+Version "1.01";
+Author "----* (A)";
+
+/*
+ * Snoop control functions - full multiple depths
+ * Limit set at 2
+ */
+
+int StartSnoop(ITEM *from, ITEM *to, short type)
+{
+ SNOOP *s;
+ SNOOPBACK *b;
+ if(from==to)
+ return(-1); /* No Self Snoop Please */
+ s=(SNOOP *)AllocSub(to,KEY_SNOOP,sizeof(SNOOP));
+ b=(SNOOPBACK *)AllocSub(from,KEY_SNOOPBACK,sizeof(SNOOPBACK));
+ b->sb_SnoopKey=s;
+ s->sn_BackPtr=b;
+ b->sb_Snooped=to;
+ s->sn_Snooper=from;
+ LockItem(from);
+ LockItem(to);
+ s->sn_String[0]='|';
+ s->sn_String[1]=0;
+ s->sn_Ident=type;
+ return 0;
+}
+
+void StopSnoop(ITEM *i, SNOOP *s)
+{
+ UnlockItem(s->sn_Snooper);
+ UnlockItem(i);
+ FreeSub(s->sn_Snooper,(SUB *)s->sn_BackPtr);
+ FreeSub(i,(SUB *)s);
+}
+
+void StopSnoopOn(ITEM *i, ITEM *at)
+{
+ SNOOPBACK *b;
+ b=(SNOOPBACK *)FindSub(i,KEY_SNOOP);
+ while(b)
+ {
+ if(b->sb_Snooped==at)
+ StopSnoop(b->sb_Snooped,b->sb_SnoopKey);
+ b=(SNOOPBACK *)NextSub((SUB *)b,KEY_SNOOPBACK);
+ }
+}
+
+void StopAllSnoops(ITEM *i) /* Stop all snoops by I */
+{
+ SNOOPBACK *b;
+ while((b=(SNOOPBACK *)FindSub(i,KEY_SNOOPBACK))!=NULL)
+ {
+ StopSnoop(b->sb_Snooped,b->sb_SnoopKey);
+ }
+}
+
+void StopSnoopsOn(ITEM *x)
+{
+ SNOOP *s;
+ while((s=(SNOOP *)FindSub(x,KEY_SNOOP))!=NULL)
+ {
+ SendItem(s->sn_Snooper,"You can no longer snoop on %s.\n",
+ NameOf(x));
+ StopSnoop(x,s);
+ }
+}
+
+void SnoopCheckString(ITEM *i, char *x)
+{
+ SnoopCheckRec(i,x,0);
+}
+
+/*
+ * Primary Snoop Validating Logic
+ *
+ * We limit the depth to 10 (CURR 2) layers of recursion -> which you can get esp
+ * if a watches b watches a!
+ */
+
+int SnoopCheckRec(ITEM *i, char *x, short d)
+{
+ short c=d+1;
+ SNOOP *s;
+ if(d>1)
+ return(-1);
+ s=(SNOOP *)FindSub(i,KEY_SNOOP);
+ while(s)
+ {
+/* while(c--)
+ SendItemDirect(s->sn_Snooper,s->sn_String);*/
+ c=d;
+ SendItemDirect(s->sn_Snooper,x);
+ SnoopCheckRec(s->sn_Snooper,x,(short)(d+1));
+ s=(SNOOP *)NextSub((SUB *)s,KEY_SNOOP);
+ }
+ return(0);
+}
+
diff --git a/Socket.c b/Socket.c
new file mode 100644
index 0000000..b8b9606
--- /dev/null
+++ b/Socket.c
@@ -0,0 +1,48 @@
+/*
+ * Set up a socket
+ *
+ * Alan Cox 1990
+ *
+ * This software is placed in the public domain
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <unistd.h>
+
+
+/*
+ * Create the client socket
+ */
+
+int Make_Connection(int port,const char *buf)
+{
+ struct sockaddr_in myaddress;
+ struct hostent *host;
+ int v;
+ host=gethostbyname(buf);
+ if(host==NULL)
+ {
+ return(-1);
+ }
+ myaddress.sin_family=host->h_addrtype;
+ myaddress.sin_addr.s_addr=*((long *)host->h_addr);
+ myaddress.sin_port=htons(port);
+ v=socket(AF_INET,SOCK_STREAM,0);
+ if(v==-1)
+ {
+ return(-1);
+ }
+ if(connect(v,(struct sockaddr *)&myaddress,sizeof(myaddress))<0)
+ {
+ close(v);
+ return(-1);
+ }
+ return(v);
+}
+
diff --git a/SubHandler.c b/SubHandler.c
new file mode 100644
index 0000000..90f20f4
--- /dev/null
+++ b/SubHandler.c
@@ -0,0 +1,614 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Substructure handlers
+ *
+ * 1.00 Handlers For ROOM PLAYER OBJECT
+ * 1.02 Exit Handlers Added For GENEXIT
+ * 1.03 Message And Conditional Exit Drivers Added
+ * 1.10 New SubTypes CONTAINER and CHAIN
+ * 1.12 BACKTRACK System Added - Avoids Players Sticking On UserItems
+ * 1.13 Fixed bug in UnGenExit
+ * 1.14 Added INHERIT
+ * 1.15 Fixed bug in UnUserFlag
+ * 1.16 Register Optimisations Added
+ * 1.17 SetIn SetOut SetHere added
+ * 1.18 BACKTRACK system dumped
+ * 1.19 USERTEXT added
+ * 1.20 Tidying for release 5.06
+ * 1.21 Added USERFLAG2 Entries, Added working CondExit system(at last)
+ * 1.22 Strict ANSIfication
+ */
+
+#include "System.h"
+
+Module "Substructure Handler";
+Version "1.22";
+Author "----*(A)";
+
+
+int MakeRoom(ITEM *x)
+{
+ register ROOM *a;
+ if(FindSub(x,KEY_ROOM))
+ return(-1); /* Already is */
+ a=(ROOM *)AllocSub(x,KEY_ROOM,sizeof(ROOM));
+ a->rm_Short=AllocText("Room");
+ a->rm_Long=AllocText("Description");
+ a->rm_Flags=0;
+ return(0);
+}
+
+int UnRoom(ITEM *i)
+{
+ register ROOM *x=(ROOM *)FindSub(i,KEY_ROOM);
+ if(x==NULL)
+ return(-1);
+ FreeText(x->rm_Short);
+ FreeText(x->rm_Long);
+ FreeSub(i,(SUB *)x);
+ return(0);
+}
+
+int MakeObject(ITEM *x)
+{
+ register OBJECT *a;
+ if(FindSub(x,KEY_OBJECT))
+ return(-1); /* Already is */
+ a=(OBJECT *)AllocSub(x,KEY_OBJECT,sizeof(OBJECT));
+ a->ob_Text[0]=AllocText("<unset>");
+ a->ob_Text[1]=AllocText("");
+ a->ob_Text[2]=AllocText("");
+ a->ob_Text[3]=AllocText("");
+ a->ob_Size=0;
+ a->ob_Weight=0;
+ a->ob_Flags=0;
+ return(0);
+}
+
+int UnObject(ITEM *i)
+{
+ register OBJECT *x=(OBJECT *)FindSub(i,KEY_OBJECT);
+ if(x==NULL)
+ return(-1);
+ FreeText(x->ob_Text[0]);
+ FreeText(x->ob_Text[1]);
+ FreeText(x->ob_Text[2]);
+ FreeText(x->ob_Text[3]);
+ FreeSub(i,(SUB *)x);
+ return(0);
+}
+
+int MakePlayer(ITEM *x)
+{
+ register PLAYER *a;
+ if(FindSub(x,KEY_PLAYER))
+ return(-1); /* Already is */
+ a=(PLAYER *)AllocSub(x,KEY_PLAYER,sizeof(PLAYER));
+ a->pl_UserKey=-1;
+ a->pl_Size=0;
+ a->pl_Weight=0;
+ a->pl_Flags=0;
+ a->pl_Level=0;
+ a->pl_Score=0;
+ a->pl_Strength=0;
+ return(0);
+}
+
+int UnPlayer(ITEM *i)
+{
+ register PLAYER *x=(PLAYER *)FindSub(i,KEY_PLAYER);
+ if(x==NULL)
+ return(-1);
+ FreeSub(i,(SUB *)x);
+ return(0);
+}
+
+int MakeGenExit(ITEM *x)
+{
+ register GENEXIT *a;
+ if(FindSub(x,KEY_GENEXIT)) /* Only one genexit a room */
+ return(-1); /* Already is */
+ a=(GENEXIT *)AllocSub(x,KEY_GENEXIT,sizeof(GENEXIT));
+ a->ge_Dest[0]=0;
+ a->ge_Dest[1]=0;
+ a->ge_Dest[2]=0;
+ a->ge_Dest[3]=0;
+ a->ge_Dest[4]=0;
+ a->ge_Dest[5]=0;
+ a->ge_Dest[6]=0;
+ a->ge_Dest[7]=0;
+ a->ge_Dest[8]=0;
+ a->ge_Dest[9]=0;
+ a->ge_Dest[10]=0;
+ a->ge_Dest[11]=0;
+ return(0);
+}
+
+int UnGenExit(ITEM *i)
+{
+ register short ct=0;
+ register GENEXIT *x=(GENEXIT *)FindSub(i,KEY_GENEXIT);
+ if(x==NULL)
+ return(-1);
+ while(ct<12)
+ {
+ if(x->ge_Dest[ct])
+ UnlockItem(x->ge_Dest[ct]); /* Exits should be locked on add */
+ ct++;
+ }
+ FreeSub(i,(SUB *)x);
+ return(0);
+}
+
+CONDEXIT *MakeCondExit(ITEM *x, ITEM *to, short table, short exit)
+{
+ register CONDEXIT *a;
+ a=(CONDEXIT *)FindCondExit(x,exit);
+ if(a)
+ UnCondExit(x,a);
+ a=(CONDEXIT *)AllocSub(x,KEY_CONDEXIT,sizeof(CONDEXIT));
+ a->ce_ExitNumber=exit;
+ a->ce_Table=table;
+ a->ce_Dest=to;
+ if(to)
+ LockItem(to); /* Lock since referred to */
+ return(a);
+}
+
+CONDEXIT *MakeNLCondExit(ITEM *x, ITEM *to, short table, short exit)
+{
+ register CONDEXIT *a;
+ a=(CONDEXIT *)FindCondExit(x,exit);
+ if(a)
+ UnCondExit(x,a);
+ a=(CONDEXIT *)AllocSub(x,KEY_CONDEXIT,sizeof(CONDEXIT));
+ a->ce_ExitNumber=exit;
+ a->ce_Table=table;
+ a->ce_Dest=to;
+ return(a);
+}
+
+int UnCondExit(ITEM *i, register CONDEXIT *x) /* Sub to give which one to do*/
+{
+ if(x->ce_Dest!=NULL)
+ UnlockItem(x->ce_Dest);
+ FreeSub(i,(SUB *)x);
+ return(0);
+}
+
+CONDEXIT *FindCondExit(ITEM *i, short d)
+{
+ register CONDEXIT *a=(CONDEXIT *)FindSub(i,KEY_CONDEXIT);
+ while(a)
+ {
+ if(a->ce_ExitNumber==d)
+ return(a);
+ a=(CONDEXIT *)NextSub((SUB *)a,KEY_CONDEXIT);
+ }
+ return(NULL);
+}
+
+MSGEXIT *MakeMsgExit(ITEM *x, ITEM *to, short d, char *msg)
+{
+ register MSGEXIT *a;
+ a=FindMsgExit(x,d);
+ if(a)
+ UnMsgExit(x,a);
+ a=(MSGEXIT *)AllocSub(x,KEY_MSGEXIT,sizeof(MSGEXIT));
+ a->me_Dest=to;
+ if(to)
+ LockItem(a->me_Dest);
+ a->me_ExitNumber=d;
+ a->me_Text=AllocText(msg);
+ return(a);
+}
+
+MSGEXIT *MakeNLMsgExit(ITEM *x, ITEM *to, short d, char *msg)
+{
+ register MSGEXIT *a;
+ a=FindMsgExit(x,d);
+ if(a)
+ UnMsgExit(x,a);
+ a=(MSGEXIT *)AllocSub(x,KEY_MSGEXIT,sizeof(MSGEXIT));
+ a->me_Dest=to;
+ a->me_ExitNumber=d;
+ a->me_Text=AllocText(msg);
+ return(a);
+}
+
+int UnMsgExit(ITEM *i, register MSGEXIT *x)
+{
+ if(x->me_Dest)
+ UnlockItem(x->me_Dest);
+ FreeText(x->me_Text);
+ FreeSub(i,(SUB *)x);
+ return(0);
+}
+
+MSGEXIT *FindMsgExit(ITEM *i, short d)
+{
+ register MSGEXIT *a=(MSGEXIT *)FindSub(i,KEY_MSGEXIT);
+ while(a)
+ {
+ if(a->me_ExitNumber==d)
+ return(a);
+ a=(MSGEXIT *)NextSub((SUB *)a,KEY_MSGEXIT);
+ }
+ return(NULL);
+}
+
+int AddChain(ITEM *i, ITEM *t)
+{
+ register CHAIN *c;
+ if(FindChain(i,t))
+ return(1);
+ c=(CHAIN *)AllocSub(i,KEY_CHAIN,sizeof(CHAIN));
+ c->ch_Chained=t;
+ LockItem(t);
+ return(1);
+}
+
+int AddNLChain(ITEM *i, ITEM *t)
+{
+ register CHAIN *c;
+ if(FindChain(i,t))
+ return(1);
+ c=(CHAIN *)AllocSub(i,KEY_CHAIN,sizeof(CHAIN));
+ c->ch_Chained=t;
+ LockItem(t);
+ return(1);
+}
+
+CHAIN *FindChain(ITEM *i, ITEM *x)
+{
+ register CHAIN *c;
+ c=(CHAIN *)FindSub(i,KEY_CHAIN);
+ while(c)
+ {
+ if(c->ch_Chained==x)
+ return(c);
+ c=(CHAIN *)NextSub((SUB *)c,KEY_CHAIN);
+ }
+ return(NULL);
+}
+
+int RemoveChain(ITEM *i, register ITEM *x)
+{
+ register CHAIN *c;
+ c=FindChain(i,x);
+ if(c==NULL)
+ return(-1);
+ else
+ {
+ UnlockItem(x);
+ FreeSub(i,(SUB *)c);
+ }
+ return(0);
+}
+
+
+void SynchChain(ITEM *i)
+{
+ register CHAIN *c;
+ c=(CHAIN *)FindSub(i,KEY_CHAIN);
+ while(c)
+ {
+ SetState(c->ch_Chained,O_STATE(i));
+ c=(CHAIN *)NextSub((SUB *)c,KEY_CHAIN);
+ }
+ return;
+}
+
+CONTAINER *BeContainer(ITEM *x)
+{
+ register CONTAINER *c=(CONTAINER *)FindSub(x,KEY_CONTAINER);
+ if(c)
+ return(NULL);
+ c=(CONTAINER *)AllocSub(x,KEY_CONTAINER,sizeof(CONTAINER));
+ c->co_Volume=0;
+ c->co_Flags=0;
+ return(c);
+}
+
+int UnContainer(ITEM *x)
+{
+ CONTAINER *c;
+ if((c=(CONTAINER *)FindSub(x,KEY_CONTAINER))==NULL)
+ return(-1);
+ FreeSub(x,(SUB *)c);
+ return(0);
+}
+
+int GetUserFlag(ITEM *i, int n)
+{
+ USERFLAG *x;
+ if(n<8)
+ x=(USERFLAG *)FindSub(i,KEY_USERFLAG);
+ else
+ x=(USERFLAG *)FindSub(i,KEY_USERFLAG2);
+ if(x==NULL)
+ return(0);
+ if((n<0)||(n>15))
+ {
+ Log("Userflag out of range");
+ return(0);
+ }
+ return(x->uf_Flags[(short)(n%8)]);
+}
+
+ITEM *GetUserItem(ITEM *i, int n)
+{
+ USERFLAG *x;
+ if(n<8)
+ x=(USERFLAG *)FindSub(i,KEY_USERFLAG);
+ else
+ x=(USERFLAG *)FindSub(i,KEY_USERFLAG2);
+ if(x==NULL)
+ return(0);
+ if((n<0)||(n>15))
+ {
+ Log("UserItem out of range");
+ return(0);
+ }
+ return(x->uf_Items[(short)(n%8)]);
+}
+
+void SetUserFlag(ITEM *i, int n, int m)
+{
+ register USERFLAG *x;
+ if(n<8)
+ x=(USERFLAG *)FindSub(i,KEY_USERFLAG);
+ else
+ x=(USERFLAG *)FindSub(i,KEY_USERFLAG2);
+ if(x==NULL)
+ {
+ x=(USERFLAG *)AllocSub(i,n<8?KEY_USERFLAG:KEY_USERFLAG2,sizeof(USERFLAG));
+ InitUserFlag(x);
+ }
+ if((n<0)||(n>15))
+ {
+ Log("Userflag out of range");
+ return;
+ }
+ x->uf_Flags[n%8]=m;
+}
+
+void SetUserItem(ITEM *i, int n, ITEM *m)
+{
+ register USERFLAG *x;
+ if(n<8)
+ x=(USERFLAG *)FindSub(i,KEY_USERFLAG);
+ else
+ x=(USERFLAG *)FindSub(i,KEY_USERFLAG2);
+ if(x==NULL)
+ {
+ x=(USERFLAG *)AllocSub(i,n<8?KEY_USERFLAG:KEY_USERFLAG2,
+ sizeof(USERFLAG));
+ InitUserFlag(x);
+ }
+ if((n<0)||(n>15))
+ {
+ Log("UserItem out of range");
+ return;
+ }
+ if(x->uf_Items[n%8])
+ {
+ UnlockItem(x->uf_Items[n%8]);
+ }
+ if(m)
+ {
+ LockItem(m);
+ }
+ x->uf_Items[n%8]=m;
+}
+
+int UnUserFlag(ITEM *x)
+{
+ register USERFLAG *u=(USERFLAG *)FindSub(x,KEY_USERFLAG);
+ UnUserBlock(u,x);
+ u=(USERFLAG *)FindSub(x,KEY_USERFLAG2);
+ if(u==NULL)
+ return(-1);
+ UnUserBlock(u,x);
+ return(0);
+}
+
+
+int UnUserBlock(USERFLAG *u, ITEM *x)
+{
+ register short ct=0;
+ if(u==NULL)
+ return(-1);
+ while(ct<8)
+ {
+ if(u->uf_Items[ct])
+ {
+ UnlockItem(u->uf_Items[ct]);
+ }
+ ct++;
+ }
+ FreeSub(x,(SUB *)u);
+ return(0);
+}
+
+void InitUserFlag(register USERFLAG *x)
+{
+ x->uf_Items[0]=NULL;
+ x->uf_Items[1]=NULL;
+ x->uf_Items[2]=NULL;
+ x->uf_Items[3]=NULL;
+ x->uf_Items[4]=NULL;
+ x->uf_Items[5]=NULL;
+ x->uf_Items[6]=NULL;
+ x->uf_Items[7]=NULL;
+ x->uf_Flags[0]=0;
+ x->uf_Flags[1]=0;
+ x->uf_Flags[2]=0;
+ x->uf_Flags[3]=0;
+ x->uf_Flags[4]=0;
+ x->uf_Flags[5]=0;
+ x->uf_Flags[6]=0;
+ x->uf_Flags[7]=0;
+}
+
+int MakeInherit(ITEM *x, ITEM *y)
+{
+ register INHERIT *a;
+ if((a=(INHERIT *)FindSub(x,KEY_INHERIT))!=NULL)
+ {
+ a->in_Master=y;
+ return(0); /* Already is */
+ }
+ a=(INHERIT *)AllocSub(x,KEY_INHERIT,sizeof(INHERIT));
+ a->in_Master=y;
+ LockItem(y);
+ return(0);
+}
+
+int UnInherit(ITEM *i)
+{
+ register INHERIT *x=(INHERIT *)FindSub(i,KEY_INHERIT);
+ if(x==NULL)
+ return(-1);
+ UnlockItem(x->in_Master);
+ FreeSub(i,(SUB *)x);
+ return(0);
+}
+
+ITEM *Inheritor(ITEM *a)
+{
+ INHERIT *b;
+ b=(INHERIT *)FindSub(a,KEY_INHERIT);
+ if(b==NULL)
+ return(NULL);
+ return(b->in_Master);
+}
+
+
+static USERTEXT *GetUT(ITEM *i)
+{
+ register USERTEXT *u=(USERTEXT *)FindSub(i,KEY_USERTEXT);
+ if(u)
+ return(u);
+ u=(USERTEXT *)AllocSub(i,KEY_USERTEXT,sizeof(USERTEXT));
+ u->ut_Text[0]=AllocText("");
+ u->ut_Text[1]=AllocText("");
+ u->ut_Text[2]=AllocText("");
+ u->ut_Text[3]=AllocText("");
+ u->ut_Text[4]=AllocText("");
+ u->ut_Text[5]=AllocText("");
+ u->ut_Text[6]=AllocText("");
+ u->ut_Text[7]=AllocText("");
+ return(u);
+}
+
+void UnUserText(ITEM *i)
+{
+ USERTEXT *u=GetUT(i);
+ if(u)
+ {
+ FreeText(u->ut_Text[0]);
+ FreeText(u->ut_Text[1]);
+ FreeText(u->ut_Text[2]);
+ FreeText(u->ut_Text[3]);
+ FreeText(u->ut_Text[4]);
+ FreeText(u->ut_Text[5]);
+ FreeText(u->ut_Text[6]);
+ FreeText(u->ut_Text[7]);
+ FreeSub(i,(SUB *)u);
+ }
+}
+
+void SetUText(ITEM *i, int n, TPTR t)
+{
+ USERTEXT *u=GetUT(i);
+ FreeText(u->ut_Text[n]);
+ u->ut_Text[n]=AllocText(TextOf(t));
+}
+
+TPTR GetUText(ITEM *i, int n)
+{
+ return(GetUT(i)->ut_Text[n]);
+}
+
+INOUTHERE *FindIOH(ITEM *i)
+{
+ return((INOUTHERE *)FindSub(i,KEY_INOUTHERE));
+}
+
+void KillIOH(ITEM *i)
+{
+ SUB *s=FindSub(i,KEY_INOUTHERE);
+ if(s)
+ FreeSub(i,s);
+}
+
+INOUTHERE *GetIOH(ITEM *i)
+{
+ register INOUTHERE *r=(INOUTHERE *)FindSub(i,KEY_INOUTHERE);
+ if(r)
+ return(r);
+ r=(INOUTHERE *)AllocSub(i,KEY_INOUTHERE,sizeof(INOUTHERE));
+ r->io_InMsg=AllocText("arrives");
+ r->io_OutMsg=AllocText("goes");
+ r->io_HereMsg=AllocText("is here");
+ return(r);
+}
+
+void SetInMsg(ITEM *it, char *x)
+{
+ INOUTHERE *i=GetIOH(it);
+ FreeText(i->io_InMsg);
+ i->io_InMsg=AllocText(x);
+}
+
+void SetOutMsg(ITEM *it, char *x)
+{
+ INOUTHERE *i=GetIOH(it);
+ FreeText(i->io_OutMsg);
+ i->io_OutMsg=AllocText(x);
+}
+
+void SetHereMsg(ITEM *it, char *x)
+{
+ INOUTHERE *i=GetIOH(it);
+ FreeText(i->io_HereMsg);
+ i->io_HereMsg=AllocText(x);
+}
+
+char *GetInMsg(ITEM *it)
+{
+ INOUTHERE *i=FindIOH(it);
+ if(i)
+ return(TextOf(i->io_InMsg));
+ else
+ return("arrives");
+}
+
+char *GetOutMsg(ITEM *it)
+{
+ INOUTHERE *i=FindIOH(it);
+ if(i)
+ return(TextOf(i->io_OutMsg));
+ else
+ return("goes");
+}
+
+char *GetHereMsg(ITEM *it)
+{
+ INOUTHERE *i=FindIOH(it);
+ if(i)
+ return(TextOf(i->io_HereMsg));
+ else
+ return("is here");
+}
+
diff --git a/SysSupport.c b/SysSupport.c
new file mode 100644
index 0000000..52f332a
--- /dev/null
+++ b/SysSupport.c
@@ -0,0 +1,904 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+#include "User.h"
+
+extern USER UserList[];
+
+Module "System Support";
+Version "1.17";
+Author "Alan Cox";
+
+/*
+ * Useful routines we use a lot, these use the low level facilities to
+ * provide handy facilities we use a lot, and to save the programmer
+ * going potty....
+ *
+ * 1.00 PlayerOf,RoomOf,ObjectOf SetName SendItem and basics added
+ * 1.01 RemovePlayer,ExitPlayer extracted from CommandDriver
+ * 1.02 Added DoesAction and Broadcast type drivers
+ * 1.03 Added Exit Support Code
+ * 1.04 Drivers for Prompt and Edit packets
+ * 1.05 Fixed Carry when Quit - Items now dropped
+ * 1.06 Understands BOSS1/2 defines
+ * 1.07 Added BACKTRACK and UserOf
+ * 1.08 Added Gfx Driver support
+ * 1.09 Added SNOOP support
+ * 1.10 IsDarkFor implemented and moved to DarkLight.c
+ * 1.11 #<id> support added
+ * 1.12 Added register optimisations and short array references
+ * 1.13 Added Setin Setout Sethere
+ * 1.14 Clear Item1/Item2/Me correctly on player exit (still wrong on stacked cases)
+ * 1.15 Support for ACKnowledge on clear.
+ * Protected CNameOf from crashes on long names (returns lowercase)
+ * 1.16 RemoveUser doesn't remove blank names
+ * 1.17 Strict ANSIfication
+ */
+
+PLAYER *PlayerOf(x) /* Return player pointer of item (or NULL) */
+ITEM *x;
+{
+ return((PLAYER *)FindSub(x,KEY_PLAYER));
+}
+
+OBJECT *ObjectOf(x) /* Guess ... */
+ITEM *x;
+{
+ return((OBJECT *)FindSub(x,KEY_OBJECT));
+}
+
+ROOM *RoomOf(x) /* Keep guessing */
+ITEM *x;
+{
+ return((ROOM *)FindSub(x,KEY_ROOM));
+}
+
+USERFLAG *UserFlagOf(x) /* Fun this */
+ITEM *x;
+{
+ return((USERFLAG *)FindSub(x,KEY_USERFLAG));
+}
+
+USERFLAG *UserFlag2Of(x)
+ITEM *x;
+{
+ return((USERFLAG *)FindSub(x,KEY_USERFLAG2));
+}
+
+CONTAINER *ContainerOf(x) /* Dum de dum */
+ITEM *x;
+{
+ return((CONTAINER *)FindSub(x,KEY_CONTAINER));
+}
+
+int UserOf(x) /* DIFFERENT (STOP!!!) - returns an integer
+ holding player number -1 if not a user */
+ITEM *x;
+{
+ register PLAYER *p=PlayerOf(x);
+ if(p==NULL)
+ return(-1);
+ return(p->pl_UserKey);
+}
+
+int IsUser(x) /* Tests for all of the above */
+ITEM *x;
+{
+ return(UserOf(x)!=-1);
+}
+
+int IsRoom(i)
+ITEM *i;
+{
+ return(RoomOf(i)!=NULL);
+}
+
+int IsPlayer(i)
+ITEM *i;
+{
+ return(PlayerOf(i)!=NULL);
+}
+
+int IsObject(i)
+ITEM *i;
+{
+ return(ObjectOf(i)!=NULL);
+}
+
+/*
+ * This low level text driver is used to send SNOOP data. You shouldn't
+ * need to touch this bit
+ */
+
+void SendItemDirect(i,x)
+ITEM *i;
+char *x;
+{
+ register char *y=x;
+ short u;
+ PORT *pr;
+ register char v;
+ register PLAYER *p=PlayerOf(i);
+ if(p==NULL)
+ return;
+ if(p->pl_UserKey==-1)
+ return;
+ u=p->pl_UserKey;
+ pr=UserList[u].us_Port;
+ while(strlen(y)>510)
+ {
+ v=y[510];
+ y[510]=0;
+ SendTPacket(pr,PACKET_SNOOPTEXT,y);
+ y[510]=v;
+ y+=510;
+ }
+ SendTPacket(pr,PACKET_SNOOPTEXT,y);
+}
+
+/*
+ * Send a message to an item (VarArgs)
+ *
+ */
+void SendItem(x,a,b,c,d,e,f)
+ITEM *x;
+char *a,*b,*c,*d,*e,*f;
+{
+ register PLAYER *p=PlayerOf(x);
+ if(p==NULL) /* Dont send to non players */
+ {
+ SendUser(-1,a,b,c,d,e,f);
+ goto l1;
+ }
+ SendUser(p->pl_UserKey,a,b,c,d,e,f); /* Send message */
+l1: SnoopCheckString(x,UserLastLine); /* Check snooping */
+}
+
+int IsCalled(i,s) /* Check item name against string */
+ITEM *i;
+char *s;
+{
+ if(stricmp(TextOf(i->it_Name),s)==0)
+ return(1);
+ return(0);
+}
+
+void SetName(i,s) /* Change the name of an item. This is how all text works */
+ /* YOU MUST FREE the old text before creating the new */
+register ITEM *i;
+char *s;
+{
+ FreeText(i->it_Name);
+ i->it_Name=AllocText(s);
+}
+
+int ArchWizard(i) /* Check for debugging persona */
+register ITEM *i;
+{
+ if(IsCalled(i,"Anarchy"))
+ return(1);
+ if(IsCalled(i,"Debugiit"))
+ return(1);
+ if(IsCalled(i,BOSS1))
+ return(1);
+ if(IsCalled(i,BOSS2))
+ return(1);
+ if(IsCalled(i,BOSS3))
+ return(1);
+ if(IsCalled(i,BOSS4))
+ return(1);
+ if(IsCalled(i,BOSS5))
+ return(1);
+ return(0);
+}
+
+char *NameOf(x) /* Return the name of an item */
+ITEM *x;
+{
+ return(TextOf(x->it_Name));
+}
+
+char *CNameOf(x) /* Return the name of an item with 1st letter capital
+ size limit of 128 bytes */
+ITEM *x;
+{
+ static char bf[128];
+ if(strlen(NameOf(x))>127)
+ return(NameOf(x));
+ strcpy(bf,NameOf(x));
+ if(*bf)
+ {
+ if(islower(*bf))
+ *bf=toupper(*bf);
+ }
+ return(bf);
+}
+
+short LevelOf(x) /* Return level of user */
+ITEM *x;
+{
+ register PLAYER *p=PlayerOf(x);
+ if(p==NULL)
+ return(0);
+ if((ArchWizard(x))&&(p->pl_Level<10000))
+ return(10000);
+ return(p->pl_Level);
+}
+
+void Place(x,y) /* Place item X at Y, doing all links/unlinks needed */
+register ITEM *x,*y;
+{
+ if(IsObject(x))
+ ObjectOf(x)->ob_Flags&=~OB_WORN; /* Clear worn when move */
+ if(!O_FREE(x))
+ UnlinkItem(x);
+ LinkItem(x,y);
+}
+
+void XPlace(x,y) /* Place item X at Y, doing all links/unlinks needed */
+register ITEM *x,*y; /* But only doing a temporary movement while thinking */
+{
+ if(!O_FREE(x))
+ UnlinkItem(x);
+ LinkItem(x,y);
+}
+
+/*
+ * Remove a user from the game system.
+ *
+ */
+
+void RemoveUser(u)
+unsigned int u;
+{
+ extern ITEM *Item1,*Item2;
+ register ITEM *i;
+ register ITEM *j;
+ SendUser(-2, "");
+ if(UserList[(unsigned short)u].us_Item!=NULL)
+ {
+ i=O_CHILDREN(UserList[(unsigned short)u].us_Item);
+ while(i) /* Drop all items */
+ {
+ j=O_NEXT(i); /* Before Move! - NEXT will change otherwise */
+ Place(i,O_PARENT(UserList[(unsigned short)u].us_Item));
+ i=j;
+ }
+#ifdef ATTACH
+ if(UserList[u].us_RealPerson&&UserList[u].us_Port!=NULL)
+ {
+ Act_UnAlias();
+ return;
+ }
+#endif
+ if(UserList[u].us_Port!=NULL)
+ SendUser(-2, "");
+ i=UserList[(unsigned short)u].us_Item;
+ UnUserFlag(i); /* Remove properties */
+ UnlinkItem(i);
+ UnlockItem(i);
+ KillEventQueue(i);
+ UnPlayer(i);
+ i->it_Perception=-1; /* Delayed Expunge in case */
+ StopAllSnoops(i);
+ StopSnoopsOn(i);
+ KillIOH(i);
+ UnUserText(i);
+ if(Debugger==i)
+ Debugger=NULL;
+ if(Me()==i)
+ SetMe(NULL);
+ if(Item1==i)
+ Item1=NULL;
+ if(Item2==i)
+ Item2=NULL;
+ FreeItem(i); /* Remove it all */
+ }
+ UserList[(unsigned short)u].us_Item=NULL;
+ if(*UserList[u].us_Name)
+ FreeWord(UserList[(unsigned short)u].us_Name,WD_NOUN);
+ strcpy(UserList[(unsigned short)u].us_Name,"");
+ if(UserList[(unsigned short)u].us_Port!=NULL)
+ CloseMPort(UserList[(unsigned short)u].us_Port); /* Bye bye */
+ UserList[u].us_Port=NULL; /* Port now free */
+}
+
+void ExitUser(u) /* Kicks user back to login */
+unsigned int u;
+{
+ extern ITEM *Item1,*Item2;
+ register ITEM *i=O_CHILDREN(UserList[(unsigned short)u].us_Item);
+ register ITEM *j;
+ while(i)
+ {
+ j=O_NEXT(i); /* Before Move! - NEXT will change otherwise */
+ Place(i,O_PARENT(UserList[(unsigned short)u].us_Item));
+ i=j;
+ }
+#ifdef ATTACH
+ if(UserList[u].us_RealPerson)
+ {
+ PlayerOf(UserList[u].us_Item)->pl_UserKey=-1;
+ UnlockItem(UserList[u].us_Item);
+ UserList[u].us_Item=UserList[u].us_RealPerson;
+ }
+#endif
+ i=UserList[(short)u].us_Item;
+ UnUserFlag(i);
+ UnlinkItem(i);
+ UnlockItem(i);
+ KillEventQueue(i);
+ UnPlayer(i);
+ StopAllSnoops(i);
+ StopSnoopsOn(i);
+ KillIOH(i);
+ UnUserText(i);
+ if(Debugger==i)
+ Debugger=NULL;
+ if(Me()==i)
+ SetMe(NULL);
+ if(Item1==i)
+ Item1=NULL;
+ if(Item2==i)
+ Item2=NULL;
+ i->it_Perception=-1; /* Delayed Expunge */
+ FreeItem(i);
+ UserList[(unsigned short)u].us_Item=NULL;
+ FreeWord(UserList[(unsigned short)u].us_Name,WD_NOUN);
+ UserList[(unsigned short)u].us_State=AWAIT_NAME;
+}
+
+int CountUsers() /* Count number of users on system */
+{
+ register short ct=0;
+ register short c2=0;
+ while(ct<MAXUSER)
+ {
+ if(UserList[ct].us_Port)
+ c2++;
+ ct++;
+ }
+ return((int)c2);
+}
+
+int IsBlind(i) /* Basic checks */
+ITEM *i;
+{
+ register PLAYER *p=PlayerOf(i);
+ if(p==NULL)
+ return(0);
+ if(p->pl_Flags&PL_BLIND)
+ return(1);
+ return(0);
+}
+
+int IsDeaf(i)
+ITEM *i;
+{
+ register PLAYER *p=PlayerOf(i);
+ if(p==NULL)
+ return(0);
+ if(p->pl_Flags&PL_DEAF)
+ return(1);
+ return(0);
+}
+
+
+void ByeBye(i,m) /* Clear a user with a message */
+ITEM *i;
+char *m;
+{
+ if(UserOf(i)==-1)
+ return;
+ UserList[UserOf(i)].us_State=AWAIT_ACK;
+ SendTPacket(UserList[UserOf(i)].us_Port,PACKET_CLEAR,m);
+}
+
+
+static int AnyMore(u,i)
+ITEM *u;
+ITEM *i;
+{
+l1: if(!O_NEXT(i))
+ return(0);
+ else
+ {
+ if((IsObject(O_NEXT(i)))&&
+ (ObjectOf(O_NEXT(i))->ob_Flags&OB_NOSEECARRY))
+ {
+ i=O_NEXT(i);
+ goto l1;
+ }
+ if(!CanSee(LevelOf(u),O_NEXT(i)))
+ {
+ i=O_NEXT(i);
+ goto l1;
+ }
+ }
+ return(1);
+}
+
+static ITEM *NextFor(u,i)
+ITEM *u;
+ITEM *i;
+{
+l1: if(!O_NEXT(i))
+ return(NULL);
+ else
+ {
+ i=O_NEXT(i);
+ if((IsObject(i))&&
+ (ObjectOf(i)->ob_Flags&OB_NOSEECARRY))
+ {
+ goto l1;
+ }
+ if(!CanSee(LevelOf(u),i))
+ {
+ goto l1;
+ }
+ }
+ return(i);
+}
+
+static void ShowInventory(i,x)
+ITEM *i,*x;
+{
+ short f=0;
+ if(x==NULL)
+ {
+ SendItem(i,".\n");
+ return;
+ }
+ while(x)
+ {
+ if(f)
+ {
+ if(!AnyMore(i,x))
+ SendItem(i," and ");
+ else
+ SendItem(i,",");
+ }
+ if(!((IsObject(x))&&(ObjectOf(x)->ob_Flags&OB_NOSEECARRY)))
+ {
+ if(!f)
+ SendItem(i," carrying ");
+ SendItem(i,NameOf(x));
+ f=1;
+ }
+ if(!AnyMore(i,x))
+ {
+ SendItem(i,".\n");
+ return;
+ }
+ x=NextFor(i,x);
+ }
+}
+
+void DescribeItem(i,x) /* Describe an item (AberMUD style) */
+ITEM *i;
+ITEM *x;
+{
+ OBJECT *o=ObjectOf(x);
+ PLAYER *p=PlayerOf(x);
+ if(CanSee(LevelOf(i),x)==0)
+ return;
+ if(o)
+ {
+ if(o->ob_Flags&OB_FLANNEL) /* Not flannels */
+ return;
+ SendItem(i,"%s\n",TextOf(o->ob_Text[O_STATE(x)]));
+ if(UserOf(i)>=0)
+ SetItData((short)UserOf(i),x,x->it_Adjective,x->it_Noun);
+ return;
+ }
+ if(p)
+ {
+ SendItem(i,"%s %s",CNameOf(x),GetHereMsg(x)); /* Players */
+ if(UserOf(i)>=0)
+ SetItData((short)UserOf(i),x,x->it_Adjective,x->it_Noun);
+ ShowInventory(i,O_CHILDREN(x));
+ /* Will do inventory too later */
+ }
+}
+
+void DoesAction(user,flag,msg,p1,p2,p3,p4,p5,p6)
+register ITEM *user;
+int flag; /* 1=Someone 0=Nothing if cant see */
+ /* 2=Nothing if deaf */
+ /* 4=Must Be Present */
+char *msg,*p1,*p2,*p3,*p4,*p5,*p6;
+{
+/*
+ * See the DOESACTION database action documentation
+ */
+ register short ct=0;
+ register ITEM *i;
+ while(ct<MAXUSER) /* For each user */
+ {
+ i=UserList[ct].us_Item;
+ if((i)&&(i!=user)) /* Each but me ... */
+ {
+ if(flag&4) /* Must be present */
+ {
+ if(O_PARENT(i)!=O_PARENT(user))
+ goto ne;
+ }
+ if(IsDeaf(i)&&(flag&2)) /* Must be able to here */
+ goto ne;
+ if((IsBlind(i))||(CanSee(LevelOf(i),user)==0))
+ { /* Cant see */
+ if((flag&1)==0)
+ goto ne; /* No one */
+ SendItem(i,"Someone "); /* Someone */
+ SendItem(i,msg,p1,p2,p3,p4,p5,p6);
+ if(!strchr(msg,'\n'))
+ SendItem(i,"\n");
+ goto ne;
+ }
+ SendItem(i,"%s ",CNameOf(user));
+ SendItem(i,msg,p1,p2,p3,p4,p5,p6); /* Send message */
+ if(UserOf(i)>=0)
+ SetItData((short)UserOf(i),
+ user,user->it_Adjective,user->it_Noun);
+ if(!strchr(msg,'\n'))
+ SendItem(i,"\n");
+ }
+ne: ct++;
+ }
+}
+
+void DoesTo(user,flag,thing,msg,p1,p2,p3,p4,p5,p6)
+register ITEM *user;
+int flag;
+ITEM *thing;
+/* 1=Someone 0=Nothing if cant see */
+/* 2=Nothing if deaf */
+/* 4=Must Be Present */
+/* 8=Aware if target */
+char *msg,*p1,*p2,*p3,*p4,*p5,*p6;
+{
+/*
+ * See database Documentation here
+ */
+ register short ct=0;
+ register ITEM *i;
+ while(ct<MAXUSER)
+ {
+ i=UserList[ct].us_Item;
+ if((i)&&(i!=user))
+ {
+ if(flag&4)
+ {
+ if(O_PARENT(i)!=O_PARENT(user))
+ goto ne;
+ }
+ if(thing==i&&(flag&8))
+ goto uncs;
+ if(IsDeaf(i)&&(flag&2))
+ goto ne;
+ if((IsBlind(i))||((CanSee(LevelOf(i),user)==0)&&
+ (CanSee(LevelOf(i),thing)==0)))
+ {
+ if(flag&1)
+ goto ne;
+ }
+uncs: if((IsBlind(i))||(CanSee(LevelOf(i),user)==0))
+ {
+ if(IsPlayer(user))
+ SendItem(i,"Someone ");
+ else
+ SendItem(i,"Something ");
+ SendItem(i,msg,p1,p2,p3,p4,p5,p6);
+ goto it1;
+ }
+ SendItem(i,"%s ",CNameOf(user));
+ if(UserOf(i)>=0)
+ SetItData((short)UserOf(i),
+ user,user->it_Adjective,user->it_Noun);
+ SendItem(i,msg,p1,p2,p3,p4,p5,p6);
+it1: if(CanSee(LevelOf(i),thing)==0||IsBlind(i))
+ {
+ if(IsPlayer(thing))
+ SendItem(i," someone.\n");
+ else
+ SendItem(i," something.\n");
+ }
+ else
+ {
+ if(UserOf(i)>=0)
+ SetItData((short)UserOf(i),
+ thing,thing->it_Adjective,thing->it_Noun);
+ SendItem(i," %s.\n",NameOf(thing));
+ }
+ }
+ne: ct++;
+ }
+}
+
+void DoesToPlayer(user,flag,thing,msg,p1,p2,p3,p4,p5,p6)
+register ITEM *user;
+int flag;
+ITEM *thing;
+/* 1=Someone 0=Nothing if cant see */
+/* 2=Nothing if deaf */
+/* 4=Must Be Present */
+/* 8=Always if target */
+char *msg,*p1,*p2,*p3,*p4,*p5,*p6;
+{
+ register int ct=0;
+ register ITEM *i;
+ while(ct<MAXUSER)
+ {
+ i=UserList[ct].us_Item;
+ if((i)&&(i!=user))
+ {
+ if(flag&4)
+ {
+ if(O_PARENT(i)!=O_PARENT(user))
+ goto ne;
+ }
+ if((flag&8)&&i==thing)
+ goto uncst;
+ if(IsDeaf(i)&&(flag&2))
+ goto ne;
+ if(IsBlind(i)||(CanSee(LevelOf(i),user)==0&&
+ CanSee(LevelOf(i),thing)==0))
+ {
+ if(flag&1)
+ goto ne;
+ }
+uncst: if((IsBlind(i))||(CanSee(LevelOf(i),user)==0))
+ {
+ if(IsPlayer(user))
+ SendItem(i,"Someone ");
+ else
+ SendItem(i,"Something ");
+ SendItem(i,msg,p1,p2,p3,p4,p5,p6);
+ goto it1;
+ }
+ SendItem(i,"%s ",CNameOf(user));
+ if(UserOf(i)>=0)
+ SetItData((short)UserOf(i),
+ user,user->it_Adjective,user->it_Noun);
+ SendItem(i,msg,p1,p2,p3,p4,p5,p6);
+it1: if(thing==i)
+ SendItem(i," you.\n");
+ else
+ {
+ if(CanSee(LevelOf(i),thing)==0||IsBlind(i))
+ {
+ if(IsPlayer(i))
+ SendItem(i," someone.\n");
+ else
+ SendItem(i," something.\n");
+ }
+ else
+ {
+ if(UserOf(i)>=0)
+ SetItData((short)UserOf(i),
+ thing,thing->it_Adjective,thing->it_Noun);
+ SendItem(i," %s.\n",NameOf(thing));
+ }
+ }
+ }
+ne: ct++;
+ }
+}
+
+
+ITEM *FindSomething(i,defloc)
+ITEM *i;
+ITEM *defloc;
+{
+/*
+ * Standard routine for finding item, checking specific room first, then
+ * whole game, used by editing commands.
+ */
+ register ITEM *a;
+ char *r;
+ int refid=0;
+ int ad,no;
+ r=WordPtr;
+ GetParsedWord();
+ if(*WordBuffer=='#') /* #n item */
+ {
+ if(sscanf(WordBuffer,"#%d",&refid)==0)
+ return(NULL);
+ }
+ else
+ WordPtr=r;
+ if(GetThing(&ad,&no)==-1)
+ {
+ return(NULL);
+ }
+ if(refid==0)
+ {
+ a=FindIn(LevelOf(i),defloc,(short)ad,(short)no);
+ if(a)
+ return(a);
+ a=FindMaster(LevelOf(i),(short)ad,(short)no);
+ return(a);
+ }
+ else
+ {
+ a=FindMaster(LevelOf(i),(short)ad,(short)no);
+ while((--refid)&&(a))
+ a=NextMaster(LevelOf(i),a,(short)ad,(short)no);
+ return(a);
+ }
+}
+
+void SetPrompt(i,p) /* Set the prompt a user has on input line */
+ITEM *i;
+char *p;
+{
+ short v=(short)UserOf(i);
+ if(v!=-1)
+ {
+ SendTPacket(UserList[v].us_Port,PACKET_SETPROMPT,p);
+ }
+}
+
+ITEM *ExitOf(i,d) /* Return the exit in direction d. This routine should
+ be in InsAndOuts.c and may move one day */
+ITEM *i;
+unsigned int d;
+{
+ register ITEM *x;
+ GENEXIT *g;
+ g=(GENEXIT *)FindSub(i,KEY_GENEXIT);
+ if(g==NULL)
+ return(NULL);
+ if(d>11)
+ return(NULL);
+ x=g->ge_Dest[(unsigned short)d];
+ if(x==NULL)
+ return(NULL);
+ if(IsRoom(x))
+ return(x);
+ if(O_STATE(x)!=0)
+ return(NULL);
+ return(O_PARENT(x));
+}
+
+ITEM *DoorOf(i,d) /* Find the door in direction - comments as above */
+ITEM *i;
+unsigned int d;
+{
+ register ITEM *x;
+ register GENEXIT *g;
+ g=(GENEXIT *)FindSub(i,KEY_GENEXIT);
+ if(g==NULL)
+ return(NULL);
+ x=g->ge_Dest[(unsigned short)d];
+ if(x==NULL)
+ return(NULL);
+ if(IsRoom(x))
+ return(NULL);
+ return(x);
+}
+
+
+void Broadcast(msg,flag)
+int flag; /* 1=Someone 0=Nothing if cant see */
+ /* 2=Nothing if deaf */
+ /* 4=Must Be Present */
+register char *msg;
+{
+/*
+ * Send a message to 'everyone'
+ */
+ register short ct=0;
+ register ITEM *i;
+ while(ct<MAXUSER)
+ {
+ i=UserList[ct].us_Item;
+ if(i)
+ {
+ if(!(IsDeaf(i)&&(flag&2)))
+ SendItem(i,"%s\n",msg);
+ }
+ ct++;
+ }
+}
+
+void SendEdit(i,x,a1,a2,a3,a4,a5,a6,a7)
+ITEM *i;
+char *x;
+char *a1,*a2,*a3,*a4,*a5,*a6,*a7; /* VARARGS */
+{
+/*
+ * Send a string to an item, to be edited.
+ */
+ static char sbf[512];
+ short u=(short)UserOf(i);
+ if(u==-1)
+ return;
+ sprintf(sbf,x,a1,a2,a3,a4,a5,a6,a7);
+ SendTPacket(UserList[u].us_Port,PACKET_EDIT,sbf);
+}
+
+void TimeOut(u)
+int u;
+{
+/*
+ * Time out controller
+ */
+ char x[MAXNAME+30];
+ if(u<0)
+ return;
+ if(UserList[(unsigned short)u].us_Port!=NULL)
+ CloseMPort(UserList[(unsigned short)u].us_Port); /* Bye bye */
+ UserList[u].us_Port=NULL; /* Port now free */
+ if(*UserList[u].us_Name==0)
+ {
+ return;
+ }
+ sprintf(x,"%s has been timed out.",UserList[u].us_Name);
+ RemoveUser(u);
+ Broadcast(x,0);
+}
+
+void SetUserTitle(i,p,x) /* AberMUD gfx drivers */
+ITEM *i;
+char *p,*x;
+{
+ char a[128];
+ short v=(short)UserOf(i);
+ if(v!=-1)
+ {
+ sprintf(a,p,x);
+ SendTPacket(UserList[v].us_Port,PACKET_SETTITLE,a);
+ }
+}
+
+
+int IsLit(i) /* Check if an item is lit - should be in DarkLight.c */
+ITEM *i;
+{
+ register OBJECT *o=ObjectOf(i);
+ if(!o)
+ return(0);
+ if(o->ob_Flags&OB_LIGHTSOURCE)
+ return(1);
+ if(o->ob_Flags&OB_LIGHT0)
+ return((O_STATE(i)==0));
+ return(0);
+}
+
+int IsUnique(short pe, short a, short n)
+/* True if adj noun refer to unique item (for perception pe) */
+{
+ register ITEM *x=FindMaster(pe,a,n);
+ if(x==NULL)
+ return(1);
+ if(NextMaster(pe,x,a,n))
+ return(0);
+ return(1);
+}
+
+int ItemNumber(short pe, ITEM *i) /* Get number (#n) of an item */
+{
+ register ITEM *j;
+ register short ct=2;
+ j=FindMaster(pe,i->it_Adjective,i->it_Noun);
+ if(j==i)
+ return(1);
+ if(j==NULL)
+ return(-1);
+ while((j=NextMaster(pe,j,i->it_Adjective,i->it_Noun)))
+ {
+ if(i==j)
+ return(ct);
+ ct++;
+ }
+ return(-1);
+}
diff --git a/System.c b/System.c
new file mode 100644
index 0000000..3178aa9
--- /dev/null
+++ b/System.c
@@ -0,0 +1,867 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * System Functions
+ *
+ * 1.00 Original Version
+ * 1.04 Added Pointer Validation Facilities
+ * 1.05 Made Alloc clear the structure allocated
+ * 1.10 Added Memory Statistics On Boot
+ * 1.11 Fixed Link to null bug
+ * 1.12 Added INHERIT to FindSub
+ * 1.13 Added Comments
+ * 1.14 Fixed Texts >32766 times
+ * 1.15 Made it FreeText item names and also free text block when does
+ * a FreeText.
+ * 1.16 Added Register Optimisations
+ * 1.17 75 way hashed text list
+ * 1.18 Added Save/Restore on NextInByClass for DOCLASS nesting
+ * 1.19 Made FindInByClass etc do mask 0 correctly.
+ * 1.20 Added QuickAllocText feature
+ * 1.21 Tidied up Error crash recovery
+ * 1.22 Bug fixes for 5.06
+ * 1.23 Extended Error Logging
+ * 1.24 Fixed SHARE and Save/Load
+ * 1.25 Changed to reduce string load, due to unix malloc overhead
+ * 1.26 Flushes log writes
+ * 1.27 Deleting items now checks for tables and deletes them.
+ * 1.28 Removed pointless uid logging
+ * 1.29 Cleaned up for strict ANSI C
+ */
+
+#include "System.h"
+#include "User.h"
+
+extern USER UserList[];
+
+Module "System";
+Version "1.29";
+Author "----*(A)";
+
+
+/*
+ * Display An Error Message, called via the Error() macro
+ */
+
+void ErrFunc(er,mod,ver,line,file)
+char *er,*mod,*ver,*file;
+int line;
+{
+ short ct=0;
+ static int err_yes=0;
+ printf("MODULE: %s VERSION: %s\n",mod,ver);
+ printf("FILE: %s LINE: %d\n",file,line);
+ printf("ERROR LOGGED WAS\n");
+ printf("%s.\n",er);
+ Log("MODULE: %s VERSION: %s",mod,ver);
+ Log("FILE: %s LINE: %d",file,line);
+ Log("ERROR LOGGED WAS");
+ Log("%s",er);
+ if(err_yes==0&&post_boot)
+ {
+ err_yes++;
+ printf("\n\nAttempting to rescue universe\n");
+ while(ct<MAXUSER)
+ {
+ if(UserList[ct].us_Item)
+ ExitUser(ct);
+ ct++;
+ }
+ DisintegrateAll();
+ DisintegrateAll();
+ if(SaveSystem("gonebang.uni")==0)
+ {
+printf("\n\n-----------------------------------------------\n\n");
+printf("System successfully saved as 'gonebang.uni'\n");
+printf("CAUTION: Ensure this rescued game works correctly before replacing the \
+older\nversions with it.\n");
+ }
+ else
+ printf("Attempt to save failed.\n");
+ }
+ else
+ printf("Cannot rescue game.\n");
+ exit(1);
+}
+
+/*
+ * Log an error to the log file
+ */
+
+void Log(char *fmt, ...)
+{
+ char *x;
+ long v;
+ va_list va;
+ static FILE *file=NULL;
+ if(file==NULL) file=fopen(LOG_FILE,"a");
+ if(file==NULL)
+ return; /* Try to open log file */
+
+ va_start(va, fmt);
+ time(&v);
+ x=ctime(&v);
+ *strchr(x,'\n')=0;
+ fprintf(file,"%s:",x);
+ vfprintf(file, fmt, va); /* Save error message */
+ fprintf(file,"\n"); /* Return to tidy it */
+ fflush(file);
+ va_end(va);
+}
+
+/*
+ * Allocate a block of memory via the Allocate macro. The memory is
+ * cleared to 0 and if close to no free memory a warning is displayed
+ */
+
+char *AllocFunc(int x, char *mod, char *ver, int line, char *file)
+{
+ register char *a;
+ register int n=0;
+ a=malloc(x); /* Request Memory */
+ if(a==NULL)
+ {
+ ErrFunc("Out Of Memory",mod,ver,line,file); /* Failed */
+ }
+ while(n<x)
+ a[n++]=0; /* Clear Memory */
+ return(a); /* Return block */
+}
+
+
+TPTR AllocText(char *x)
+{
+ return((TPTR)strdup(x));
+}
+
+TPTR AllocComment(char *x)
+{
+ return((TPTR)strdup(x));
+}
+
+TPTR QuickAllocText(char *x)
+{
+ return((TPTR)strdup(x));
+}
+
+
+long TextNumber(register TPTR t)
+{
+ Error("TextNumber: Text not listed");
+ return(0L); /* Compiler happiness */
+}
+
+/*
+ * Return a string pointer given a TXT pointer
+ */
+
+char *TextOf(TPTR x)
+{
+ return((char *)x);
+}
+
+void FreeText(TPTR x)
+{
+ free((char *)x);
+}
+
+
+void FreeComment(TPTR x)
+{
+ free((char *)x);
+}
+
+/*
+ * Fundamental Item Controllers
+ *
+ * The item list works on a similar structure to the texts, a one way linked
+ * list. However to handle containment the system is far more complex in its
+ * potential twinings. Each item has a pointer to its parent (container),
+ * a pointer to the first thing in a linked list it contains, and a pointer
+ * to the next item in the linked list of items contained by its parent.
+ */
+
+/*
+ * Disconnect An Item From Any Parent Objects
+ */
+
+int UnlinkItem(register ITEM *x)
+{
+ register ITEM *a;
+#ifdef CHECK_ITEM
+ CheckItem(x);
+#endif
+ if(O_FREE(x)) /* Already disconnected */
+ return(0);
+ if(O_CHILDREN(O_PARENT(x))==x) /* First item special case */
+ {
+ O_CHILDREN(O_PARENT(x))=O_NEXT(x); /* Move pointer on */
+ O_PARENT(x)=NULL; /* Clear our pointers */
+ O_NEXT(x)=NULL;
+ return(0);
+ }
+ a=O_CHILDREN(O_PARENT(x));
+ if(a==NULL) /* More cockup checks */
+ Error("UnlinkItem: Parent Empty");
+ while(O_NEXT(a))
+ {
+ if(O_NEXT(a)==x) /* Unlink from list */
+ {
+ O_NEXT(a)=O_NEXT(x);
+ O_PARENT(x)=NULL;
+ O_NEXT(x)=NULL;
+ return(0);
+ }
+ a=O_NEXT(a);
+ }
+ Error("UnlinkItem: Parent Does Not Contain Child");
+}
+
+/*
+ * Place an UnLinked item into a container. Note an UNLINKED item.
+ */
+
+int LinkItem(ITEM *a, ITEM *b)
+{
+#ifdef CHECK_ITEM
+ CheckItem(a);
+ if(b)
+ CheckItem(b);
+#endif
+ if(!O_FREE(a))
+ return(-1); /* item not free yet */
+ O_PARENT(a)=b;
+ if(b)
+ {
+ O_NEXT(a)=O_CHILDREN(b); /* Hook into chain */
+ O_CHILDREN(b)=a;
+ }
+ else
+ O_NEXT(a)=NULL; /* Moving into nothingness */
+ return(0);
+}
+
+
+/*
+ * ITEM CONTROLLERS
+ */
+
+ITEM *ItemList=NULL; /* Global list of items, see above */
+
+/*
+ * Create an item, setting up its name adj and noun fields. We have to set
+ * adj and noun so you can refer to it. If you set up an item with no
+ * adjective and noun, you have a problem!
+ */
+
+ITEM *CreateItem(char *name, int ad, int no)
+{
+ register ITEM *a=Allocate(ITEM);/* Memory for the item */
+ O_PARENT(a)=NULL; /* Starts in the void */
+ O_NEXT(a)=NULL; /* Connected to nothing */
+ O_CHILDREN(a)=NULL; /* No children either */
+ O_PROPERTIES(a)=NULL; /* No properties */
+ O_ADJECTIVE(a)=ad; /* Adjective as asked */
+ O_NOUN(a)=no; /* Noun as was asked */
+ a->it_Users=0; /* Not yet locked into */
+ O_STATE(a)=0; /* Set its state to zero*/
+ a->it_MasterNext=ItemList; /* Link into lists */
+ ItemList=a;
+ a->it_ActorTable=0; /* Start with tables 0 */
+ a->it_ActionTable=0;
+ a->it_Class=0; /* Clear class maskings */
+ a->it_Perception=0; /* Generally visiblish */
+ a->it_Name=AllocText(name); /* allocate the text string */
+ return(a);
+}
+
+/*
+ * Delete an object, very similar in many ways to freeing a text but with
+ * more requirements: Item must be EMPTY, IN VOID, UNLOCKED, and with NO
+ * properties
+ */
+
+int FreeItem(register ITEM *x)
+{
+ register ITEM *a;
+#ifdef CHECK_ITEM
+ CheckItem(x);
+#endif
+ /* Free tables first of all */
+ if(x->it_ObjectTable!=NULL)
+ {
+ DeleteTable(x->it_ObjectTable);
+ FreeTableHeader(x->it_ObjectTable);
+ x->it_ObjectTable=NULL;
+ }
+ if(x->it_SubjectTable!=NULL)
+ {
+ DeleteTable(x->it_SubjectTable);
+ FreeTableHeader(x->it_SubjectTable);
+ x->it_SubjectTable=NULL;
+ }
+ if(x->it_DaemonTable!=NULL)
+ {
+ DeleteTable(x->it_DaemonTable);
+ FreeTableHeader(x->it_DaemonTable);
+ x->it_DaemonTable=NULL;
+ }
+ /* We must delete tables first - we may have a lock into ourself */
+ if(x->it_Users) /* Still in use */
+ return(-1);
+ if(!O_EMPTY(x)) /* Not empty */
+ return(-2);
+ if(O_PROPERTIES(x))
+ return(-3); /* Delete ALL Props First */
+ if(!O_FREE(x))
+ return(-4); /* Still linked */
+ if(x->it_Superclass) /* Dump superclasses */
+ {
+ UnlockItem(x->it_Superclass);
+ }
+ if(ItemList==x)
+ {
+ ItemList=x->it_MasterNext; /* Now delete the entry */
+ FreeText(x->it_Name);
+ free((char *)x);
+ return(0);
+ }
+ a=ItemList;
+ if(!a)
+ Error("FreeItem: Empty Item List");
+ while(a->it_MasterNext)
+ {
+ if(a->it_MasterNext==x)
+ {
+ a->it_MasterNext=x->it_MasterNext;
+ FreeText(x->it_Name);
+ free((char *)x);
+ return(0);
+ }
+ a=a->it_MasterNext;
+ }
+ Error("FreeItem: Invalid Item Handle");
+}
+
+void LockItem(ITEM *x) /* Mark an item 'in use' */
+{
+#ifdef CHECK_ITEM
+ CheckItem(x);
+#endif
+ x->it_Users++;
+}
+
+void UnlockItem(ITEM *x) /* Mark an item 'out of use' */
+{
+#ifdef CHECK_ITEM
+ CheckItem(x);
+#endif
+ x->it_Users--;
+ if((x->it_Users==0)&&(x->it_Perception==-1)) /* Pending deletion */
+ {
+ FreeItem(x);
+ return;
+ }
+ if(x->it_Users<0)
+ {
+ Log("Can't unlock %s",NameOf(x));
+ Error("Unlock: Item already free");
+ }
+}
+
+void SetState(ITEM *x, short v)
+{
+#ifdef CHECK_ITEM
+ CheckItem(x);
+#endif
+ x->it_State=v;
+}
+
+/*
+ * Change the vocabulary on an item NEVER set to -1,-1
+ */
+
+void SetVocab(ITEM *item, short ad, short no)
+{
+#ifdef CHECK_ITEM
+ CheckItem(item);
+#endif
+ O_NOUN(item)=no;
+ O_ADJECTIVE(item)=ad;
+}
+
+/*
+ * Test for a word matching
+ */
+
+int WordMatch(ITEM *i, short a, short n)
+{
+#ifdef CHECK_ITEM
+/* CheckItem(i); */ /* Removed because it made testing TOO slow */
+#endif
+ if((a==-1)&&(n==O_NOUN(i)))
+ return(1);
+ if((a==O_ADJECTIVE(i))&&(n==O_NOUN(i)))
+ return(1);
+ return(0);
+}
+
+/*
+ * Test if item is visible
+ */
+
+int CanSee(short pe, ITEM *it)
+{
+#ifdef CHECK_ITEM
+/* CheckItem(it); */ /* Removed because it made testing too slow */
+#endif
+ if(it->it_Perception>pe)
+ return(0);
+ return(1);
+}
+
+/*
+ * Find a matching item, anywhere in the game
+ */
+
+ITEM *FindMaster(short pe, short a, short n)
+{
+ register ITEM *i=ItemList; /* Walk the entire list of items */
+ while(i)
+ {
+ if((WordMatch(i,a,n))&&(CanSee(pe,i)))
+ return(i);
+ i=i->it_MasterNext;
+ }
+ return(NULL);
+}
+
+/*
+ * Find the next item in the game matching the words
+ */
+
+ITEM *NextMaster(short pe,register ITEM *i, short a, short n)
+{
+#ifdef CHECK_ITEM
+ CheckItem(i);
+#endif
+ i=i->it_MasterNext;
+ while(i)
+ {
+ if((WordMatch(i,a,n))&&(CanSee(pe,i)))
+ return(i);
+ i=i->it_MasterNext;
+ }
+ return(NULL);
+}
+
+/*
+ * Find the first item in container matching the words
+ */
+
+ITEM *FindIn(short pe, ITEM *i, short a, short n)
+{
+ if(i==NULL)
+ return(NULL);
+#ifdef CHECK_ITEM
+ CheckItem(i);
+#endif
+ i=O_CHILDREN(i);
+ while(i)
+ {
+ if((WordMatch(i,a,n))&&(CanSee(pe,i)))
+ return(i);
+ i=O_NEXT(i);
+ }
+ return(NULL);
+}
+
+/*
+ * Find the next item matching the words
+ */
+
+ITEM *NextIn(short pe, register ITEM *i, short a, short n)
+{
+#ifdef CHECK_ITEM
+ CheckItem(i);
+#endif
+ i=O_NEXT(i);
+ while(i)
+ {
+ if((WordMatch(i,a,n))&&(CanSee(pe,i)))
+ return(i);
+ i=O_NEXT(i);
+ }
+ return(NULL);
+}
+
+/*
+ * Properties: The substructure handlers.
+ *
+ * Every substructure has a SUB entry at the start of the data (see
+ * system.h), this is all that is used by these routines
+ */
+
+/*
+ * Find the first substructure of type 'key' in item.
+ */
+
+SUB *FindSub(ITEM *item, register short key)
+{
+ ITEM *b=NULL;
+ register SUB *a=item->it_Properties; /* Start of property list */
+#ifdef CHECK_ITEM
+ CheckItem(item);
+#endif
+ while(a) /* Walk list */
+ {
+ if(a->pr_Key==key)
+ return(a); /* Found it */
+ if(a->pr_Key==KEY_INHERIT)
+ b=((INHERIT *)(a))->in_Master; /* Note inheritance */
+ a=a->pr_Next;
+ }
+ if(!post_boot)
+ return(NULL); /* Don't share while booting */
+ if(b)
+ {
+ a=b->it_Properties; /* Do properties if any inherited */
+ while(a)
+ {
+ if(a->pr_Key==key)
+ return(a);
+ a=a->pr_Next;
+ }
+ }
+ return(NULL);
+}
+
+/*
+ * Find the next substructure of type 'key' in item.
+ * NOTE: This does not walk across two items. Thus an inherited chain
+ * and a non-inherited chain will not both be found. This is a 'feature'
+ */
+
+SUB *NextSub(SUB *sub, register short key)
+{
+ register SUB *a=sub->pr_Next;
+ while(a)
+ {
+ if(a->pr_Key==key)
+ return(a);
+ a=a->pr_Next;
+ }
+ return(NULL);
+}
+
+/*
+ * Allocate a substructure of type 'key' and size 'size', then add it to
+ * ITEM. Note the entry is added first and thus will be found first.
+ *
+ * Both of these routines are almost always used indirectly by other setup
+ * code. (See SubHandler.c mainly)
+ */
+
+SUB *AllocSub(ITEM *item, short key, short size)
+{
+ SUB *a=(SUB *)malloc(size);
+#ifdef CHECK_ITEM
+ CheckItem(item);
+#endif
+ if(a==NULL)
+ Error("Out Of Memory");
+ a->pr_Next=item->it_Properties; /* Link into list */
+ item->it_Properties=a;
+ a->pr_Key=key;
+ return(a);
+}
+
+/*
+ * Free a substructure from an item, pretty much like freeing text
+ */
+
+void FreeSub(ITEM *item, register SUB *sub)
+{
+ register SUB *a=item->it_Properties;
+#ifdef CHECK_ITEM
+ CheckItem(item);
+#endif
+ if(a==NULL)
+ Error("FreeSub: Item has no properties");
+ if(a==sub)
+ {
+ item->it_Properties=sub->pr_Next;
+ free((char *)sub);
+ return;
+ }
+ while(a->pr_Next)
+ {
+ if(a->pr_Next==sub)
+ {
+ a->pr_Next=sub->pr_Next;
+ free((char *)sub);
+ return;
+ }
+ a=a->pr_Next;
+ }
+ Error("FreeProp: Property not in item given");
+}
+
+/*
+ * Test if item a contains item b to any depth (non recursive)
+ */
+
+int Contains(register ITEM *a, register ITEM *b)
+/* true if a cont b */
+{
+ int ct=32;
+#ifdef CHECK_ITEM
+ CheckItem(a);
+ CheckItem(b);
+#endif
+ while(O_PARENT(b)&& ct-- )
+ {
+ if(O_PARENT(b)==a)
+ return(1);
+ b=O_PARENT(b); /* Go up a level */
+ }
+ return(0);
+}
+
+/*
+ * Find the first item contained in i matching words
+ */
+
+ITEM *FindContains(short pe, ITEM *i, short a, short n)
+{
+ register ITEM *b=FindMaster(pe,a,n);
+#ifdef CHECK_ITEM
+ CheckItem(i);
+#endif
+ while(b)
+ {
+ if(Contains(i,b))
+ return(b);
+ b=NextMaster(pe,b,a,n);
+ }
+ return(NULL);
+}
+
+/*
+ * Find the next item contained in i, after j
+ */
+
+ITEM *NextContains(short pe, ITEM *i, ITEM *j, short a, short n)
+{
+ register ITEM *b=NextMaster(pe,j,a,n);
+#ifdef CHECK_ITEM
+ CheckItem(i);
+ CheckItem(j);
+#endif
+ while(b)
+ {
+ if(Contains(i,b))
+ return(b);
+ b=NextMaster(pe,b,a,n);
+ }
+ return(NULL);
+}
+
+/*
+ * Return the position of an item in the master lists
+ */
+
+long MasterNumber(ITEM *x)
+{
+ register ITEM *a=ItemList;
+ register int b=0;
+ while(a)
+ {
+ if(a==x)
+ return(b);
+ b++;
+ a=a->it_MasterNext;
+ }
+ Error("Invalid Item Handle");
+}
+
+/*
+ * Test if an item pointer is valid
+ */
+
+int ValidItem(ITEM *x)
+{
+ register ITEM *a=ItemList;
+ while(a)
+ {
+ if(a==x)
+ return(1);
+ a=a->it_MasterNext;
+ }
+ return(0);
+}
+
+/*
+ * Count the number of items in the master lists.
+ */
+
+long CountItems(void)
+{
+ register ITEM *a=ItemList;
+ register long b=0;
+ while(a)
+ {
+ b++;
+ a=a->it_MasterNext;
+ }
+ return(b);
+}
+
+static ITEM *Lfnd_NextPtr=NULL; /* We have to cache one here */
+
+/*
+ * Remember the next pointer, used by tables for context changing
+ */
+
+ITEM *GetNextPointer(void)
+{
+ return(Lfnd_NextPtr);
+}
+
+/*
+ * Restore the pointer
+ */
+
+void SetNextPointer(ITEM *x)
+{
+ Lfnd_NextPtr=x;
+}
+
+/*
+ * Find an item in an item, by classmask not by words
+ */
+
+ITEM *FindInByClass(short per, register ITEM *i, register short m)
+{
+ i=O_CHILDREN(i);
+ while(i)
+ {
+ if((i->it_Class&m)&&(CanSee(per,i)))
+ {
+ Lfnd_NextPtr=O_NEXT(i);
+ return(i);
+ }
+ if((m==0)&&(CanSee(per,i)))
+ {
+ Lfnd_NextPtr=O_NEXT(i);
+ return(i);
+ }
+ i=O_NEXT(i);
+ }
+ return(NULL);
+}
+
+/*
+ * Find the next item in a container by classmask
+ */
+
+ITEM *NextInByClass(short per, register ITEM *i, register short m)
+{
+/*
+ * We don't use item->next, since user may have moved item. We DO NOT define
+ * what happens if the user moves item->next itself. (There must be a better
+ * way to do this, but I can't think of one right now...)
+ */
+ i=Lfnd_NextPtr;
+ while(i)
+ {
+ if((i->it_Class&m)&&(CanSee(per,i)))
+ {
+ Lfnd_NextPtr=O_NEXT(i);
+ return(i);
+ }
+ if((m==0)&&(CanSee(per,i)))
+ {
+ Lfnd_NextPtr=O_NEXT(i);
+ return(i);
+ }
+ i=O_NEXT(i);
+ }
+ return(NULL);
+}
+
+static char *Valt(ITEM *x)
+{
+ if(ValidItem(x))
+ return("");
+ else
+ return("<**INVALID**>");
+}
+
+void LineDump(void)
+{
+ extern ITEM *Item1,*Item2;
+ static short called=0; /* If we fail we skip second time */
+ if(called==1)
+ return;
+ called=1;
+ fprintf(stderr,"Verb %d Adj1 %d Noun1 %d Prep %d Adj2 %d Noun2 %d\
+\n",Verb,Adj1,Noun1,Prep,Adj2,Noun2);
+ fprintf(stderr,"$ME is %lx %s\n",(unsigned long)Me(),Valt(Me()));
+ fprintf(stderr,"$1 is %lx %s\n",(unsigned long)Item1,Valt(Item1));
+ fprintf(stderr,"$2 is %lx %s\n",(unsigned long)Item1,Valt(Item2));
+ fprintf(stderr,"$AC is %lx %s\n",(unsigned long)Actor(),Valt(Actor()));
+ if(CurrentLine)
+ {
+ FPCurrentLine();
+ }
+}
+
+#ifdef CHECK_ITEM
+
+/*
+ * Check an item pointer to trap system errors
+ */
+
+int ICheck(register ITEM *item, int line, char *file)
+{
+ register ITEM *x=ItemList;
+ extern ITEM DummyItem;
+ while(x)
+ {
+ if(x==item)
+ return(1);
+ x=x->it_MasterNext;
+ }
+ if(item==&DummyItem)
+ return(1);
+ fprintf(stderr,"Pointer=%ld!\n", (unsigned long)item);
+ LineDump();
+ ErrFunc("Invalid ITEM *","<VALIDATOR>","1.00",line,file);
+}
+
+#else
+int ICheck(register ITEM *item, int line, char *file){return(1);}
+#endif
+
+#ifdef CHECK_TXT
+
+/*
+ * Check a text pointer to trap system errors
+ */
+
+int TCheck(register TPTR txt, int line, char *file)
+{
+ return(1);
+}
+
+#endif
+
diff --git a/System.h b/System.h
new file mode 100644
index 0000000..3887800
--- /dev/null
+++ b/System.h
@@ -0,0 +1,606 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/******************************************************************************
+ * *
+ * System Include File: Version 5.30 *
+ * *
+ *****************************************************************************/
+/* -------------------------- System Includes ------------------------ */
+
+#include <stdio.h>
+#include <ctype.h>
+#include <time.h>
+#include <stdlib.h>
+#include <string.h>
+#include <setjmp.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+#include "IPC.h"
+#include "Comms.h"
+
+/*
+ * WARNING: The system is set up to run on a compiler which promotes
+ * all arguments: eg lattice C. If you need to change this, you will
+ * have to implement proper varargs and also tidy up some of the
+ * function calls, where the typing is not precise. A simpler approach
+ * is to find a compiler with sizeof(int)==sizeof(long) and then
+ * #define short int, since I don't think any library calls expect shorts.
+ */
+
+#define CPRT "Alan Cox"
+
+/*
+ * These seem dodgy on Lattice 4.01 so we don't use the builtins
+ * The other good bugs to watch include being allowed to return(n)
+ * from a void, which simply loses n
+ */
+
+#ifdef LETTUCE_4
+#ifdef stricmp
+#undef stricmp
+#endif
+#ifdef strcmp
+#undef strcmp
+#endif
+#ifdef memcmp
+#undef memcmp
+#endif
+#endif
+
+/*
+ * GNU C macro bits to keep warnings down
+ */
+
+#ifdef __GNUC__
+#define unused __attribute__((unused))
+#define noreturn __attribute__((noreturn))
+#else
+#define unused
+#define noreturn
+#endif
+
+/*
+ * ---------- Configuration Options ---------
+ */
+
+#define ANSI_C /* Has prototypes */
+/*#define NO_VOID*/ /* Doesn't know 'void' */
+#define LOG_FILE "Creator.log" /* Where to dump logging crud */
+/*#define SECURE*/ /* Disable shell/file stuff */
+#define UNIX
+/*#define AMIGA */
+#define MAXUSER 128 /* Max users at once */
+#define MAXNAME 14 /* Maximum length of players */
+ /* Don't set this >32 */
+#define MAXUSERID 32 /* 8 for U*IX *//* Max space to hold a userid */
+
+/*
+ * If you keep MAXNAME/MAXUSERID 32 even if too large, it will ensure the
+ * user file is compatible with any other machines which do the same
+ */
+
+/*#define PANSY_MODE*/ /* Americans don't like dying.. */
+#define REGISTER /* For irritating users */
+
+#define TCP_PORT 5000
+
+#define USERFILE "UAF" /* Where to find characters */
+
+#define BOSS1 "Arashi" /* Name of priviledged chars */
+#define BOSS2 "Hobbit" /* "" "" "" */
+#define BOSS3 "Debugger" /* "" "" "" */
+#define BOSS4 "Bonzo" /* "" "" "" */
+#define BOSS5 ":Boss" /* "" "" "" */
+
+/*
+ * If you change BOSS1/BOSS2 recompile SysSupport. If you change USERFILE
+ * recompile UserFile.c. If you change any of the MAXxxxx entries recompile
+ * everything which mentions User.h (most of it)
+ * If you change LOG_FILE recompile system.c. To disable Logging on the
+ * Amiga set LOG_FILE to "NIL:" or hack it out of the code. If you want
+ * you can set LOG_FILE to a console window and monitor the log output on
+ * it instead of into a file, or you can set it to go through a PIPE:
+ * device to another program.
+ */
+
+/*
+ * Other Options
+ */
+
+#define CHECK_TXT /* Check all text pointers at low level */
+/* CHECK_TXT is not supported on the unix implementation */
+#define CHECK_ITEM /* Check all item pointers at low level */
+
+/* The two above lower system performance especially on large games -
+ they are meant for system debugging (or paranoid authors). Its a good
+ idea *NOT* to use these on a virtual memory system
+*/
+#undef BOOT_DEBUG /* Startup with Debug set */
+/* For errors prior to character logins - unless is really screws up you
+ * can stick a DEBUG command in the startup and save the db again then
+ * restart - this option is meant for emergencies - I use it always tho
+ * and have a debug 0 at the end of startup - of course if it crashes at the
+ * moment between debug 0 and login I got problems....
+ */
+#define ATTACH /* Include attach function */
+
+
+
+#ifdef NO_VOID
+#define void
+#endif
+
+/* ------------------------ Control Macros -------------------------- */
+
+
+#define Module static char *Mod_Name unused =
+#define Version static char *Ver_Name unused =
+#define Author static char *Aut_Name unused =
+
+#define Error(x) ErrFunc((x),Mod_Name,Ver_Name,__LINE__,__FILE__)
+#define Allocate(x) \
+ (x *)AllocFunc(sizeof(x),Mod_Name,Ver_Name,__LINE__,__FILE__)
+#define CheckItem(x) ICheck((x),__LINE__,__FILE__)
+#define CheckTxt(x) TCheck((x),__LINE__,__FILE__)
+
+/* ----------------- Creator Of Legends Structures ----------------- */
+
+struct Txt
+{
+ char *te_Text; /* The string of text */
+ short te_Users; /* Number of uses - if this goes >32767
+ trouble, so every 32768th is new one! */
+ struct Txt *te_Next; /* Next text */
+};
+
+typedef struct Txt TXT; /* No longer TEXT - clashed with exec/types.h */
+typedef struct Txt * TPTR; /* Text Pointer */
+
+struct WordList
+{
+ char *wd_Text; /* The word text */
+ short wd_Type; /* Its type - see WD_ defs */
+ short wd_Code; /* Code for this word */
+ struct WordList *wd_Next; /* Next Word */
+};
+
+
+typedef struct WordList WLIST;
+
+
+struct Sub /* Substruct Node */
+{
+ struct Sub *pr_Next; /* Next Substructure */
+ short pr_Key; /* Substructure identity key */
+};
+
+typedef struct Sub SUB;
+
+typedef struct Table TABLE; /* Forward reference for items */
+
+struct Item
+{
+ struct Item *it_MasterNext; /* Next Master Entry */
+ struct Item *it_Parent; /* Parent Entry */
+ struct Item *it_Children; /* First item it contains */
+ struct Item *it_Next; /* Next item in this chain*/
+ short it_Noun; /* Noun for the item */
+ short it_Adjective; /* Adjective for it */
+ short it_ActorTable; /* Table for actions by it*/
+ short it_ActionTable; /* Daemon handler for it */
+ short it_Users; /* Number of locks on it */
+ short it_State; /* Item actual state */
+ short it_Class; /* Class bitmask */
+ short it_Perception; /* Level needed to see it */
+ TPTR it_Name; /* Items name string */
+ SUB *it_Properties; /* Substructure chain */
+ struct Item *it_Superclass; /* Superclass for tables */
+/*
+ * New for 5.08 - item bound tables
+ */
+ TABLE *it_ObjectTable;
+ TABLE *it_SubjectTable;
+ TABLE *it_DaemonTable; /* Personal Daemon Table */
+/*
+ * New for 5.30 - item zone
+ */
+ short it_Zone; /* Item 'zone' */
+};
+
+typedef struct Item ITEM;
+
+/*
+ * Useful Item Macros
+ */
+
+#define O_NEXT(o) ((o)->it_Next) /* The next item in room */
+#define O_PARENT(o) ((o)->it_Parent) /* The holder of this item */
+#define O_FREE(o) (O_PARENT(o)==NULL) /* True if item is in void */
+#define O_CHILDREN(o) ((o)->it_Children) /* The first item within */
+#define O_EMPTY(o) (O_CHILDREN(o)==NULL) /* True if item empty */
+#define O_PROPERTIES(o) ((o)->it_Properties) /* First property of item */
+#define O_ADJECTIVE(o) ((o)->it_Adjective) /* Adjective of item */
+#define O_NOUN(o) ((o)->it_Noun) /* Noun of item */
+#define O_STATE(o) ((o)->it_State) /* The state of the item */
+ /* DO NOT USE TO SET */
+#define O_USERS(o) ((o)->it_Users) /* Number of locks on item */
+ /* DO NOT USE TO SET */
+
+/* --------------------------- SubStructs -------------------------- */
+
+struct Sub_Room
+{
+ SUB rm_Sub;
+ TPTR rm_Short; /* Short Text */
+ TPTR rm_Long; /* Long Text */
+ unsigned short rm_Flags;
+};
+
+typedef struct Sub_Room ROOM;
+
+#define RM_DARK 1 /* Room has no light source */
+#define RM_OUTSIDE 2 /* Room is outside (OBSOLETE) */
+#define RM_DEATH 4 /* Room description kills players */
+#define RM_MERGE 8 /* Room should be merged with parent */
+#define RM_JOIN 16 /* Room may be used in a merge */
+#define RM_DROPEMSG 32 /* Drop description if doing a msgexit */
+
+/* PICMASK is obsolete */
+#define RM_PICMASK 0xFFC0 /* Max of 1024 pictures */
+#define GETPICTURE(x) (((x)&RM_PICMASK)>>6)
+
+struct Sub_Object
+{
+ SUB ob_Sub; /* Substructure node */
+ TPTR ob_Text[4]; /* State 0-3 texts */
+/*
+ * Under AGOSII only Text[3] is used. This is compatible databasewise with
+ * a Creator Of Legends database and thus makes testing easier. Of course
+ * run time trashes all the junk anyway
+ */
+ short ob_Size; /* Size (overrides Player size) */
+ short ob_Weight; /* Weight (overrides Player) */
+ short ob_Flags; /* Misc Info */
+};
+
+typedef struct Sub_Object OBJECT;
+
+#define OB_FLANNEL 1 /* Merge text into main description */
+#define OB_NOIT 2 /* Do not affect pronouns */
+#define OB_WORN 4 /* Item is 'worn' */
+#define OB_DESTROYED 8 /* Item is destroyed (OBSOLETE ) */
+#define OB_CANGET 16 /* Player can get the item (used by GET)*/
+#define OB_CANWEAR 32 /* Player can wear item (used by WEAR) */
+#define OB_LIGHTSOURCE 64 /* Always lit */
+#define OB_LIGHT0 128 /* Lit in state 0 */
+#define OB_NOSEECARRY 256 /* Don't see item when carried */
+
+struct Sub_Player
+{
+ SUB pl_Sub;
+ short pl_UserKey; /* -1 for mobiles */
+ short pl_Size; /* Overriden by object */
+ short pl_Weight; /* "" "" "" */
+ short pl_Strength; /* 1/10 Carrying Limit */
+ short pl_Flags; /* Misc Info */
+ short pl_Level; /* User Utilitised */
+ long pl_Score; /* User Utilitised */
+};
+
+#define PL_MALE 1 /* Player is male */
+#define PL_FEMALE 2 /* Player is female */
+#define PL_NEUTER 0 /* Player is sexless */
+#define PL_CONFUSED 3 /* Person with a problem! */
+#define PL_SEXBITS 3 /* Sex mask */
+#define PL_BRIEF 4 /* Player in BRIEF mode */
+#define PL_BLIND 8 /* Player cannot see */
+#define PL_DEAF 16 /* Player cannot hear */
+
+typedef struct Sub_Player PLAYER;
+
+struct Sub_GenExit
+{
+ SUB ge_Sub;
+ ITEM *ge_Dest[12]; /* Array of exits NULL - none */
+};
+
+typedef struct Sub_GenExit GENEXIT;
+
+struct Sub_CondExit
+{
+ SUB ce_Sub;
+ ITEM *ce_Dest;
+ short ce_Table;
+ short ce_ExitNumber;
+};
+
+typedef struct Sub_CondExit CONDEXIT;
+
+struct Sub_MsgExit
+{
+ SUB me_Sub;
+ ITEM *me_Dest; /* Where it goes */
+ TPTR me_Text; /* What text to use */
+ short me_ExitNumber; /* Which exit it is */
+};
+
+typedef struct Sub_MsgExit MSGEXIT;
+
+struct Sub_Chain
+{
+ SUB ch_Sub;
+ ITEM *ch_Chained; /* The linked item */
+};
+
+typedef struct Sub_Chain CHAIN;
+
+struct Sub_UserFlag
+{
+ SUB uf_Sub;
+ short uf_Flags[8]; /* 8 Number Flags (currently) */
+ ITEM *uf_Items[8]; /* 8 Item Flags (currently) */
+};
+
+typedef struct Sub_UserFlag USERFLAG;
+
+struct Sub_Container
+{
+ SUB co_Sub;
+ short co_Volume; /* MAX Volume */
+ short co_Flags;
+ TPTR co_ConText; /* Used to prefix contents lists (eg 'On the shelf is') */
+};
+
+typedef struct Sub_Container CONTAINER;
+
+#define CO_SOFT 1 /* Item has size increased by contents */
+#define CO_SEETHRU 2 /* You can see into the item */
+#define CO_CANPUTIN 4 /* For PUTIN action */
+#define CO_CANGETOUT 8 /* For GETOUT action */
+#define CO_CLOSES 16 /* Not state 0 = closed */
+#define CO_SEEIN 32 /* Container shows contents by */
+
+struct Sub_Snoop
+{
+ SUB sn_Sub;
+ ITEM *sn_Snooper; /* Who is snooping */
+ char sn_String[12]; /* 12 reserved bytes */
+ struct Sub_SnoopBack *sn_BackPtr; /* Other half of data */
+ short sn_Ident; /* Ident flags */
+};
+
+#define SN_PLAYER 1 /* Watching someone/thing */
+#define SN_PLACE 2 /* Not implemented yet */
+#define SN_GLOBAL 3 /* Fun.... but not working */
+
+typedef struct Sub_Snoop SNOOP;
+
+struct Sub_SnoopBack
+{
+ SUB sb_Sub;
+ ITEM *sb_Snooped; /* What we snooping */
+ SNOOP *sb_SnoopKey; /* Pointer to its snoop structure */
+};
+
+typedef struct Sub_SnoopBack SNOOPBACK;
+
+struct Sub_Dup
+{
+ SUB du_Sub;
+ ITEM *du_Master; /* Master this is copied from */
+};
+
+typedef struct Sub_Dup DUP;
+
+/*
+ * Ropes not currently supported
+ */
+
+struct Sub_Rope
+{
+ SUB ro_Sub;
+ ITEM *ro_Next[2]; /* Next node in both dirns */
+ ITEM *ro_Tied; /* First item this is tied to */
+ unsigned long ro_Event; /* Event key - stops looping */
+ short ro_Position; /* Node positioning */
+};
+
+typedef struct Sub_Rope ROPE;
+
+struct Sub_TieChain
+{
+ SUB tc_Sub;
+ ITEM *tc_Rope; /* The rope we are tied to */
+ ITEM *tc_Next; /* Next item tied in this list */
+ unsigned long tc_Event; /* Event number to avoid accidents */
+};
+
+typedef struct Sub_TieChain TIECHAIN;
+
+/*
+ * Inheritance of sub items
+ */
+
+struct Sub_Inherit
+{
+ SUB in_Sub;
+ ITEM *in_Master; /* Who to inherit from - NOT NESTED! */
+};
+
+typedef struct Sub_Inherit INHERIT;
+
+struct Sub_InOutHere
+{
+ SUB io_Sub;
+ TPTR io_InMsg;
+ TPTR io_OutMsg;
+ TPTR io_HereMsg;
+};
+
+typedef struct Sub_InOutHere INOUTHERE;
+
+struct Sub_UserText
+{
+ SUB ut_Sub;
+ TPTR ut_Text[8];
+};
+
+typedef struct Sub_UserText USERTEXT;
+
+/* New in 5.30 */
+
+struct Tag_Generic
+{
+ unsigned short ta_TagID;
+ unsigned short ta_TagInfo;
+ /* Tag data follows */
+};
+
+#define TAGID_SPACE 0 /* Tag ID for free space */
+#define TAGID(x) ((x)&0x7FFF) /* Tag field */
+#define TAGID_SIMPLE 0x8000 /* Tag has simple (2 byte) data form */
+
+struct Sub_Generic
+{
+ SUB ge_Sub;
+ unsigned short ge_TagCount;
+ struct Tag_Generic ge_Tags[1]; /* Array of 1 or more tags. */
+};
+
+/* Substructure Identity Tags. Note: If a substructure is changed so that
+ * it is incompatible with its old saved form, a new tag id should be
+ * defined for it, and a converting load routine added for the old one
+ * Such convertors will eventually be discarded when sufficiently old
+ * in the interests of code size. The other approach is to leave the tag
+ * ID the same, and to change system version number for the save format.
+ * The first method is much preferred
+ */
+
+#define KEY_ROOM 1
+#define KEY_OBJECT 2
+#define KEY_PLAYER 3
+#define KEY_GENEXIT 4
+#define KEY_MSGEXIT 5
+#define KEY_CONDEXIT 6
+#define KEY_CONTAINER 7
+#define KEY_CHAIN 8
+#define KEY_USERFLAG 9
+#define KEY_BACKTRACK 10 /* OBSOLETE - UNUSED */
+#define KEY_SNOOP 11
+#define KEY_SNOOPBACK 12
+#define KEY_ROPE 13 /* Reserved - unused */
+#define KEY_DUPED 14
+#define KEY_TIECHAIN 15 /* Reserved - unused */
+#define KEY_INOUTHERE 16
+#define KEY_USERTEXT 17
+#define KEY_USERFLAG2 18
+/*
+ * Entries 18-63 are reserved for system expansion - try to use 64-254 if
+ * you add your own user substructures, in case of system updates.
+ */
+
+#define KEY_INHERIT 255 /* Inherit */
+
+#define WD_NOUN 1
+#define WD_PREP 2
+#define WD_PRONOUN 3
+#define WD_CLASS 4
+#define WD_VERB 5
+#define WD_ADJ 6
+#define WD_NOISE 7 /* DO NOT USE! */
+#define WD_ORDIN 8
+
+struct ParserContext
+{
+ short pa_It[2]; /* Adj[0] Noun[1] of pronoun */
+ short pa_Them[2];
+ short pa_Him[2];
+ short pa_Her[2];
+ short pa_There[2];
+ short pa_Verb; /* <1 means none */
+};
+
+typedef struct ParserContext PCONTEXT;
+
+typedef struct Line LINE;
+
+struct Line
+{
+ short li_Verb; /* -1 = any -2 = none */
+ short li_Noun1;
+ short li_Noun2;
+ unsigned short *li_Data; /* The line command bytes */
+ LINE *li_Next; /* Next line to execute */
+};
+
+
+struct Table
+{
+ short tb_Number; /* Table number */
+ LINE *tb_First; /* First line */
+ TABLE *tb_Next; /* Next table in list */
+ TXT *tb_Name; /* Tables now have names! */
+};
+
+
+#define CMD_EOL 10000
+
+/*
+ * WARNING: The UserFileFormat structure IS machine dependant and
+ * length dependant. If you need to port a user file from machine
+ * to machine, write a program to read each entry and dump it all
+ * in Ascii on one machine, and another to convert the ascii back
+ * to UFF structures and resave. So long as you stick to similar
+ * processor machines you should be ok - eg SUN to AMIGA.
+ */
+
+struct UserFileFormat
+{
+ char uff_Name[32/*MAXNAME*/];
+ short uff_Perception;
+ short uff_ActorTable;
+ short uff_ActionTable;
+ short uff_Size;
+ short uff_Weight;
+ short uff_Strength;
+ short uff_Flags;
+ short uff_Level;
+ long uff_Score;
+ char uff_Password[8];
+ long uff_Flag[10];
+ char uff_Reserved[28]; /* For userflags etc */
+};
+
+typedef struct UserFileFormat UFF;
+
+#define Arch(x) ((ArchWizard(x))||(stricmp(CNameOf(x),CPRT)==0))
+#define ArchCheck(x) ArchWizard(x)
+
+/* Now the stuff for BSX. I did consider binding images to rooms and stuff, but it raises a few
+ awkward issues when you wish to do special effects, and by keeping them together it speeds
+ up BSX requests and lets me compress the hex format BSX data in memory */
+
+typedef struct _bsximage
+{
+ struct _bsximage *bsx_Next;
+ char bsx_Identifier[8];
+ unsigned char *bsx_Data;
+ short bsx_DataSize;
+} BSXImage;
+
+/* ----------------------- System.c Functions ---------------------- */
+
+#ifdef ANSI_C
+#include "Prototype.h" /* NON ANSI IS UNTESTED */
+#else
+#include "NoPrototype.h"
+#endif
diff --git a/TabCommand.c b/TabCommand.c
new file mode 100644
index 0000000..1ca0287
--- /dev/null
+++ b/TabCommand.c
@@ -0,0 +1,206 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+
+Module "Table Control Commands";
+Version "1.01";
+Author "Alan Cox";
+
+/*
+ * Commands for editing the tables.
+ *
+ * 1.00 AGC Original Commands
+ * 1.01 AGC Support For Named Tables
+ */
+
+
+void Cmd_ListTables(i)
+ITEM *i;
+{
+ TABLE *t=TableList;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Two small, one large and a multiplication..\n");
+ return;
+ }
+ while(t)
+ {
+ SendItem(i,"%d)\t%s\n",t->tb_Number,TextOf(t->tb_Name));
+ t=t->tb_Next;
+ }
+}
+
+void Cmd_AddTable(i)
+ITEM *i;
+{
+ TABLE *t;
+ FILE *f;
+ int n;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Ask a carpenter..\n");
+ return;
+ }
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Which Table Though ?\n");
+ return;
+ }
+ t=FindTable(n);
+ if(t)
+ {
+ if(t->tb_First)
+ {
+ SendItem(i,"Table Exists!\n");
+ return;
+ }
+ }
+ if(t==NULL)
+ {
+ if(!GetParsedWord())
+ {
+ SendItem(i,"You must specify a table name.\n");
+ return;
+ }
+ if(FindTableByName(WordBuffer)!=-1)
+ {
+ SendItem(i,"Table name already in use.\n");
+ return;
+ }
+ t=NewTable(n,WordBuffer);
+ }
+ GetAll();
+ f=fopen(WordBuffer,"r");
+ if(f==NULL)
+ {
+ SendItem(i,"Can't open file : %s.\n",WordBuffer);
+ return;
+ }
+ EncodeTable(i,t,f);
+ fclose(f);
+}
+
+void Cmd_DeleteTable(i)
+ITEM *i;
+{
+ TABLE *t;
+ int n;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Ask a carpenter..\n");
+ return;
+ }
+ if(GetParsedWord()==NULL)
+ {
+ SendItem(i,"Which Table ?\n");
+ return;
+ }
+ if(isdigit(*WordBuffer))
+ {
+ sscanf(WordBuffer,"%d",&n);
+ }
+ else
+ {
+ n=FindTableByName(WordBuffer);
+ if(n==-1)
+ {
+ SendItem(i,"No Such Table.\n");
+ return;
+ }
+ }
+ t=FindTable(n);
+ if(t==NULL)
+ {
+ SendItem(i,"No Such Table.\n");
+ return;
+ }
+ DeleteTable(t);
+}
+
+void Cmd_NewTable(i)
+ITEM *i;
+{
+ TABLE *t;
+ int n;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Ask a carpenter..\n");
+ return;
+ }
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Which Table Though ?\n");
+ return;
+ }
+ t=FindTable(n);
+ if(t)
+ {
+ if(t->tb_First)
+ {
+ SendItem(i,"Table Exists!\n");
+ return;
+ }
+ }
+ if(t==NULL)
+ {
+ if(!GetParsedWord())
+ {
+ SendItem(i,"You must specify a table name.\n");
+ return;
+ }
+ if(FindTableByName(WordBuffer)!=-1)
+ {
+ SendItem(i,"Table name already in use.\n");
+ return;
+ }
+ t=NewTable(n,WordBuffer);
+ }
+}
+
+void Cmd_NameTable(i)
+ITEM *i;
+{
+ TABLE *t;
+ int n;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"I hearby christen this table 'Fred'.\n");
+ return;
+ }
+ n=GetNumber();
+ if(n==-1)
+ {
+ SendItem(i,"Which table though ?\n");
+ return;
+ }
+ t=FindTable(n);
+ if(t==NULL)
+ {
+ SendItem(i,"No such table.\n");
+ return;
+ }
+ if(!GetParsedWord())
+ {
+ SendItem(i,"You must specify a table name.\n");
+ return;
+ }
+ if(FindTableByName(WordBuffer)!=-1)
+ {
+ SendItem(i,"Table name already in use.\n");
+ return;
+ }
+ FreeText(t->tb_Name);
+ t->tb_Name=AllocText(WordBuffer);
+}
+
+
diff --git a/TableDriver.c b/TableDriver.c
new file mode 100644
index 0000000..779da7f
--- /dev/null
+++ b/TableDriver.c
@@ -0,0 +1,969 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+#include <string.h>
+
+Module "Table Drivers";
+Version "1.18";
+Author "Alan Cox";
+
+TABLE *TableList=NULL; /* Linked list of tables */
+TPTR TxtArg=NULL; /* {$} */
+TPTR TxtArg2=NULL; /* {$2} */
+char TxBuf[512]; /* Working buffer */
+#ifdef BOOT_DEBUG
+int System_Debug=1; /* Decide if debugging starts ON */
+#else
+int System_Debug=0;
+#endif
+static short FlagData[512]; /* The flags - change number here and in GetFlag
+ SetFlag, if desired. */
+short Traf[4]={-1,-1,-1,-1}; /* four flags max being tracked */
+
+static unsigned short *DataPointer; /* Where we are in table */
+LINE *CurrentLine; /* Line we are executing */
+TABLE *CurrentTable; /* Table we are executing */
+ITEM *Item1,*Item2; /* $1 and $2 data values */
+int Noun1,Adj1,Noun2,Adj2,Verb,Prep; /* The word codes needed */
+int Ord1,Ord2;
+ITEM *Debugger; /* Dest for flag traps */
+
+/*
+ * 1.00 AGC Created
+ * 1.01-1.05 AGC Added lots of action calls
+ * 1.06 AGC Added DAEMON entry points
+ * 1.07 AGC Added background executes
+ * 1.08 AGC Misc Bug Fixes and added stack protection
+ * 1.09 AGC Next batch of commands added
+ * 1.10 AGC Commands added in the right place this time
+ * 1.11 AGC Fixed debugging crashes (NOT RIGHT STILL) and mended NOT
+ * 1.12 AGC Allowed DAEMON etc to nest DOCLASS calls.
+ * 1.13 AGC Made END and KILLOFF do DONE so they don't crash(as often)
+ * 1.14 AGC Added Flag Tracking Code
+ * 1.15 AGC Added Ordinate Code
+ * 1.16 AGC Fixed UArgNum 512 byte error areas problem.
+ * Also added DEBUG 2 - second level debugging
+ * 1.17 AGC 5.08 changes for item bound tables
+ * 1.18 AGC Fixed stupid bugs assuming top bit of address was 0
+ * 1.19 AGC Private Daemon Table. Superclasses
+ */
+
+void WipeFlags()
+{
+ short ct=0;
+ while(ct<512)
+ FlagData[ct++]=0; /* Clear all the flags */
+}
+
+int GetFlag(n)
+int n;
+{
+ if(n<0||n>=512)
+ {
+ Log("Flag Out Of Range");
+ SendItem(Me(),"Flag Out Of Range [%d].\n",n);
+ return(-1);
+ }
+ return((int)FlagData[n]); /* Get the value of a flag */
+}
+
+void PCurrentLine()
+{
+ char x[512];
+ if(Debugger&&CurrentLine)
+ {
+ Decompress(CurrentLine,x); /* Print it to DEBUG */
+ SendItem(Debugger,"%d:%s:%s\n",(int)CurrentTable->tb_Number,
+ CNameOf(Me()),x);
+ }
+}
+
+void FPCurrentLine()
+{
+ char x[512];
+ if(Debugger&&CurrentLine)
+ {
+ Decompress(CurrentLine,x); /* Print it to DEBUG */
+ fprintf(stderr,"%d:%s:%s\n",(int)CurrentTable->tb_Number,
+ CNameOf(Me()),x);
+ }
+}
+
+void SetFlag(n,m) /* Set the value of a flag */
+int n,m;
+{
+ if((n<0)||(n>511))
+ {
+ Log("Flag Out Of Range");
+ SendItem(Me(),"Flag Out Of Range [%d].\n",n);
+ return;
+ }
+ if(Traf[0]==n)
+ if(Debugger)
+ {
+ SendItem(Debugger,"Flag %d -> %d\n",n,m);
+ PCurrentLine();
+ }
+ if(Traf[1]==n)
+ if(Debugger)
+ {
+ SendItem(Debugger,"Flag %d -> %d\n",n,m);
+ PCurrentLine();
+ }
+ if(Traf[2]==n)
+ if(Debugger)
+ {
+ SendItem(Debugger,"Flag %d -> %d\n",n,m);
+ PCurrentLine();
+ }
+ if(Traf[3]==n)
+ if(Debugger)
+ {
+ SendItem(Debugger,"Flag %d -> %d\n",n,m);
+ PCurrentLine();
+ }
+ FlagData[n]=m;
+}
+
+static ITEM *CurrentPlayer; /* $ME */
+static ITEM *ActorPlayer; /* $AC */
+
+/*
+ * A fake item which does the set up...
+ */
+TXT DummyTxt={"<GLOBAL DUMMY>",-1,NULL};
+ITEM DummyItem={NULL,NULL,NULL,NULL,-1,-1,-1,-1,0,0,0,0,NULL,NULL,NULL,NULL,NULL,NULL};
+
+ITEM *Me()
+{
+ DummyItem.it_Name=&DummyTxt; /* Set up item */
+ if(CurrentPlayer==NULL)
+ return(&DummyItem); /* No player so is dummy */
+ return(CurrentPlayer); /* Else is player */
+}
+
+void SetMe(i) /* Set current player ($ME) */
+ITEM *i;
+{
+ CurrentPlayer=i;
+}
+
+ITEM *Actor()
+{
+ DummyItem.it_Name=&DummyTxt;
+ if(ActorPlayer==NULL)
+ return(&DummyItem);
+ return(ActorPlayer);
+}
+
+
+int ArgNum() /* Read numeric (number/flag) argument from line */
+{
+ int a=((int)*DataPointer++);
+ if((a>=30000)&&(a<30512))
+ return(GetFlag(a-30000));
+ else
+ return(a);
+}
+
+unsigned int UArgNum() /* Read word, unmodified from text */
+{
+ unsigned int a=((unsigned int)(*DataPointer++));
+ return(a);
+}
+
+int ArgWord() /* Read word from line */
+{
+ return((int)(*DataPointer++));
+}
+
+ITEM *ArgItem() /* Read item from line */
+{
+ ITEM *x=(ITEM *)PairArg(DataPointer);
+ DataPointer+=2;
+ if(x==(ITEM *)1)
+ x=Item1; /* $1 */
+ if(x==(ITEM *)3) /* $2 */
+ x=Item2;
+ if(x==(ITEM *)5) /* $ME */
+ x=Me();
+ if(x==(ITEM *)7) /* $AC */
+ x=Actor();
+ if(x==(ITEM *)9) /* $RM */
+ x=O_PARENT(Me());
+ if(x==NULL)
+ {
+ Broadcast("Invalid Item Reference: -> Using ME as dummy.\n",0);
+ FPCurrentLine();
+ Log("Invalid Item Reference: -> Using ME as dummy.\n");
+ return(Me());
+ }
+ return(x);
+}
+
+TPTR ArgText() /* Read a text argument */
+{
+ TPTR x=(TPTR)PairArg(DataPointer);
+ DataPointer+=2;
+ if(x==(TPTR )1)
+ {
+ x=TxtArg; /* {$} */
+ WordPtr=NULL;
+ }
+ if(x==(TPTR )3)
+ {
+ x=TxtArg2; /* {$2} */
+ WordPtr=NULL;
+ }
+ return(x);
+}
+
+void ParseArgs(v) /* Break input using parser */
+int v;
+{
+ Verb=v;
+ GetRestOfInput(WordPtr,TxBuf);
+ if(TxtArg)
+ FreeText(TxtArg); /* Free any old {$} */
+ while(*WordPtr)
+ if(isspace(*WordPtr))
+ WordPtr++;
+ else
+ break;
+ TxtArg=AllocText(WordPtr); /* Set new {$} */
+ Ord1=GetOrd();
+ if(GetThing(&Adj1,&Noun1)==-1)
+ {
+ Adj1=-1; /* Parse arg 1 */
+ Noun1=-1;
+ }
+ if(TxtArg2) /* Delete old and create new {$2} */
+ FreeText(TxtArg2);
+ while(*WordPtr)
+ if(isspace(*WordPtr))
+ WordPtr++;
+ else
+ break;
+ TxtArg2=AllocText(WordPtr);
+ Prep=GetPrep();
+ Ord2=GetOrd();
+ if(GetThing(&Adj2,&Noun2)==-1)
+ {
+ Adj2=-1; /* Parse arg 2 */
+ Noun2=-1;
+ }
+ Item1=FindAnItem(Adj1,Noun1,Ord1); /* Find $1 and $2 */
+ if(Item1)
+ SetItData(-1,Item1,(short)Adj1,(short)Noun1);
+ Item2=FindAnItem(Adj2,Noun2,Ord2);
+ if(Item2)
+ SetItData(-1,Item2,(short)Adj2,(short)Noun2);
+}
+
+#define WORDMATCH(a,b) (((a)==-1)||((a)==(b))||(((a)==-2)&&((b)==-1)))
+
+int ArgMatch(l) /* Decide if line should be run */
+LINE *l;
+{
+ if(!WORDMATCH(l->li_Verb,Verb))
+ return(0);
+ if(!WORDMATCH(l->li_Noun1,Noun1))
+ return(0);
+ if(!WORDMATCH(l->li_Noun2,Noun2))
+ return(0);
+ return(1);
+}
+
+int ExecBackground(t,i) /* Run a table in background (WHEN) */
+TABLE *t;
+ITEM *i;
+{
+ int n;
+ ITEM *p=CurrentPlayer;
+ CurrentPlayer=i;
+ n=ExecTable(t);
+ CurrentPlayer=p;
+ return(n);
+}
+
+int ExecTable(t) /* Run a table */
+TABLE *t;
+{
+ static short TCount=0;
+ short lcm1=ClassMode1,lcm2=ClassMode2; /* Lots of junk to save */
+ register LINE *lcl=ClassLine; /* For recursions PROCESS */
+ short lcmsk=ClassMask;
+ int stat=-1;
+ LINE *l=t->tb_First; /* First line to run */
+ TABLE *ot=CurrentTable;
+ LINE *ol=CurrentLine;
+ unsigned short *op=DataPointer;
+ ITEM *lfp=GetNextPointer(); /* Stack DOCLASS search info */
+ ClassMode1=0;
+ ClassMode2=0;
+ ClassLine=NULL;
+ ClassMask=0; /* Clear DOCLASS prev */
+ TCount++;
+ if(TCount>40) /* Stack Max */
+ {
+ TCount=0;
+ SendItem(Me(),"STACK OVERFLOW: KERNEL RESET\n");
+ printf("STACK OVERFLOW: KERNEL RESET\n");
+ longjmp(Oops,1); /* Escape to top level ! */
+ }
+ CurrentTable=t;
+l1: while(l) /* For each line */
+ {
+ CurrentLine=l;
+ if(ArgMatch(l)) /* If it should be run */
+ {
+ if(System_Debug)
+ {
+ static char x[512];
+ Decompress(l,x); /* Print it to DEBUG */
+ printf("%d:%s:%s\n",(int)t->tb_Number,
+ CNameOf(Me()),
+ x);
+ }
+ stat=0;
+ DataPointer=l->li_Data;
+ if((stat=RunLine(l))!=0) /* Run the line */
+ break;
+ }
+ l=l->li_Next;
+ }
+ if(ClassMode1) /* Check for DOCLASS logic */
+ {
+ Item1=NextInByClass(LevelOf(Me()),Item1,ClassMask);
+ if(!Item1)
+ {
+ ClassMode1=0;
+ }
+ else
+ {
+ l=ClassLine; /* Rescanner */
+ goto l1;
+ }
+ }
+ if(ClassMode2)
+ {
+ Item2=NextInByClass(LevelOf(Me()),Item2,ClassMask);
+ if(!Item2)
+ {
+ ClassMode2=0;
+ }
+ else
+ {
+ l=ClassLine; /* Rescanner */
+ goto l1;
+ }
+ }
+ if(stat==-10) /* stat -10 return means rescan table */
+ {
+ l=t->tb_First;
+ goto l1;
+ }
+ DataPointer=op; /* Put it all back */
+ CurrentLine=ol;
+ CurrentTable=ot;
+ ClassMode1=lcm1;
+ ClassMode2=lcm2;
+ ClassLine=lcl;
+ ClassMask=lcmsk;
+ TCount--;
+ SetNextPointer(lfp); /* Restore DOCLASS search context */
+ return(stat); /* Return answer */
+}
+
+
+int RunLine(x) /* Execute a line of database */
+register LINE *x;
+{
+ register int c,v,neg;
+ while((c=ArgNum())!=CMD_EOL) /* End marker ? */
+ {
+ neg=0;
+ if(c==203) /* NOT */
+ {
+ neg=1; /* Note in NOT mode */
+ c=ArgNum();
+ if(c==CMD_EOL) /* Trap NOT as last command! */
+ break;
+ }
+ v=1;
+ if(System_Debug==2)
+ printf("Action: %s\n",Cnd_Table[c]);
+/* Apple A/UX can't handle big switch statements (sigh)
+ oh for a real compiler */
+ if(c<200) {
+ switch(c) /* Run correct condition/action */
+ {
+/*
+ * BASIC CONDITIONS
+ */
+ case 0:v=Cnd_At();break;
+ case 1:v=Cnd_NotAt();break;
+ case 2:v=Cnd_Present();break;
+ case 3:v=Cnd_Absent();break;
+ case 4:v=Cnd_Worn();break;
+ case 5:v=Cnd_NotWorn();break;
+ case 6:v=Cnd_Carried();break;
+ case 7:v=Cnd_NotCarr();break;
+ case 8:v=Cnd_IsAt();break;
+ case 9:v=Cnd_IsNotAt();break;
+ case 10:v=Cnd_IsBy();break;
+ case 11:v=Cnd_IsNotBy();break;
+ case 12:v=Cnd_Zero();break;
+ case 13:v=Cnd_NotZero();break;
+ case 14:v=Cnd_Eq();break;
+ case 15:v=Cnd_NotEq();break;
+ case 16:v=Cnd_Gt();break;
+ case 17:v=Cnd_Lt();break;
+ case 18:v=Cnd_EqF();break;
+ case 19:v=Cnd_NeF();break;
+ case 20:v=Cnd_LtF();break;
+ case 21:v=Cnd_GtF();break;
+ case 22:v=Cnd_IsIn();break;
+ case 23:v=Cnd_IsNotIn();break;
+ case 24:v=Cnd_Adj1();break;
+ case 25:v=Cnd_Adj2();break;
+ case 26:v=Cnd_Noun1();break;
+ case 27:v=Cnd_Noun2();break;
+ case 28:v=Cnd_Prep();break;
+ case 29:v=Cnd_Chance();break;
+ case 30:v=Cnd_IsPlayer();break;
+ case 31:v=Cnd_IsUser();break;
+ case 32:v=Cnd_IsRoom();break;
+ case 33:v=Cnd_IsObject();break;
+ case 34:v=Cnd_State();break;
+ case 35:v=Cnd_PFlag();break;
+ case 36:v=Cnd_OFlag();break;
+ case 37:v=Cnd_CanPut();break;
+ case 38:v=Cnd_RFlag();break;
+ case 39:v=Cnd_Level();break;
+ case 40:v=Cnd_IfDeaf();break;
+ case 41:v=Cnd_IfBlind();break;
+ case 42:v=Cnd_Arch();break;
+/*
+ * MAIN ACTION LIST
+ */
+ case 43:Act_Get();break;
+ case 44:Act_Drop();break;
+ case 45:Act_Remove();break;
+ case 46:Act_Wear();break;
+ case 47:Act_Create();break;
+ case 48:Act_Destroy();break;
+ case 49:Act_PutO();break;
+ case 50:Act_Swap();break;
+ case 51:Act_Place();break;
+ case 52:Act_PutIn();break;
+ case 53:Act_TakeOut();break;
+ case 54:Act_CopyOF();break;
+ case 55:Act_CopyFO();break;
+ case 56:Act_CopyFF();break;
+ case 57:Act_WhatO();break;
+ case 58:Act_GetO();break;
+ case 59:Act_Weigh();break;
+ case 60:Act_Set();break;
+ case 61:Act_Clear();break;
+ case 62:Act_PSet();break;
+ case 63:Act_PClear();break;
+ case 64:Act_Let();break;
+ case 65:Act_Add();break;
+ case 66:Act_Sub();break;
+ case 67:Act_AddF();break;
+ case 68:Act_SubF();break;
+ case 69:Act_Mul();break;
+ case 70:Act_Div();break;
+ case 71:Act_MulF();break;
+ case 72:Act_DivF();break;
+ case 73:Act_Mod();break;
+ case 74:Act_ModF();break;
+ case 75:Act_Random();break;
+ case 76:Act_Move();break;
+ case 77:Act_Goto();break;
+ case 78:Act_Weight();break;
+ case 79:Act_Size();break;
+ case 80:Act_OSet();break;
+ case 81:Act_OClear();break;
+ case 82:Act_RSet();break;
+ case 83:Act_RClear();break;
+ case 84:Act_PutBy();break;
+ case 85:Act_Inc();break;
+ case 86:Act_Dec();break;
+ case 87:Act_SetState();break;
+ case 88:Act_Prompt();break;
+ case 89:Act_Print();break;
+ case 90:Act_Score();break;
+ case 91:Act_Message();break;
+ case 92:Act_Msg();break;
+ case 93:Act_ListObj();break;
+ case 94:Act_ListAt();break;
+ case 95:Act_Inven();break;
+ case 96:Act_Desc();break;
+ case 97:Act_End();return(1);
+ case 98:return(1); /* DONE */
+ case 99:return(-1); /* NOTDONE */
+ case 100:Act_Ok();return(1);
+ case 101:Act_Abort();break;
+ case 102:Act_Save();break;
+ case 103:Act_Parse();break;
+ case 104:Act_NewText();break;
+ case 105:Act_Process();break;
+ case 106:Act_DoClass();break;
+ case 107:Act_Give();break;
+ case 108:Act_SetUText();break;
+ case 109:Act_DoesAction();break;
+ case 110:Act_DoesTo();break;
+ case 111:Act_DoesToPlayer();break;
+ case 112:Act_PObj();break;
+ case 113:Act_PLoc();break;
+ case 114:Act_PName();break;
+ case 115:Act_PCName();break;
+ case 116:Act_Daemon();break;
+ case 117:Act_AllDaemon();break;
+ case 118:Act_HDaemon();break;
+ case 119:Act_When();break;
+ case 120:Act_SetName();break;
+ case 121:Act_Dup();break;
+ case 122:Act_Frig();break;
+ case 123:Act_Points();break;
+ case 124:Act_Hurt();break;
+ case 125:Act_Cured();break;
+ case 126:Act_KillOff();return(1);
+ case 127:Act_AutoVerb();break;
+ case 128:v=Act_If1();break;
+ case 129:v=Act_If2();break;
+ case 130:Act_Bug();break;
+ case 131:Act_Typo();break;
+ case 132:Act_NArg();break;
+ case 133:v=Act_IsMe();break;
+ case 134:Act_Broadcast();break;
+ case 135:v=Cnd_IsCalled();break;
+ case 136:v=Cnd_Is();break;
+ case 137:Act_SetMe();break;
+ case 138:Act_Pronouns();break;
+ case 139:v=Cnd_ChanceLev();break;
+ case 140:Act_Exits();break;
+ case 141:Act_PWChange();break;
+ case 142:Act_Snoop();break;
+ case 143:Act_UnSnoop();break;
+ case 144:Act_GetUText();break;
+ case 145:Act_Cat();break;
+ case 146:Act_Become();break;
+ case 147:Act_Alias();break;
+ case 148:Act_UnAlias();break;
+ case 149:Act_Field();break;
+ case 150:Act_NeedField();break;
+ case 151:Act_Unveil();break;
+ case 152:Act_Debug();break;
+ case 153:Act_GetScore();break;
+ case 154:Act_GetStr();break;
+ case 155:Act_GetLev();break;
+ case 156:Act_SetScore();break;
+ case 157:Act_SetLev();break;
+ case 158:Act_SetStr();break;
+ case 159:Act_Shell();break;
+ case 160:Act_CSet();break;
+ case 161:Act_CClear();break;
+ case 162:v=Cnd_CFlag();break;
+ case 163:v=Cnd_CanSee();break;
+ case 164:return(-10);
+ case 165:Act_Means();break;
+ case 166:Act_TreeDaemon();break;
+ case 167:Act_SetIn();break;
+ case 168:Act_SetOut();break;
+ case 169:Act_SetHere();break;
+ case 170:Act_CanGoto();break;
+/*
+ * Must re-write these one day - but are they needed ?
+ */
+ case 171:Act_Mobiles();break;
+ case 172:Act_Dir();break;
+ case 173:Act_Rooms();break;
+/*
+ * ITE/EXIT MANIPULATORS
+ */
+ case 174:Act_ChainDaemon();break;
+ case 175:Act_CanGoBy();break;
+ case 176:Act_SetIFlag();break;
+ case 177:Act_GetIFlag();break;
+ case 178:Act_ClearIFlag();break;
+ case 180:Act_WhereTo();break;
+ case 181:Act_DoorExit();break;
+/*
+ * ROPE LOGIC - NOT YET REWRITTEN
+ */
+ case 182:v=Cnd_CanMoveRope();break;
+ case 183:Act_PlaceRope();break;
+ case 184:v=Cnd_IsRope();break;
+ case 185:v=Cnd_IsTied();break;
+ case 186:Act_RopePrev();break;
+ case 187:Act_RopeNext();break;
+ case 188:Act_Tie();break;
+ case 189:Act_Untie();break;
+ case 190:Act_Join();break;
+ case 191:Act_CutRope();break;
+ case 192:Act_Distance();break;
+ case 193:Act_WhichWay();break;
+/*
+ * ASSORTED ADDITIONS
+ */
+ case 194:v=Cnd_ClassAt();break;
+ case 195:v=Cnd_DupOf();break;
+ case 196:Act_MasterOf();break;
+ case 197:Act_TiedTo();break;
+ case 198:Act_Comment();break;
+ case 199:Act_ComVocab();break;
+ }
+ } else { /* Sigh.. */
+ switch(c){
+ case 200:Act_Command();break;
+ case 201:Act_BSXScene();break;
+ case 202:Act_BSXObject();break;
+ case 204:v=Cnd_IfDark();break;
+ case 205:Act_Visibility();break;
+ case 206:Act_GetParent();break;
+ case 207:Act_GetNext();break;
+ case 208:Act_GetChild();break;
+ case 209:Act_PExit();break;
+ case 210:Act_SetDesc();break;
+ case 211:Act_SetLong();break;
+ case 212:Act_SetShort();break;
+ case 213:Act_GetLong();break;
+ case 214:Act_GetShort();break;
+ case 215:Act_GetDesc();break;
+ case 216:Act_GetName();break;
+ case 217:Act_Swat();break;
+ case 218:Act_Flat();break;
+ case 219:Act_FindMaster();break;
+ case 220:Act_NextMaster();break;
+ case 221:Act_FindIn();break;
+ case 222:Act_NextIn();break;
+ case 223:Act_LenText();break;
+/*
+ * 5.21 extensions for superclasses
+ */
+ case 224:v=Cnd_ProcSubject();break;
+ case 225:v=Cnd_ProcObject();break;
+ case 226:v=Cnd_ProcDaemon();break;
+ case 227:v=Cnd_GetSuper();break;
+ case 228:Act_SetSuper();break;
+ case 229:v=Cnd_Member();break;
+/*
+ * Blizzad.uni uses this function, so we have to implement it
+ */
+ case 231:Act_Cls();break;
+
+/*
+ * Aber5 extensions for better game control
+ * variable saving etc.
+ */
+ case 243:v=Cnd_IsClass();break;
+ case 244:v=Cnd_SubStr();break;
+ case 245:Act_GetIn();break;
+ case 246:Act_GetOut();break;
+ case 247:Act_GetHere();break;
+ case 248:Act_Log();break;
+ case 249:Act_SetClass();break;
+ case 250:Act_UnSetClass();break;
+ case 251:Act_BitClear();break;
+ case 252:Act_BitSet();break;
+ case 253:v=Cnd_BitTest();break;
+ case 254:Act_SPrint();break;
+ case 255:Act_User();break;
+ case 256:Act_SetI();break;
+ case 257:Act_CDaemon();break;
+ case 258:v=Cnd_Delete();break;
+ case 259:v=Cnd_ULoad();break;
+ case 260:v=Cnd_USave();break;
+ case 261:v=Cnd_FLoad();break;
+ case 262:v=Cnd_FSave();break;
+ case 263:Act_Getvis();break;
+ case 264:Act_MessageTo();break;
+ case 265:Act_MsgTo();break;
+ case 266:Act_RwhoDeclareUp();break;
+ case 267:Act_RwhoDeclareDown();break;
+ case 268:Act_RwhoLogin();break;
+ case 269:Act_RwhoLogout();break;
+ case 270:Act_RwhoDeclareAlive();break;
+ case 271:Act_SetExit();break;
+ case 272:Act_DelExit();break;
+/* case 273:Act_GetExit();break;*/
+ case 274:Act_ForkDump();break;
+ default:SendItem(Me(),"Error Invalid Action(%d)\n",c);
+ }
+ }
+ if(v==neg) /* Check for failed break */
+ break;
+ }
+ return(0);
+}
+
+ITEM *FindAnItem(ad,no,ord) /* Find an item in normal path (ROOM/CARRIED) */
+int ad,no,ord;
+{
+ ITEM *a;
+ a=FindIn(LevelOf(Me()),O_PARENT(Me()),(short)ad,(short)no);
+ if(!a)
+ goto l2;
+ while(--ord)
+ {
+ a=NextIn(LevelOf(Me()),a,(short)ad,(short)no);
+ if(!a)
+ goto l2;
+ }
+ return(a);
+l2: a=FindIn(LevelOf(Me()),Me(),(short)ad,(short)no);
+ if(!a)
+ return(a);
+ while(--ord)
+ {
+ a=NextIn(LevelOf(Me()),a,(short)ad,(short)no);
+ if(!a)
+ return(a);
+ }
+ return(a);
+}
+
+int FindTableByName(x)
+char *x;
+{
+ TABLE *t=TableList;
+ while(t)
+ {
+ if(stricmp(TextOf(t->tb_Name),x)==0)
+ return(t->tb_Number);
+ t=t->tb_Next;
+ }
+ return(-1);
+}
+
+TABLE *FindTable(n) /* Find a table by number */
+int n;
+{
+ TABLE *t=TableList;
+ while(t)
+ {
+ if(t->tb_Number==n)
+ return(t);
+ t=t->tb_Next;
+ }
+ return(NULL);
+}
+
+TABLE *NewTable(n,name) /* Create a table */
+int n;
+char *name;
+{
+ TABLE *l=Allocate(TABLE);
+ l->tb_Number=n;
+ l->tb_Next=TableList;
+ l->tb_First=NULL;
+ if(name)
+ l->tb_Name=AllocText(name);
+ TableList=l;
+ return(l);
+}
+
+LINE *NewLine(t,n) /* Create a line */
+TABLE *t;
+int n;
+{
+ LINE *a=Allocate(LINE);
+ LINE *p=NULL;
+ LINE *l=t->tb_First;
+ if(l==NULL)
+ goto skisc;
+ while(n)
+ {
+ p=l;
+ l=l->li_Next;
+ if(l==NULL)
+ break;
+ n--;
+ }
+skisc: if(p)
+ {
+ p->li_Next=a;
+ a->li_Next=l;
+ }
+ else
+ {
+ a->li_Next=t->tb_First;
+ t->tb_First=a;
+ }
+ a->li_Data=Allocate(unsigned short);
+ a->li_Data[0]=CMD_EOL;
+ return(a);
+}
+
+LINE *FindLine(t,n) /* Find specific line */
+TABLE *t;
+int n;
+{
+ LINE *l=t->tb_First;
+ while(n)
+ {
+ if(l==NULL)
+ return(l);
+ l=l->li_Next;
+ n--;
+ }
+ return(l);
+}
+
+int DeleteLine(t,n) /* Delete a line (lowest level) */
+TABLE *t;
+int n;
+{
+ LINE *l=FindLine(t,n);
+ LINE *p;
+ if(n==0)
+ {
+ if(l==NULL)
+ return(-1);
+ t->tb_First=l->li_Next;
+ }
+ else
+ {
+ p=FindLine(t,n-1);
+ if(l==NULL)
+ return(-1); /* No Such Line */
+ p->li_Next=l->li_Next;
+ }
+ free((char *)l->li_Data);
+ free((char *)l);
+ return(0);
+}
+
+int WipeDeleteLine(t,n) /* Delete a line (lowest level) */
+TABLE *t;
+int n;
+{
+ LINE *l=FindLine(t,n);
+ LINE *p;
+ if(n==0)
+ {
+ if(l==NULL)
+ return(-1);
+ t->tb_First=l->li_Next;
+ }
+ else
+ {
+ p=FindLine(t,n-1);
+ if(l==NULL)
+ return(-1); /* No Such Line */
+ p->li_Next=l->li_Next;
+ }
+ WipeLine(l);
+ free((char *)l->li_Data);
+ free((char *)l);
+ return(0);
+}
+
+int UserAction(u,v)
+ITEM *u;
+int v; /* Pregot Verb */
+{
+ TABLE *t;
+ int ct=0; /* Safety on superclass loops */
+ ITEM *i1;
+ ITEM *i2;
+
+ CurrentPlayer=u;
+ ParseArgs(v);
+
+ i1=Item1;
+ i2=Item2;
+
+ if(Item2)
+ {
+ while(i2 && ct<20)
+ {
+ ct++;
+ if(i2->it_ObjectTable)
+ {
+ if(ExecTable(i2->it_ObjectTable)==1)
+ return(1);
+ }
+ i2=i2->it_Superclass;
+ }
+
+ }
+ if(Item1)
+ {
+ ct=0;
+ while(i1 && ct<20)
+ {
+ ct++;
+ if(i1->it_SubjectTable)
+ {
+ if(ExecTable(i1->it_SubjectTable)==1)
+ return(1);
+ }
+ i1=i1->it_Superclass;
+ }
+ }
+ t=FindTable(u->it_ActorTable);
+ if(t==NULL)
+ return(-1);
+ return(ExecTable(t));
+}
+
+int UserDaemon(i)
+ITEM *i;
+{
+ TABLE *t;
+ ITEM *op=CurrentPlayer;
+ ITEM *oa=ActorPlayer;
+ ITEM *o1=Item1,*o2=Item2;
+ ITEM *ip=i;
+ int n=0;
+ int ct=0;
+
+ ActorPlayer=CurrentPlayer;
+ CurrentPlayer=i;
+
+
+ while(ip && n!=1 && ct<20)
+ {
+ t=ip->it_DaemonTable;
+ if(t!=NULL)
+ n=ExecTable(t);
+ ct++;
+ ip=ip->it_Superclass;
+ }
+ if(n!=1)
+ {
+ t=FindTable(i->it_ActionTable);
+ if(t!=NULL)
+ ExecTable(t); /* System table last */
+ }
+
+/*
+ * We have to restore NULL if the person we are returning to has just
+ * gone and died. If this is the case his item pointer will be invalid.
+ * This relies on the fact that no creation occurs during the daemons too
+ * (Basically this one is a problem, and a little dodgy at the moment).
+ */
+ if(((op!=i)||(CurrentPlayer!=NULL))&&(ValidItem(op)))
+ CurrentPlayer=op;
+ ActorPlayer=oa;
+ Item1=o1;
+ Item2=o2;
+ return(n);
+}
+
+int RandPerc() /* Random %age chance */
+{
+ return((rand()>>7)%100);
+}
diff --git a/TableEditing.c b/TableEditing.c
new file mode 100644
index 0000000..f543a4a
--- /dev/null
+++ b/TableEditing.c
@@ -0,0 +1,647 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+#include "User.h"
+
+extern USER UserList[];
+
+Module "Table Editing";
+Version "1.03";
+Author "Alan Cox";
+
+/*
+ * 1.01 AGC Initial Code.
+ * 1.02 AGC Tweaks for 5.08 to support item bound tables.
+ * 1.03 AGC Daemon table support.
+ */
+
+
+extern void Tbl_Edit();
+
+char *EditingBuffers[MAXUSER];
+
+void Cmd_EditTable(i)
+ITEM *i;
+{
+ int u,n;
+ short ct=0;
+ TABLE *t;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Carpentry ?\n");
+ return;
+ }
+ u=UserOf(i);
+ if(u==-1)
+ return;
+ if(GetParsedWord()==NULL)
+ {
+ SendItem(i,"Yes but which table.\n");
+ return;
+ }
+ if(isdigit(*WordBuffer))
+ sscanf(WordBuffer,"%d",&n);
+ else
+ {
+ n=FindTableByName(WordBuffer);
+ if(n==-1)
+ {
+ SendItem(i,"Unknown table.\n");
+ return;
+ }
+ }
+ t=FindTable(n);
+ if(t==NULL)
+ {
+ SendItem(i,"No such table.\n");
+ return;
+ }
+ ct=0;
+ while(ct<MAXUSER)
+ {
+ if(((UserList[ct].us_State==AWAIT_TEDIT)||
+ (UserList[ct].us_State==AWAIT_EDLIN))&&
+ UserList[ct].us_UserPtr==(char *)t)
+ {
+ SendItem(i,"Sorry - This table is being edited.\n");
+ SendUser(ct,"%s tried edit this table.\n",
+ CNameOf(i));
+ return;
+ }
+ ct++;
+ }
+ if(EditingBuffers[u]==NULL)
+ EditingBuffers[u]=malloc(512);
+ if(EditingBuffers[u]==NULL)
+ {
+ SendItem(i,"Sorry - no memory.\n");
+ return;
+ }
+ UserList[u].us_State=AWAIT_TEDIT;
+ UserList[u].us_UserInfo=0; /* Start Line */
+ UserList[u].us_UserPtr=(char *)t;
+ SetPrompt(UserList[u].us_Item,":");
+}
+
+void Cmd_EditOTable(i)
+ITEM *i;
+{
+ int u;
+ TABLE *t;
+ ITEM *j;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Carpentry ?\n");
+ return;
+ }
+ u=UserOf(i);
+ if(u==-1)
+ return;
+ j=FindSomething(i,O_PARENT(i));
+ if(j==NULL)
+ {
+ SendItem(i,"What is that ?\n");
+ return;
+ }
+ t=j->it_ObjectTable;
+ if(t==NULL)
+ {
+ t=Allocate(TABLE);
+ j->it_ObjectTable=t;
+ t->tb_Number= -1;
+ t->tb_Next=NULL;
+ t->tb_First=NULL;
+ t->tb_Name=AllocText("");
+ }
+ if(EditingBuffers[u]==NULL)
+ EditingBuffers[u]=malloc(512);
+ if(EditingBuffers[u]==NULL)
+ {
+ SendItem(i,"Sorry - no memory.\n");
+ return;
+ }
+ UserList[u].us_State=AWAIT_TEDIT;
+ UserList[u].us_UserInfo=0; /* Start Line */
+ UserList[u].us_UserPtr=(char *)t;
+ SetPrompt(UserList[u].us_Item,":");
+}
+
+void Cmd_EditSTable(i)
+ITEM *i;
+{
+ int u;
+ TABLE *t;
+ ITEM *j;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Carpentry ?\n");
+ return;
+ }
+ u=UserOf(i);
+ if(u==-1)
+ return;
+ j=FindSomething(i,O_PARENT(i));
+ if(j==NULL)
+ {
+ SendItem(i,"What is that ?\n");
+ return;
+ }
+ t=j->it_SubjectTable;
+ if(t==NULL)
+ {
+ t=Allocate(TABLE);
+ j->it_SubjectTable=t;
+ t->tb_Number= -1;
+ t->tb_Next=NULL;
+ t->tb_First=NULL;
+ t->tb_Name=AllocText("");
+ }
+ if(EditingBuffers[u]==NULL)
+ EditingBuffers[u]=malloc(512);
+ if(EditingBuffers[u]==NULL)
+ {
+ SendItem(i,"Sorry - no memory.\n");
+ return;
+ }
+ UserList[u].us_State=AWAIT_TEDIT;
+ UserList[u].us_UserInfo=0; /* Start Line */
+ UserList[u].us_UserPtr=(char *)t;
+ SetPrompt(UserList[u].us_Item,":");
+}
+
+void Cmd_EditDTable(i)
+ITEM *i;
+{
+ int u;
+ TABLE *t;
+ ITEM *j;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Carpentry ?\n");
+ return;
+ }
+ u=UserOf(i);
+ if(u==-1)
+ return;
+ j=FindSomething(i,O_PARENT(i));
+ if(j==NULL)
+ {
+ SendItem(i,"What is that ?\n");
+ return;
+ }
+ t=j->it_DaemonTable;
+ if(t==NULL)
+ {
+ t=Allocate(TABLE);
+ j->it_DaemonTable=t;
+ t->tb_Number= -1;
+ t->tb_Next=NULL;
+ t->tb_First=NULL;
+ t->tb_Name=AllocText("");
+ }
+ if(EditingBuffers[u]==NULL)
+ EditingBuffers[u]=malloc(512);
+ if(EditingBuffers[u]==NULL)
+ {
+ SendItem(i,"Sorry - no memory.\n");
+ return;
+ }
+ UserList[u].us_State=AWAIT_TEDIT;
+ UserList[u].us_UserInfo=0; /* Start Line */
+ UserList[u].us_UserPtr=(char *)t;
+ SetPrompt(UserList[u].us_Item,":");
+}
+
+/*
+ * Table State Drivers
+ *
+ *
+ * Editing Commands
+ *
+ * G<n> goto line n
+ * Q quit
+ * L<n>{,<m>} List range
+ * E<n>{,<m>} edit line
+ * D<n>{,<m>} delete lines
+ * I insert a line
+ * N next line
+ * P previous line
+ * B bottom
+ * T top
+ * F <v> {n} {n} [l] [l]
+ *
+ *
+ * RETURN does N
+ *
+ */
+
+
+void Tbl_Quit(u,x)
+int u;
+char *x;
+{
+ UserList[u].us_State=AWAIT_COMMAND;
+ free(EditingBuffers[u]);
+ EditingBuffers[u]=NULL;
+ SetPrompt(UserList[u].us_Item,"-}--- ");
+}
+
+void Tbl_Goto(u,x)
+int u;
+char *x; /* Arg String */
+{
+ int line=UserList[u].us_UserInfo;
+ LINE *l;
+ if(*x)
+ {
+ if(sscanf(x,"%d",&line)==0)
+ {
+ SendUser(u,"ERR> Invalid Line Number\n");
+ return;
+ }
+ }
+ if(line>=0)
+ l=FindLine((TABLE *)UserList[u].us_UserPtr,line);
+ else
+ l=NULL;
+ if(l==NULL)
+ {
+ SendUser(u,"ERR> No Such Line\n");
+ return;
+ }
+ Decompress(l,EditingBuffers[u]);
+/* Show New Line - Note G alone shows line */
+ SendUser(u,"%d %s\n",line,EditingBuffers[u]);
+ UserList[u].us_UserInfo=line;
+}
+
+void Tbl_Find(u,arg)
+int u;
+char *arg;
+{
+ short v,n1,n2;
+ short nps;
+ short ct=0;
+ char vs[32],n1s[32],n2s[32];
+ int tl= -1,bl= 99999;
+ int cl=0;
+ WLIST *w;
+ LINE *l;
+ strcpy(vs,"ANY");
+ if((nps=sscanf(arg,"%29s %29s %29s %d %d",vs,n1s,n2s,&tl,&bl))<1)
+ {
+ SendUser(u,"Unknown wordmatch.\n");
+ return;
+ }
+ if(nps<2) strcpy(n1s,"ANY");
+ if(nps<3)strcpy(n2s,"ANY");
+/* printf("%s:%s:%s\n",vs,n1s,n2s); */
+ if(stricmp(vs,"ANY")==0)
+ v=-1;
+ else
+ {
+ w=FindInList(WordList,vs,WD_VERB);
+ if(w)
+ v=w->wd_Code;
+ else
+ {
+ SendUser(u,"Unknown verb: %s.\n",vs);
+ return;
+ }
+ }
+ if(stricmp(n1s,"ANY")==0)
+ n1=-1;
+ else
+ {
+ w=FindInList(WordList,n1s,WD_NOUN);
+ if(w)
+ n1=w->wd_Code;
+ else
+ {
+ SendUser(u,"Unknown noun: %s.\n",n1s);
+ return;
+ }
+ }
+ if(stricmp(n2s,"ANY")==0)
+ n2=-1;
+ else
+ {
+ w=FindInList(WordList,n2s,WD_NOUN);
+ if(w)
+ n2=w->wd_Code;
+ else
+ {
+ SendUser(u,"Unknown noun: %s.\n",n2s);
+ return;
+ }
+ }
+ Verb=v;
+ Noun1=n1;
+ Noun2=n2;
+ l=((TABLE *)UserList[u].us_UserPtr)->tb_First;
+ while(l)
+ {
+ if(ArgMatch(l)&&cl<=bl&&cl>=tl)
+ {
+ Decompress(l,EditingBuffers[u]);
+ SendUser(u,"%d %s\n",ct,EditingBuffers[u]);
+ }
+ l=l->li_Next;
+ cl++;
+ ct++;
+ }
+}
+
+void Tbl_Top(u,arg)
+int u;
+char *arg;
+{
+ UserList[u].us_UserInfo=0;
+ Tbl_Goto(u,"");
+}
+
+long CountEntries(x)
+TABLE *x;
+{
+ long ct=0;
+ LINE *l=x->tb_First;
+ while(l)
+ {
+ ct++;
+ l=l->li_Next;
+ }
+ return(ct);
+}
+
+void Tbl_Bottom(u,arg)
+int u;
+char *arg;
+{
+ UserList[u].us_UserInfo=CountEntries((TABLE *)UserList[u].us_UserPtr)-1;
+ Tbl_Goto(u,"");
+}
+
+void Tbl_Next(u,arg)
+int u;
+char *arg;
+{
+ if(UserList[u].us_UserInfo==
+ CountEntries((TABLE *)UserList[u].us_UserPtr)-1)
+ SendUser(u,"BOTTOM\n");
+ else
+ UserList[u].us_UserInfo++;
+ Tbl_Goto(u,"");
+}
+
+void Tbl_Previous(u,arg)
+int u;
+char *arg;
+{
+ if(UserList[u].us_UserInfo)
+ UserList[u].us_UserInfo--;
+ else
+ SendUser(u,"TOP\n");
+ Tbl_Goto(u,"");
+}
+
+void Tbl_List(u,arg)
+int u;
+char *arg;
+{
+ int line,lend,n;
+ LINE *l;
+ n=sscanf(arg,"%d,%d",&line,&lend);
+ if(n==0)
+ line=UserList[u].us_UserInfo;
+ if(n==1)
+ lend=line;
+ if(lend<line)
+ return;
+ if(lend-line>39)
+ {
+ SendUser(u,"ERR> Too may lines\n");
+ return;
+ }
+ while(line<=lend)
+ {
+ if(line>=0)
+ l=FindLine((TABLE *)UserList[u].us_UserPtr,line);
+ else
+ l=NULL;
+ if(l==NULL)
+ {
+ SendUser(u,"ERR> No Such Line\n");
+ return;
+ }
+ Decompress(l,EditingBuffers[u]);
+/* Show New Line - Note G alone shows line */
+ SendUser(u,"%d %s\n",line,EditingBuffers[u]);
+ line++;
+ }
+}
+
+/* Insert Edit Delete */
+
+void Tbl_Insert(u,arg)
+int u;
+char *arg;
+{
+ LINE *n;
+ int line=UserList[u].us_UserInfo;
+ short ia=0;
+ if((*arg=='B')||(*arg=='b'))
+ {
+ ia=1;
+ arg++;
+ }
+ if(sscanf(arg,"%d",&line)!=1)
+ line=UserList[u].us_UserInfo;
+ n=NewLine((TABLE *)UserList[u].us_UserPtr,line+ia);
+ n->li_Verb=-1;
+ n->li_Noun1=-1;
+ n->li_Noun2=-1;
+ UserList[u].us_UserInfo=line+ia;
+ Tbl_Edit(u,"");
+}
+
+void Tbl_Edit(u,arg)
+int u;
+char *arg;
+{
+ int line;
+ LINE *l;
+ line=UserList[u].us_UserInfo;
+ if(sscanf(arg,"%d",&line)!=1)
+ line=UserList[u].us_UserInfo;
+ l=FindLine((TABLE *)UserList[u].us_UserPtr,line);
+ if(l==NULL)
+ {
+ SendUser(u,"No Such Line\n");
+ return;
+ }
+ UserList[u].us_UserInfo=line;
+ UserList[u].us_State=AWAIT_EDLIN;
+ Decompress(l,EditingBuffers[u]);
+ SendEdit(UserList[u].us_Item,"%s",EditingBuffers[u]);
+ SetPrompt(UserList[u].us_Item,">");
+}
+
+void Tbl_EditLine(u,line)
+int u;
+char *line;
+{
+ char x[24];
+ LINE *l=FindLine((TABLE *)
+ UserList[u].us_UserPtr,UserList[u].us_UserInfo);
+ if(strlen(line)==0)
+ {
+ SendUser(u,"Edit Abandoned\n");
+ goto ned;
+ }
+ if(l==NULL)
+ {
+ SendUser(u,"Umm, someone else has fiddled with the table!\n");
+ }
+ else
+ {
+ Decompress(l,EditingBuffers[u]);
+ WipeLine(l);
+ free((char *)l->li_Data);
+ l->li_Data=Allocate(unsigned short);
+ l->li_Data[0]=CMD_EOL;
+ LoadLineBuffer(line);
+ if(EncodeEntry(UserList[u].us_Item,l)==-1)
+ { /* Restore Old Entry */
+ LoadLineBuffer(EditingBuffers[u]);
+ EncodeEntry(UserList[u].us_Item,l);
+ goto ked;
+ }
+ }
+ned: UserList[u].us_State=AWAIT_TEDIT;
+ sprintf(x,"%d:",UserList[u].us_UserInfo);
+ SetPrompt(UserList[u].us_Item,x);
+ked: PermitInput(u);
+}
+
+void Tbl_DeleteLine(u,arg)
+int u;
+char *arg;
+{
+ int line;
+ int db=0;
+ line=UserList[u].us_UserInfo;
+ if(*arg=='B')
+ {
+ db=1;
+ arg++;
+ }
+ if(sscanf(arg,"%d",&line)==0)
+ line=UserList[u].us_UserInfo+db;
+ if(WipeDeleteLine((TABLE *)UserList[u].us_UserPtr,line+db)==-1)
+ SendUser(u,"No Such Line\n");
+ else
+ {
+ UserList[u].us_UserInfo=line;
+ Tbl_Goto(u,"");
+ }
+}
+
+void Tbl_Driver(us,command)
+int us;
+char *command;
+{
+ char x[24];
+ switch(toupper(*command))
+ {
+ case 'D':Tbl_DeleteLine(us,command+1);break;
+ case 'E':Tbl_Edit(us,command+1);
+ sprintf(x,"%d>",UserList[us].us_UserInfo);
+ goto l2;
+ case 'G':Tbl_Goto(us,command+1);break;
+ case 'B':Tbl_Bottom(us,command+1);break;
+ case 'T':Tbl_Top(us,command+1);break;
+ case 'N':Tbl_Next(us,command+1);break;
+ case 'P':Tbl_Previous(us,command+1);break;
+ case 'I':Tbl_Insert(us,command+1);break;
+ case 'L':Tbl_List(us,command+1);break;
+ case 'Q':Tbl_Quit(us,command+1);goto l1;
+ case 'F':Tbl_Find(us,command+1);break;
+ default:SendUser(us,"?\n");
+ }
+ sprintf(x,"%d:",UserList[us].us_UserInfo);
+l2: SetPrompt(UserList[us].us_Item,x);
+l1: PermitInput(us);
+}
+
+void OutLineBlock(f,s)
+FILE *f;
+char *s;
+{
+ char c;
+ while(strlen(s)>=70)
+ {
+ c=s[71];
+ s[71]=0;
+ fprintf(f,"%s+\n",s);
+ s+=71;
+ *s=c;
+ }
+ fprintf(f,"%s\n",s);
+}
+
+void Cmd_SaveTable(i)
+ITEM *i;
+{
+ int n=GetNumber();
+ TABLE *t;
+ LINE *l;
+ FILE *f;
+ char TableBuff[512];
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"I don't understand, are tables an endangered species then ?\n");
+ return;
+ }
+ if(n==-1)
+ {
+ SendItem(i,"Which table though ?\n");
+ return;
+ }
+ t=FindTable(n);
+ if(t==NULL)
+ {
+ SendItem(i,"That table doesn't exist");
+ return;
+ }
+ GetAll();
+ if(!strlen(WordBuffer))
+ {
+ SendItem(i,"Where shall I save to though ?\n");
+ return;
+ }
+ f=fopen(WordBuffer,"w");
+ if(f==NULL)
+ {
+ SendItem(i,"Can't create file '%s'.\n",WordBuffer);
+ return;
+ }
+ l=t->tb_First;
+ while(l)
+ {
+ Decompress(l,TableBuff);
+ OutLineBlock(f,TableBuff);
+ l=l->li_Next;
+ }
+ fclose(f);
+ SendItem(i,"Table Copy Dumped To File\n");
+}
+
diff --git a/TimeSched.c b/TimeSched.c
new file mode 100644
index 0000000..e226c9c
--- /dev/null
+++ b/TimeSched.c
@@ -0,0 +1,198 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * Time Scheduling Control
+ *
+ *
+ */
+
+#include "System.h"
+
+Module "Time Scheduler";
+Version "1.05";
+Author "Alan Cox";
+
+/*
+ * 1.00 Basic Scheduling
+ * 1.01 Added Facilities To Retain Defined $ME For WHEN
+ * 1.02 Fixed crash when $ME died during a WHEN
+ * 1.03 Major changes to allow for removal of event after current event
+ * during the current events execution (phew!) - took a while to
+ * find him!
+ * 1.04 Added a CountSchedules() function for profiling
+ * 1.05 Strict ansification, cleaned up time_t
+ */
+
+struct TimeEvent /* This is a private internal structure */
+{
+ unsigned long ti_Time;
+ short ti_Table;
+ ITEM *ti_Runner;
+ struct TimeEvent *ti_Next;
+};
+
+typedef struct TimeEvent EVENT;
+
+static EVENT *EventList=NULL;
+static EVENT *CurrentEvent;
+
+long CountSchedules()
+{
+ EVENT *c=EventList;
+ long ct=0;
+ while(c)
+ {
+ ct++;
+ c=c->ti_Next;
+ }
+ return(ct);
+}
+
+void AddEvent(unsigned long tm, short table)
+{
+ time_t t; /* How much software will crash when the sign
+ bit flips ? */
+ EVENT *New=Allocate(EVENT);
+ EVENT *Walk=EventList;
+ EVENT *Prev=NULL;
+ time(&t);
+ New->ti_Time=t+tm;
+ New->ti_Table=table;
+ New->ti_Runner=Me();
+ LockItem(Me());
+/*
+ * Decide Where To Add Entry
+ */
+ while(Walk)
+ {
+ if(Walk->ti_Time>=New->ti_Time)
+ {
+ if(Prev)
+ {
+ Prev->ti_Next=New;
+ New->ti_Next=Walk;
+ return;
+ }
+ else
+ {
+ New->ti_Next=EventList;
+ EventList=New;
+ return;
+ }
+ }
+ Prev=Walk;
+ Walk=Walk->ti_Next;
+ }
+ if(Prev)
+ {
+ Prev->ti_Next=New;
+ New->ti_Next=NULL;
+ }
+ else
+ {
+ EventList=New;
+ New->ti_Next=NULL;
+ }
+}
+
+static void DeleteEvent(EVENT *Ev)
+{
+/*
+ * The system takes care to avoid deleting the current event twice when the
+ * runner of that event occurs. We delete it the FIRST time only, so that
+ * we don't leave the dying person locked.
+ */
+ if(Ev==CurrentEvent)
+ CurrentEvent=NULL; /* The current event has been eaten */
+ UnlockItem(Ev->ti_Runner);
+ if(EventList==Ev)
+ {
+ EventList=Ev->ti_Next;
+ free((char *)Ev);
+ }
+ else
+ {
+ EVENT *Step=EventList;
+ if(Step==NULL)
+ Error("DeleteEvent: No Events!");
+ while(Step->ti_Next)
+ {
+ if(Step->ti_Next==Ev)
+ {
+ Step->ti_Next=Ev->ti_Next;
+ free((char *)Ev);
+ return;
+ }
+ Step=Step->ti_Next;
+ }
+ Error("DeleteEvent: Bad Event Pointer");
+ }
+}
+
+static void RunEvent(EVENT *event)
+{
+/* We keep this little routine seperate in case we need to add multiple
+ * event classes.
+ */
+
+ TABLE *tab;
+ Verb=0; /* 0 is timeout verb code in system */
+
+ tab=FindTable(event->ti_Table);
+ if(tab)
+ ExecBackground(tab,event->ti_Runner);
+}
+
+void Scheduler(void)
+{
+/* We have to be careful here, since the event queue may get changed
+ * AS we wander down it. Due to the way this routine currently works
+ * if you keep requeueing items too fast the queue may keep the
+ * scheduler running forever without returning. For the MUD system
+ * this is unlikely to cause problems.
+ */
+ time_t t;
+ EVENT *Walk=EventList;
+ time(&t);
+ while(EventList)
+ {
+ if(EventList->ti_Time>t)
+ break; /* Finished -> Since queue is time ordered */
+ Walk=EventList; /* Next event is always top */
+ CurrentEvent=Walk; /* CurrentEvent manages dying in WHEN */
+ RunEvent(Walk); /* Do the event */
+ if(CurrentEvent)
+ DeleteEvent(Walk);
+ }
+}
+
+void KillEventQueue(ITEM *i)
+{
+ EVENT *e=EventList,*ne;
+ while(e)
+ {
+ ne=e->ti_Next;
+ if(e->ti_Runner==i)
+ DeleteEvent(e);
+ e=ne;
+ }
+}
+
+void WipeEventQueue(void)
+{
+ EVENT *e=EventList,*ne;
+ while(e)
+ {
+ ne=e->ti_Next;
+ DeleteEvent(e);
+ e=ne;
+ }
+}
diff --git a/User.h b/User.h
new file mode 100644
index 0000000..f0257e6
--- /dev/null
+++ b/User.h
@@ -0,0 +1,48 @@
+#define AWAIT_LOGIN 0 /* Free slot */
+#define AWAIT_NAME 1
+#define AWAIT_PASSWORD 2
+#define AWAIT_PASSRETRY 3
+#define AWAIT_PWSET 4
+#define AWAIT_SETSEX 5
+#define AWAIT_COMMAND 0
+#define AWAIT_TEDIT 6
+#define AWAIT_EDLIN 7
+#define AWAIT_PWVERIFY 8 /* Three for password command */
+#define AWAIT_PWNEW 9
+#define AWAIT_PWVERNEW 10
+#define AWAIT_ACK 0/*11*/ /* Waiting for death event */
+#define AWAIT_OEDIT 20
+#define AWAIT_OE1 20
+#define AWAIT_OE2 21
+#define AWAIT_OE3 22
+#define AWAIT_OE4 23
+#define AWAIT_OE5 24
+#define AWAIT_OE6 25
+#define AWAIT_OE7 26
+#define AWAIT_OE8 27
+#define AWAIT_OEND 27
+#define AWAIT_EMAIL 28
+
+
+struct User_Entry
+{
+ char us_Name[MAXNAME+1]; /* Note the +1 !, finding this has caused much grief ! */
+ char us_UserName[MAXUSERID+1];
+ short us_State;
+ short us_Flags;
+ PORT *us_Port;
+ ITEM *us_Item;
+ short us_SysFlags[32];
+ short us_UserInfo; /* Two vars for state handler use */
+ char *us_UserPtr;
+ long us_Record;
+ char us_Password[8];
+#ifdef ATTACH
+ ITEM *us_RealPerson;
+#endif
+ long us_Login;
+};
+
+typedef struct User_Entry USER;
+
+#define PENT(x) (UserList[x].us_Password)
diff --git a/UserFile.c b/UserFile.c
new file mode 100644
index 0000000..72be4fd
--- /dev/null
+++ b/UserFile.c
@@ -0,0 +1,181 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+/*
+ * User Control Files
+ */
+
+#include "System.h"
+#include <netinet/in.h>
+
+Module "User File";
+Version "1.03";
+Author "Alan Cox";
+
+/*
+ * 1.00 Original very standard version
+ * 1.01 Saves userflags too!
+ * 1.02 Uses htons() htonl(), and being word aligned is more portable
+ * 1.03 Added netinet/in.h prototypes
+ */
+
+/*#define DONT_NETWORK_SWAP*/ /* Turn off use of network form */
+
+
+void SwapUFFToHost(UFF *r)
+{
+#ifndef DONT_NETWORK_SWAP
+ r->uff_Perception=ntohs(r->uff_Perception);
+ r->uff_ActorTable=ntohs(r->uff_ActorTable);
+ r->uff_ActionTable=ntohs(r->uff_ActionTable);
+ r->uff_Size=ntohs(r->uff_Size);
+ r->uff_Weight=ntohs(r->uff_Weight);
+ r->uff_Strength=ntohs(r->uff_Strength);
+ r->uff_Flags=ntohs(r->uff_Flags);
+ r->uff_Level=ntohs(r->uff_Level);
+ r->uff_Score=ntohl(r->uff_Score);
+ r->uff_Flag[0]=ntohl(r->uff_Flag[0]);
+ r->uff_Flag[1]=ntohl(r->uff_Flag[1]);
+ r->uff_Flag[2]=ntohl(r->uff_Flag[2]);
+ r->uff_Flag[3]=ntohl(r->uff_Flag[3]);
+ r->uff_Flag[4]=ntohl(r->uff_Flag[4]);
+ r->uff_Flag[5]=ntohl(r->uff_Flag[5]);
+ r->uff_Flag[6]=ntohl(r->uff_Flag[6]);
+ r->uff_Flag[7]=ntohl(r->uff_Flag[7]);
+ r->uff_Flag[8]=ntohl(r->uff_Flag[8]);
+ r->uff_Flag[9]=ntohl(r->uff_Flag[9]);
+#endif
+}
+
+void SwapUFFToNeutral(UFF *r)
+{
+#ifndef DONT_NETWORK_SWAP
+ r->uff_Perception=htons(r->uff_Perception);
+ r->uff_ActorTable=htons(r->uff_ActorTable);
+ r->uff_ActionTable=htons(r->uff_ActionTable);
+ r->uff_Size=htons(r->uff_Size);
+ r->uff_Weight=htons(r->uff_Weight);
+ r->uff_Strength=htons(r->uff_Strength);
+ r->uff_Flags=htons(r->uff_Flags);
+ r->uff_Level=htons(r->uff_Level);
+ r->uff_Score=htonl(r->uff_Score);
+ r->uff_Flag[0]=htonl(r->uff_Flag[0]);
+ r->uff_Flag[1]=htonl(r->uff_Flag[1]);
+ r->uff_Flag[2]=htonl(r->uff_Flag[2]);
+ r->uff_Flag[3]=htonl(r->uff_Flag[3]);
+ r->uff_Flag[4]=htonl(r->uff_Flag[4]);
+ r->uff_Flag[5]=htonl(r->uff_Flag[5]);
+ r->uff_Flag[6]=htonl(r->uff_Flag[6]);
+ r->uff_Flag[7]=htonl(r->uff_Flag[7]);
+ r->uff_Flag[8]=htonl(r->uff_Flag[8]);
+ r->uff_Flag[9]=htonl(r->uff_Flag[9]);
+#endif
+}
+
+int WriteRecord(FILE *f, UFF *r)
+{
+ SwapUFFToNeutral(r);
+ if(fwrite((char *)r,sizeof(UFF),1,f)!=1)
+ {
+ Log("UAF Write Failed: File May Be Corrupt!!!");
+ return(-1);
+ }
+ fflush(f);
+ return(0);
+}
+
+int ReadRecord(FILE *f, UFF *r)
+{
+ int err=fread((char *)r,sizeof(UFF),1,f);
+ if(err>0)
+ SwapUFFToHost(r);
+ return(err);
+}
+
+int FindRecord(FILE *f, int n)
+{
+ if(n==-1)
+ {
+ fseek(f,0,2); /* EOF - New Record */
+ }
+ else
+ {
+ if(fseek(f,n*sizeof(UFF),0)==-1)
+ {
+ fprintf(stderr,"FSEEK: UAF SEEK RANGE ERROR\n");
+ return(-1);
+ }
+ }
+ return(0);
+}
+
+FILE *OpenUAF(void)
+{
+ extern int errno;
+ FILE *f;
+ if((f=fopen(USERFILE,"r+"))==NULL)
+ {
+ Log("UAF Access Failed :Error %d",errno);
+ Error("UAF access failed: Cannot continue");
+ }
+ return(f);
+}
+
+void CloseUAF(FILE *f)
+{
+ fclose(f);
+}
+
+int LoadPersona(char *name, UFF *r)
+{
+ FILE *a=OpenUAF();
+ int ct=0;
+ while(ReadRecord(a,r)==1)
+ {
+ if(stricmp(name,r->uff_Name)==0)
+ {
+ CloseUAF(a);
+ return(ct);
+ }
+ ct++; /* Count records */
+ }
+ CloseUAF(a);
+ return(-1);
+}
+
+int SavePersona(UFF *r, int n)
+{
+ FILE *a=OpenUAF();
+ if(FindRecord(a,n)==-1)
+ {
+ CloseUAF(a);
+ Log("SavePersona: Record %d Does Not Exist",n);
+ Error("SavePersona: Could not find record");
+ }
+ if(WriteRecord(a,r)==-1)
+ {
+ CloseUAF(a);
+ Log("User Write Failed");
+ return(-1);
+ }
+ CloseUAF(a);
+ return(0);
+}
+
+int FindFreeRecord(void)
+{
+ UFF dummy;
+ return(LoadPersona(" ",&dummy));
+}
+
+int SaveNewPersona(UFF *r)
+{
+ return(SavePersona(r,FindFreeRecord()));
+}
diff --git a/UserVector.c b/UserVector.c
new file mode 100644
index 0000000..44d228e
--- /dev/null
+++ b/UserVector.c
@@ -0,0 +1,16 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+
+void UserVector(short a, short b, short c, ITEM *i, ITEM *j, TPTR t)
+{
+ ; /* Add user code here */
+}
diff --git a/UtilCommand.c b/UtilCommand.c
new file mode 100644
index 0000000..f6ea12b
--- /dev/null
+++ b/UtilCommand.c
@@ -0,0 +1,301 @@
+ /****************************************************************************\
+ * *
+ * C R E A T O R O F L E G E N D S *
+ * (AberMud Version 5) *
+ * *
+ * The Creator Of Legends System is (C) Copyright 1989 Alan Cox, All Rights *
+ * Reserved. *
+ * *
+ \****************************************************************************/
+
+#include "System.h"
+
+
+/*
+ * 1.00 AGC Created File
+ * 1.01 AGC Updated to cover userflag2
+ * 1.02 AGC ANSIfication
+ */
+
+Module "Utility Commands";
+Version "1.02";
+Author "Alan Cox";
+
+void Cmd_DoorPair(ITEM *i)
+{
+ char doorname[560];
+ int ad,no;
+ ITEM *door1,*door2,*from,*to;
+ GENEXIT *g1,*g2;
+ short dirn;
+ if(!ArchWizard(i))
+ {
+ SendItem(i,"Que ?\n");
+ return;
+ }
+ if(GetThing(&ad,&no)==-1)
+ {
+ SendItem(i,"There are unidentified words in your item.\n");
+ return;
+ }
+ from=FindSomething(i,O_PARENT(i));
+ if(!from)
+ {
+ SendItem(i,"I don't know where you want the exit to go from.\n");
+ return;
+ }
+ dirn=GetVerb();
+ if((dirn<99)||(dirn>110))
+ {
+ SendItem(i,"I don't recognise that direction.\n");
+ return;
+ }
+ to=FindSomething(i,O_PARENT(i));
+ if(!to)
+ {
+ SendItem(i,"I don't know where you want the exit to go to.\n");
+ return;
+ }
+ if(ad==-1)
+ sprintf(doorname,"the %s",FindWText(no,WD_NOUN));
+ else
+ sprintf(doorname,"the %s %s",FindWText(ad,WD_ADJ),
+ FindWText(no,WD_NOUN));
+ door1=CreateItem(doorname,ad,no);
+ door2=CreateItem(doorname,ad,no);
+ MakeObject(door1);
+ MakeObject(door2);
+ ObjectOf(door1)->ob_Flags=OB_FLANNEL;
+ ObjectOf(door2)->ob_Flags=OB_FLANNEL;
+ Place(door1,from);
+ Place(door2,to);
+ AddChain(door1,door2);
+ AddChain(door2,door1);
+ door1->it_ActionTable=2;
+ door2->it_ActionTable=2;
+ FreeText(ObjectOf(door1)->ob_Text[0]);
+ FreeText(ObjectOf(door1)->ob_Text[1]);
+ FreeText(ObjectOf(door2)->ob_Text[0]);
+ FreeText(ObjectOf(door2)->ob_Text[1]);
+ ObjectOf(door1)->ob_Text[0]=AllocText("The door is open. ");
+ ObjectOf(door1)->ob_Text[1]=AllocText("The door is closed. ");
+ ObjectOf(door2)->ob_Text[0]=AllocText("The door is open. ");
+ ObjectOf(door2)->ob_Text[1]=AllocText("The door is closed. ");
+ g1=(GENEXIT *)FindSub(from,KEY_GENEXIT);
+ if(!g1)
+ {
+ if(MakeGenExit(from))
+ {
+ SendItem(i,"Couldn't create GENEXIT subinfo.\n");
+ return;
+ }
+ g1=(GENEXIT *)FindSub(from,KEY_GENEXIT);
+ }
+ g2=(GENEXIT *)FindSub(to,KEY_GENEXIT);
+ if(!g2)
+ {
+ if(MakeGenExit(to))
+ {
+ SendItem(i,"Couldn't create GENEXIT subinfo.\n");
+ return;
+ }
+ g2=(GENEXIT *)FindSub(to,KEY_GENEXIT);
+ }
+ if(g1->ge_Dest[dirn-100])
+ UnlockItem(g1->ge_Dest[dirn-100]);
+ if(g2->ge_Dest[BackExit(dirn-100)])
+ UnlockItem(g2->ge_Dest[BackExit(dirn-100)]);
+ LockItem(door1);
+ LockItem(door2);
+ g1->ge_Dest[dirn-100]=door2;
+ g2->ge_Dest[BackExit(dirn-100)]=door1;
+ SendItem(i,"Exits created.\n");
+}
+
+/*
+ * Printer Commands
+ */
+
+void Cmd_ShowAllObjects(ITEM *i)
+{
+ register int ct;
+ register OBJECT *o;
+ register ITEM *b=ItemList;
+ while(b)
+ {
+ if((o=ObjectOf(b))!=NULL)
+ {
+ ShowItemData(i,b);
+ SendItem(i,"Text(0): %s\n",TextOf(o->ob_Text[0]));
+ SendItem(i,"Text(1): %s\n",TextOf(o->ob_Text[1]));
+ SendItem(i,"Text(2): %s\n",TextOf(o->ob_Text[2]));
+ SendItem(i,"Text(3): %s\n",TextOf(o->ob_Text[3]));
+ SendItem(i,"Size : %d Weight : %d\n",
+ o->ob_Size,o->ob_Weight);
+ ct=0;
+ while(ct<16)
+ {
+ if(o->ob_Flags&(1<<ct))
+ SendItem(i,"%s ",OBitName(ct));
+ else
+ if(strcmp(OBitName(ct),"{unset}"))
+ SendItem(i,"-%s ",OBitName(ct));
+ ct++;
+ }
+ SendItem(i,"\n\n-------------------------\n");
+ }
+ b=b->it_MasterNext;
+ }
+}
+
+void Cmd_ShowAllPlayers(ITEM *i)
+{
+ register int ct;
+ register PLAYER *o;
+ register ITEM *b=ItemList;
+ while(b)
+ {
+ if((o=PlayerOf(b))!=NULL)
+ {
+ ShowItemData(i,b);
+ SendItem(i,"UserKey : %d ",o->pl_UserKey);
+ SendItem(i,"Size : %d ",o->pl_Size);
+ SendItem(i,"Weight : %d \n",o->pl_Weight);
+ SendItem(i,"Strength: %d ",o->pl_Strength);
+ SendItem(i,"Level : %d ",o->pl_Level);
+ SendItem(i,"Score : %d\n",o->pl_Score);
+ ct=0;
+ while(ct<16)
+ {
+ if(o->pl_Flags&(1<<ct))
+ SendItem(i,"%s ",PBitName(ct));
+ else
+ if(strcmp(PBitName(ct),"{unset}"))
+ SendItem(i,"-%s ",PBitName(ct));
+ ct++;
+ }
+ SendItem(i,"\n\n-------------------------\n");
+
+ }
+ b=b->it_MasterNext;
+ }
+}
+
+void Cmd_ShowAllRooms(ITEM *i)
+{
+ register int ct;
+ register ROOM *r;
+ register ITEM *b=ItemList;
+ while(b)
+ {
+ if((r=RoomOf(b))!=NULL)
+ {
+ ShowItemData(i,b);
+ SendItem(i,"Short Text: %s\n",TextOf(r->rm_Short));
+ SendItem(i,"Long Text :\n%s\n",TextOf(r->rm_Long));
+ ct=0;
+ while(ct<16)
+ {
+ if(r->rm_Flags&(1<<ct))
+ SendItem(i,"%s ",RBitName(ct));
+ else
+ if(strcmp(RBitName(ct),"{unset}"))
+ SendItem(i,"-%s ",RBitName(ct));
+ ct++;
+ }
+ SendItem(i,"\n\n");
+ Cmd_Exits(i,b); /* Show exits */
+ SendItem(i,"\n\n-------------------------\n");
+ }
+ b=b->it_MasterNext;
+ }
+}
+
+int ShowItemData(ITEM *i, ITEM *b)
+{
+ register SUB *s;
+ SendItem(i,"Item: #%d %s\n",ItemNumber(LevelOf(i),b),CNameOf(b));
+ if(O_PARENT(b))
+ SendItem(i,"Parent: #%d %s\n",ItemNumber(LevelOf(i),O_PARENT(b)),
+ CNameOf(O_PARENT(b)));
+ else
+ SendItem(i,"Parent: None\n");
+ if(O_CHILDREN(b))
+ SendItem(i,"First Child: %s\n",CNameOf(O_CHILDREN(b)));
+ else
+ SendItem(i,"First Child: None\n");
+ if(O_NEXT(b))
+ SendItem(i,"Next Chained: %s\n",CNameOf(O_NEXT(b)));
+ else
+ SendItem(i,"Next Chained: None\n");
+ SendItem(i,"Adjective : %3d Noun: %3d Actor: %3d Action: %3d State: %3d\n",
+ (int)b->it_Adjective,(int)b->it_Noun,(int)b->it_ActorTable,
+ (int)b->it_ActionTable,(int)b->it_State);
+ SendItem(i,"Perception: %3d Lock: %3d Classes: %x\n",
+ (int)b->it_Perception,(int)b->it_Users,(int)b->it_Class);
+ s=b->it_Properties;
+ while(s)
+ {
+ switch(s->pr_Key)
+ {
+ case KEY_ROOM:SendItem(i,"Room");
+ break;
+ case KEY_OBJECT:SendItem(i,"Object");
+ break;
+ case KEY_PLAYER:SendItem(i,"Player");
+ break;
+ case KEY_GENEXIT:SendItem(i,"GenExit");
+ break;
+ case KEY_MSGEXIT:SendItem(i,"MsgExit");
+ break;
+ case KEY_CONDEXIT:SendItem(i,"CondExit");
+ break;
+ case KEY_CONTAINER:SendItem(i,"Container");
+ break;
+ case KEY_CHAIN:SendItem(i,"Chain -> #%d %s",
+ ItemNumber(LevelOf(i),
+ ((CHAIN *)(s))->ch_Chained),
+ CNameOf(((CHAIN *)(s))->ch_Chained));
+ break;
+ case KEY_USERFLAG:SendItem(i,"UserFlag");
+ break;
+ case KEY_BACKTRACK:SendItem(i,"BackTrack");
+ break;
+ case KEY_SNOOP:SendItem(i,"Snoop");
+ break;
+ case KEY_SNOOPBACK:
+ SendItem(i,"SnoopBack");
+ break;
+ case KEY_ROPE:
+ SendItem(i,"Rope");
+ break;
+ case KEY_DUPED:
+ SendItem(i,"Dup of %s",
+ CNameOf(((DUP *)(s))->du_Master));
+ break;
+ case KEY_TIECHAIN:
+ SendItem(i,"Tied");
+ break;
+ case KEY_INHERIT:
+ SendItem(i,"Inerit from #%d %s",
+ ItemNumber(LevelOf(i),
+ ((INHERIT *)(s))->in_Master),
+ CNameOf(((INHERIT *)(s))->in_Master));
+ break;
+ case KEY_INOUTHERE:
+ SendItem(i,"InOutHere");
+ break;
+ case KEY_USERTEXT:
+ SendItem(i,"UserText");
+ break;
+ case KEY_USERFLAG2:
+ SendItem(i,"UserFlag2");
+ break;
+ default:
+ SendItem(i,"Unknown (%d)",s->pr_Key);
+ }
+ SendItem(i,"\n");
+ s=s->pr_Next;
+ }
+ return(0);
+}
diff --git a/ValidLogin.c b/ValidLogin.c
new file mode 100644
index 0000000..5624fd2
--- /dev/null
+++ b/ValidLogin.c
@@ -0,0 +1,26 @@
+/*
+ * This function should be customised according to the actual
+ * load parameters you wish to enforce
+ */
+
+#include <time.h>
+#include <stdio.h>
+
+int MaxSlot(void)
+{
+ long t;
+ struct tm *tv;
+ time(&t);
+ tv=localtime(&t);
+ if(tv==NULL)
+ return(0);
+ if(tv->tm_hour<7)
+ return(20);
+ if(tv->tm_hour<21)
+ return(12);
+ if(tv->tm_hour<23)
+ return(16);
+ if(tv->tm_hour==23)
+ return(20);
+ return(8);
+}