/* Haktar V1.6
   The reality simulation language interpreter.
°ª° (c) by Guido Wegener      Ma.1992

*/

/* Do not change the following line! */
char *serie="Fish Discs";

/*
   Compile with Aztec C 5.0b
     simply by calling : Caos Haktar.c
   CaoS'echo "Compile Time : about 3.30 minutes"'
   CaoS'cc Haktar.c -ff -m0c -m0d -pb -pe -ps -q0f -sn -sp -su -wa -wp -wr'
   CaoS'cc HaktarExt.c -ff -m0c -m0d -pb -pe -ps -q0f -sn -sp -su -wa -wp -wr'
   CaoS'ln Haktar.o HaktarExt.o -lc16'

   Isn't it lovely ???
   
   I scream for you scream;
   we all scream for ice cream.
*/

#define SHOWPIC (char)0
#define SHOWSUB (char)1
#define SHOWFACE (char)2
#define VALIDCOL 26
#define TURNED 1
#define KEEP   0

char crapt[][80]=
 {
  "             °ª° Hi guys ! °ª°",
  "Nice to meet you here in my little piece of art !",
  "You just activated the crap text, which is a substitude for a scroller,",
  "because I like scrollers, but it is a bit complicated to code one in C,",
  "so I'll have to do it this way...",
  "This text was mainly written while waiting for Aztec C finishing compiling.",
  " ",
  "I'm a lumberjack and I'm OK...",
  "But can a bee be said to be or not to be an entire bee ?",
  "How to switch your Swiss swatch watch on :",
  "Switch the switch of your Swiss swatch watch and watch your",
  "Swiss swatch watch switching on.",
  " ",
  "Please send some letters'n'disks to :",
  "  Guido Wegener",
  "  Eisenacher Str.2",
  "  D-5300 Bonn 1",
  "  Germany",
  "I NEED your feedback !",
  " ",
  "Let's talk about me :",
  " Name : Guido Wegener",
  " Pseudo : Wonko the Sane",
  " Age : 20 (born 11.10.1971)",
  " Job: Zivildienst (substitute for the army)",
  " Computers : AMIGA 500 + 1.5MB + 2nd Drive + A590 HD + 1084S + CP-80",
  "             Gameboy + Golf + Bomberboy + Tetris (LV17;309013)",
  "              + Chessmaster + Final Fantasy + R-Type",
  "             C-64 + Drive + MagicFormel",
  "             ZX81 (broken)",
  " Other Hobbies : Reading (H.P.Lovecraft,E.A.Poe) ; Fantasy Roleplaying",
  " Languages : C,German,English,(Basic(,Assembler))",
  " Music : Eurithmics,Suzanne Vega,Public Enemy",
  " ",
  "Hey, you stupid dudes out there, this whole Haktar-stuff is getting a bit of",
  "a mess. If you look into the listing, you will find lots of senseless lines...",
  "Guys, you don't know about programming such a silly prog !",
  "I can't imagine how I could have managed it without my Aztec C 5.0 and the",
  "harddisk. The source is longer than 67kB and too much messed up and complex to",
  "be cut into pieces and compiled seperately.",
  " ",
  "Hey, you Germans out there !",
  "Do you know 'Computer-Flohmarkt' ?",
  "I just started to talk some crabs in there, buy it and read it !",
  " ",
  "What about some greetings and messages ?",
  "Eric Hambuch: Thanx for moral support, good ideas and perfect bug-reports!",
  "              Your tools for Haktar are great.",
  "Aragorn : What say you now ? (Wat sagst nu ?)",
  "          Thanx for TRYING to write a clean file requester...",
  "Cucumber : Isn't this better than artificial intelligence ?",
  "           Ooops, sorry for your computer. May it rest in pieces...",
  "Rat : Never forget that there is a REALITY out there, not only fantasy.",
  "HCF : Make adventures, not war !",
  "Neuromancer : Thanks for using Haktar.",
  "X-Tension : Try to write Haktar in assembler.",
  "AmigAmazed : Labern kann man auch hier...",
  "Harald Holtmann (is it spelled correctly ?) : What did you write in the last",
  "  year ? Is the apprentice getting better than the master ???",
  "Mike Shapiro : You don't know me, but I am the one (or are there others?) who",
  "  played your Zerg V1.0. I like your humor, so pleeeaase write a funny",
  "  adventure for Haktar. What a pity that you will never read this Msg !",
  "Lutz : No pseudo ? Will you ever learn the basic principles of society ?",
  "       I saw your 'Hawk'-piggy. Real good painting!",
  "Madison : Realschule",
  "Achim Hauck : This little piece of art should be even better than that old",
  "              stuff of mine that you kindly released.",
  "Alexander Carbin: T.u.C. is great!", 
  "Tim Zylinski: Hi!",
  "Martin Hammers: Sorry for the delay of Haktar!",
  " ",
  "Simple Greetings :",
  "Dungeon Master Christoph (sorry),Fred Fish,Baumann,Warlord,Ludwig Rotstift,",
  "all other members of T.u.C.",
  "Special Greez to all the lamers of the world !",
  " ",
  "°ª°  :-)  <v:  (^:=  °º°  ;-)  `ª'  B-)  :-}  :-D  C-:  :-O  ß-)",
  " ",
  "I should dedicate this master piece to someone, shouldn't I ?",
  "The only person who could be made responsible for this all will never",
  "read it...  (and it isn't Aragorn, the old slavedriver !)",
  "Haktar should be dedicated to the person that helped me to get through",
  "the difficult times of writing the complex logic elements of Haktar.",
  "But why didicate a proggy to a non-computerfreak like Beate?",
  "It seems to be more correct to dedicate it",
  "To All The Lamers In All Nations And Abdul Alhazred !",
  " ",
  "And now some recommendations :",
  "Athors : Stephen King (for the young ones), H.P.Lovecraft (the best, start with",
  "         'The Case Of Charles Dexter War'), Edgar Allan Poe, Douglas Adams",
  "Comics : Walter Moers, Garfield (for the youth), Asterix, Hermann der User",
  "Music  : Eurithmics (1984), Suzanne Vega, ZZ Top, Public Enemy, Ravel (Bolero),",
  "         Rocky Horror Picture Show, War of the Worlds",
  "Games  : Imperium, Tower of Babel",
  "Pubs (Bonn) : Pendel, Lampe",
  "Places to visit all over the world : Roma (Spanish staircase on Sunday",
  "         afternoon), eastern point of the French coast (Normandie)",
  "Languages to learn : C, C, C, English, Basic, Pascal, Eumel and Assembler",
  "Magazines : Computer-Flohmarkt, Amiga, Kickstart",
  "Things to buy : Gameboy, 'Qigong' Chinese Healthy Iron Balls, Funnyfrisch",
  "         Chipsfrisch, Pullmoll, Junghans Mega 1",
  "Drinks : Drambuie, Ouzo, Baileys, Batida de Coco, Ginger Ale, Kristall Weizen",
  "Disks  : Verbatims seem to be safe.",
  "Movies : Rocky Horror Picture Show, Dark Star, Little Shop of Horrors, all",
  "         movies by Monty Python and Steve Martin, Koyaanisqatsi",
  " ",
  "Do you own a Rubik's Magic toy ?",
  "Try to build this fantastic figure :  _",
  "A small ashlar with two foots.       |_|/",
  "                                       /",
  "Every day in every way I'm getting better and better.",
  "And Haktar is getting better, too. Every day I find a new bug !!!",
  "I hope that this version is at least playable...",
  " ",
  "Is there a gun in your pocket or are you just pleased to see me ?",
  " ",
  "Hey, HCF, thanx for some good ideas, and sorry for those I did not use.",
  "The keyboard actions, cprint and some stylish matters of the ACTROOM",
  "display were inspirated by him. I think that your adventure will be great.",
  "Hope you like the new style the Haktar SCREEN(!).",
  " ",
  "Aragorn, you want to write an adventure for Haktar ? I hope that you",
  "will survive the shock of seeing variables and a pseudo-block-orientated",
  "language, I do not think that you are used to such features, maybe I will",
  "write a version that you can program in hex-dumps.",
  " ",
  "Ph'nglui mglw'nafh Cthulhu R'lyeh wgah'nagl fhtagn.",
  "That is not dead which can eternal lie.",
  "And with strange eons even death may die.",
  "Last words of a blind man : 'Did I miss the bus ?'",
  "Reality is for people that can't manage drugs.",
  "I. 1 2 B.A.B. 4 A. 2.     or      I12BAB4A2.",
  " ",
  "Hey guys! I would like to hear from you.",
  "Send ideas, own stuff, money, bug reports or just letters to me!",
  " ",
  "Bene Valete",
  ""
 };

#include <pragmas.h>
#include <functions.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libraries/dosextens.h>
#include <libraries/diskfont.h>
#include <exec/types.h>
#include <exec/memory.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <graphics/gfx.h>
#include <graphics/gfxbase.h>
#include <graphics/text.h>
#include <workbench/startup.h>

typedef long MEBOOL;

#define ATINTEGER (UBYTE)0 /* +no number -> stop */
#define ATWORD    (UBYTE)1 /* +' ' as stops */
#define ATNAME    (UBYTE)2 /* +[|], as stops */
#define ATSTRING  (UBYTE)3 /* '\n' and · as stops, keep leading spaces */
#define ATLONG    (UBYTE)128 /* full 80 chars */
#define ATMEDIUM  (UBYTE)192 /* only 79 chars */
#define ATSHORT   (UBYTE)64  /* only 77 chars */
#define ATXL      (UBYTE)0   /* 999999...999 chars and more */

#define TEXTGAD 1
#define PROPGAD 2
#define UPGAD   3
#define DOWNGAD 4
#define STANDBASIS 100
#define LISTBASIS 200
#define INPGAD 301

#define LISTANZ 9

#define JIDLE 0
#define JCITEM 1
#define JCROOMDO 2
#define JCINVITEM 3
#define JCIIDO 4
#define JCITEMDO 5
#define JINPHEAD 6
#define JDEAD 7
#define JINPLOAD 8
#define JINPSAVE 9
#define JINPSTART 10
#define JCHOOSE 11

long RangeRand(long value);
extern void showilbm(char *mem,ULONG size,int timelimit,char mode);

/* ARP stuff */

void FileRequest(struct FileRequester *fr);
#pragma amicall(ArpBase,294,FileRequest(a0))

void *ArpBase=NULL; /* Sorry guys, but I do not have any literature about the ARP structure. */

struct FileRequester
 {
  char *Hail;
  char *File;
  char *Dir;
  void *Window;
  UBYTE FuncFlags;
  UBYTE Reserved1;
  void *Function;
  ULONG Reserved;
 };

struct FileRequester fr=
 {
  "Please choose a file.",
  "\0                                    ",
  "\0                                    ",
  NULL,
  0,
  0,
  NULL,
  0
 };

/* end of ARP */

struct DOSBase *DOSBase=NULL,*DOSBASE;
struct IntuitionBase *IntuitionBase=NULL,*INTUITIONBASE;
struct GfxBase *GfxBase=NULL,*GFXBASE;
struct Library *DiskfontBase=NULL;

UBYTE job=JDEAD;
char actitem[81]="";
char docop[81]="";

char inv[]="";
char mark[]="HakSaveV1";

struct item
 {
  struct item *nextitem;
  char name[81];
 };

struct raum
 {
  struct raum *nextraum;
  char name[81];
  struct item *firstitem;
 };

struct var
 {
  struct var *nextvar;
  char name[81];
  long val;
 };

struct charakter
 {
  char headpath[81];
  char realheadpath[81];
  char raum[81];
  char outraum[81];
  char lastinput[81];
  char getphrase[81];
  char nogetphrase[81];
  char dropphrase[81];
  char headfile[81];
  long int maxweight;
  long int weight;
  long int time;
  struct item *firstflag;
  struct var  *firstvar;
  struct raum *firstroom;
  struct raum *firstmultifile;
  char *eachmovemem;
  long eachmovesize;
  char eachmovename[81];
  char fontname[81];
  char interface[81];
  char subpic[81];
  BOOL locflag;
 };

struct charakter pc;
struct charakter npc=
 {
  "","","","","","Take §.","Too heavy !","Drop §.","",0,0,0,NULL,NULL,NULL,NULL,NULL,NULL,0,"","","",TRUE
 };

char lastgetphrase[81]="";
char lastdropphrase[81]="";

struct TextFont *myfont=NULL,*xfont=NULL;
struct TextAttr mytstyle=   /* I hate the guys that use the big topaz ! */
 {
  (STRPTR)"topaz.font",
  8,
  FS_NORMAL,
  FPF_ROMFONT | FPF_DESIGNED
 };
struct TextAttr xtstyle=
 {
  (STRPTR)pc.fontname,
  8,
  FS_NORMAL,
  FPF_DISKFONT | FPF_DESIGNED
 };

struct IntuiText ITDummy={1,0,JAM1,0,0,&mytstyle,NULL,NULL};
int outlines=0;
int outmode=0;
struct item *displist=NULL;
BOOL freedisplist=FALSE,donotkilllist=FALSE;

int lpos,lanz,apos;

/* texts */

char instrt[][80]=
 {
  "Somewhere on the right side of this box there is an arrow. Click on it",
  "whenever you are ready to read the next paragraph of this (or any other)",
  "text. You may also click the continue gadget.",
  "Haktar has an unusual way of letting the user enter commands :",
  "It displays all possible things the hero can do in three lists.",
  "Click on the ROOM gadget to get a list of the possible actions that concern",
  "the room. The gadgets ITEMS and INVENTORY will display sublists of the items",
  "in the room and in your hands. Choose one of these to get a list of actions.",
  "How to start an adventure :",
  "Use 'Start...' in the menu and choose the name of the adventure you want to",
  "play to start an adventure. You should be able to reach Example.hhf,",
  "MyRoom.hhf, AltesHaus.hhf, Beispiel.hhf.",
  "Have fun !",
  ""
 };

char aboutt[][80]=
 {
  " ",
  "Haktar and its related files are Freeware. You may copy the package, but",
  "you must obey the following rules if you SELL copies of it.",
  "1. You may only sell a version of Haktar and its related files on an",
  "   unchanged copy of the disc it was published on.",
  "2. The name of the disc or catalog a given version of Haktar was published",
  "   on is printed on the screen every time you start Haktar.",
  "3. You must obey the copy conditions of the disc Haktar was published on.",
  " ",
  "Haktar was written using Manx AztecC 5.0b, which is GREAT !",
  " ",
  "Enjoy the worlds of Haktar !",
  " °ª°   Guido Wegener  (Wonko the Sane)",
  "       Eisenacher Str. 2",
  "       D-5300 Bonn 1",
  "       West-Germany",
  ""
 };

/* input stuff */

struct StringInfo inpgadinf=
 {
  (UBYTE *)"\0                                                                                ",
  NULL,
  0,
  81,
  0,
  0,0,0,0,0,0,0,NULL
 };

struct Gadget inpgad=
 {
  NULL,
  1,1,632,9,
  GADGHCOMP,ENDGADGET | RELVERIFY,
  STRGADGET | REQGADGET,
  NULL,NULL,NULL,0,
  (APTR)&inpgadinf,
  INPGAD,
  NULL
 };

struct Requester inpreq=
 {
  NULL,
  3,178,634,12,
  0,0,
  &inpgad,
  NULL,NULL,0,
  3,
  NULL,{NULL},NULL,NULL,{NULL}
 };

/* reqtexts */

struct IntuiText reqtexts[]=
 {
  {2,1,JAM1,47,5,&mytstyle,(UBYTE *)"Really Quit ?",NULL},
  {0,1,JAM1,3,4,&mytstyle,(UBYTE *)"  Yes ",NULL},
  {0,1,JAM1,7,4,&mytstyle,(UBYTE *)"Cancel",NULL}
 };

/* projmenu */

struct IntuiText projtext[]=
 {
  {2,1,JAM2,2,1,&mytstyle,(UBYTE *)"Restart",NULL},
  {2,1,JAM2,2,1,&mytstyle,(UBYTE *)"Start...",NULL},
  {2,1,JAM2,2,1,&mytstyle,(UBYTE *)"Load...",NULL},
  {2,1,JAM2,2,1,&mytstyle,(UBYTE *)"Save...",NULL},
  {2,1,JAM2,2,1,&mytstyle,(UBYTE *)"About",NULL},
  {2,1,JAM2,2,1,&mytstyle,(UBYTE *)"Crap",NULL},
  {2,1,JAM2,2,1,&mytstyle,(UBYTE *)"Short Instructions",NULL},
  {2,1,JAM2,2,1,&mytstyle,(UBYTE *)"Quit",NULL}
 };

struct MenuItem projitem[]=
 {
  {&projitem[1],0,0,149,9,ITEMTEXT|ITEMENABLED|HIGHCOMP,0,
    (APTR)&projtext[0],NULL,0,NULL,MENUNULL},
  {&projitem[2],0,10,149,9,ITEMTEXT|ITEMENABLED|HIGHCOMP,0,
    (APTR)&projtext[1],NULL,0,NULL,MENUNULL},
  {&projitem[3],0,20,149,9,ITEMTEXT|ITEMENABLED|HIGHCOMP,0,
    (APTR)&projtext[2],NULL,0,NULL,MENUNULL},
  {&projitem[4],0,30,149,9,ITEMTEXT|ITEMENABLED|HIGHCOMP,0,
    (APTR)&projtext[3],NULL,0,NULL,MENUNULL},
  {&projitem[5],0,40,149,9,ITEMTEXT|ITEMENABLED|HIGHCOMP,0,
    (APTR)&projtext[4],NULL,0,NULL,MENUNULL},
  {&projitem[6],0,50,149,9,ITEMTEXT|ITEMENABLED|HIGHCOMP,0,
    (APTR)&projtext[5],NULL,0,NULL,MENUNULL},
  {&projitem[7],0,60,149,9,ITEMTEXT|ITEMENABLED|HIGHCOMP,0,
    (APTR)&projtext[6],NULL,0,NULL,MENUNULL},
  {NULL        ,0,75,149,9,ITEMTEXT|ITEMENABLED|HIGHCOMP,0,
    (APTR)&projtext[7],NULL,0,NULL,MENUNULL}
 };

/* sysitem */

struct IntuiText systext[]=
 {
  {2,1,JAM2,2,1,&mytstyle,(UBYTE *)"Headpath...",NULL},
  {2,1,JAM2,2,1,&mytstyle,(UBYTE *)"Restore Headpath",NULL}
 };

struct MenuItem sysitem[]=
 {
  {&sysitem[1],0,0,100,9,ITEMTEXT|ITEMENABLED|HIGHCOMP,0,
    (APTR)&systext[0],NULL,0,NULL,MENUNULL},
  {NULL,0,10,140,9,ITEMTEXT|ITEMENABLED|HIGHCOMP,0,
    (APTR)&systext[1],NULL,0,NULL,MENUNULL}
 };

/* menu */

struct Menu menu[]=
 {
  {&menu[1],0,0,103,0,MENUENABLED,"Project",projitem},
  {NULL,100,0,143,0,MENUENABLED,"System",sysitem}
 };

/* downgad */

struct Gadget downgad=
 {
  NULL,
  5,76,11,9,
  GADGHCOMP,
  RELVERIFY,
  BOOLGADGET,
  NULL,
  NULL,
  NULL,
  0,
  NULL,
  DOWNGAD,
  NULL
 };

/* upgad */

struct Gadget upgad=
 {
  &downgad,
  5,12,11,9,
  GADGHCOMP,
  RELVERIFY,
  BOOLGADGET,
  NULL,
  NULL,
  NULL,
  0,
  NULL,
  UPGAD,
  NULL
 };

/* propgad */

struct PropInfo propinfo=
 {
  AUTOKNOB | FREEVERT | PROPBORDERLESS,
  -1,10,
  -1,10000
 };

struct Image image;

struct Gadget propgad=
 {
  &upgad,
  5,23,
  11,51,
  0,
  RELVERIFY | GADGIMMEDIATE,
  PROPGADGET,
  (APTR)&image,
  NULL,NULL,0,
  (APTR)&propinfo,
  PROPGAD,NULL
 };

/* listgad */

struct Gadget listgad[LISTANZ]=
 {{
  NULL,
  17,13,618,8,
  GADGHCOMP,
  RELVERIFY,
  BOOLGADGET,
  NULL,
  NULL,
  NULL,
  0,
  NULL,
  LISTBASIS,
  NULL
 }};

/* standgad */

char standadj[6]={34,29,14,17,40,26};
char standnames[6][10]=
 {
  "ROOM",
  "ITEMS",
  "INVENTORY",
  "CONTINUE",
  "OK",
  "CANCEL"
 };

struct IntuiText standitex[6]={1,0,JAM1,0,1,&mytstyle,(UBYTE *)standnames[0],NULL};

SHORT standcor[]={0,0, 101,0, 101,10, 0,10, 0,0};
struct Border standbor={-1,-1,1,0,JAM1,5,standcor,NULL};

struct Gadget standgad[6]=
 {{
  NULL,
  7,91,100,9,
  GADGHCOMP,
  RELVERIFY,
  BOOLGADGET,
  (APTR)&standbor,
  NULL,
  standitex,
  0,
  NULL,
  STANDBASIS,
  NULL
 }};

/* textgad */

SHORT textcor2[]={0,0, 637,0, 637,84, 0,84, 0,0};
struct Border textbor2={-3,-2,3,0,JAM1,5,textcor2,NULL};
SHORT textcor[]={0,0, 635,0, 635,82, 0,82, 0,0};
struct Border textbor={-2,-1,1,0,JAM1,5,textcor,&textbor2};

struct Gadget textgad=
 {
  standgad,
  4,106,632,81,
  GADGHNONE,
  RELVERIFY,
  BOOLGADGET,
  (APTR)&textbor,
  NULL,
  NULL,
  0,
  NULL,
  TEXTGAD,
  NULL
 };

/* Window */

struct RastPort *rp;
struct Window *MyWindow=NULL;
struct NewWindow MyNewWindow=
 {
  0,10,640,190,
  -1,-1,
  VANILLAKEY | REQSET | GADGETUP | MENUPICK | CLOSEWINDOW | GADGETDOWN,
  WINDOWCLOSE | SMART_REFRESH | ACTIVATE,
  NULL,  /*&textgad,*/
  NULL,
  (UBYTE *)"Haktar V1.6 by Guido Wegener",
  NULL,
  NULL,
  -1,-1,-1,-1,
  CUSTOMSCREEN
 };

/* Screen */

struct Screen *MyScreen=NULL;
struct NewScreen MyNewScreen=
 {
  0,0,640,200,2,
  2,1,
  HIRES,
  CUSTOMSCREEN,
  &mytstyle,
  (UBYTE *)"Haktar V1.6 by Guido Wegener",
  NULL,NULL
 };

UBYTE scol[]=
 {
  7,7,7,
  15,15,15,
  0,0,0,
  15,6,7,
  7,7,7,
  15,15,15,
  0,0,0,
  15,6,7,
  7,7,7,
  15,15,15,
  0,0,0,
  15,6,7,
  7,7,7,
  15,15,15,
  0,0,0,
  15,6,7,
 };

BOOL wbstart;
char choices[][81]={"","","","","","","","","",""};
int clevel=-1;
int printdum;
struct item *clist=NULL;
BOOL cprob=FALSE;
struct IntuiMessage *msg=NULL;
struct Screen *subscreen=NULL;
struct Window *subwindow=NULL;
char s[81];
BOOL doactives;

void wmain(void);
void wope(void);
void wclo(void);
void gadup(struct IntuiMessage *msg,USHORT id);
BOOL menupick(struct IntuiMessage *msg);
void keyboard(struct IntuiMessage *msg);
void outp(char *text);
void warn(char *text);
void about(void);
void crap(void);
void instr(void);
void mwait(BOOL force);
void drawar(void); /* draws the cont arrow */
void linit(struct item *list,int clear);  /* init list */
void ldisp(long refresh);       /* refresh list (pos) */
void iteml(struct item *firstitem); /* init item list */
void initpc(void);

void ope(void); /* open everything, init even more */
void clos(char *text); /* close and free and unlock everything */
void analyse(char *file,struct item **ilist,struct item **dlist,char *doer,struct item **mflist);
  /* Load file, execute it if everything is NULL.
     If file  == NULL : use eachmovemem.
     If ilist != NULL : add all items to the list pointing to.
     If dlist != NULL : add all DOs to the list pointing to.
     If doer  != NULL : only execute the specific #do.
     If mflist!= NULL : add all things to the list pointing to.
  */
void ueberlesenklam(char **act); /* Move the act-pointer to the next ].*/
void ueberlesenstri(char **act); /* Move act to the next |.*/
void readarg(char **act,char *arg,UBYTE flags); /* Put one arguement into arg and move act.*/
void clearlist(struct item *list); /* Frees the memory of an item-list.*/
void load(char *fn);
void save(char *fn);
void freeem(void);
void mcreate(char *itm,char *room);
void mgone(char *itm,char *room);
BOOL mifitemin(char *itm,char *room);
void mixme(char *dest,char *string,char *replacer); /* replace § by replacer */
void lowcase(char *string); /* lower case string */
struct var *findvar(char *var);
char *loaditem(char *name,long *length);
void savelist(struct FileHandle *fh,void *point,size_t size);
void loadlist(struct FileHandle *fh,void **link,size_t size);
void fnamecpy(char *dest,char *sour); /* strcpy with / stop */
void reqinp(int jobflag); /* inpreq ; job=jobflag */
void headex(void);
void propey(struct IntuiMessage *msg);
void turnover(MEBOOL eachmoved);
void iffi(char **act,BOOL result);
BOOL hyperif(char *iftype,char **act);
void ueberklamauf(char **act);
void dechoose(void);
void getfilename(char *name);
void msimpleface(void);
void style(void);
void restyle(void);
void closesub(void);

void headpath(char **act);  /* N    path for everything */
void maxweight(char **act); /* I    maximum weight to carry */
void addweight(char **act); /* I    add weight of item */
void ifweight(char **act);  /* I    if item can be carried */
void print(char **act);     /* S    display line */
void textwait(char **act);      /*      wait for continue */
void create(char **act);    /* NN   create item in room {or pocket} */
void gone(char **act);      /* NN   delete item in room {or pocket} */
void ifflag(char **act);    /* NBB  if flag is set */
void setflag(char **act);   /* N    set flag */
void delflag(char **act);   /* N    unset flag */
void showpic(char **act);   /* NI   display IFF-file for I*50 sec. */
void showpicsub(char **act);/* NI   display IFF-file for I*50 sec. */
void settime(char **act);   /* I    set time */
void addtime(char **act);   /* I    add to time */
void ifitemin(char **act);  /* NNBB if item is in room {or pocket} */
void sys(char **act);       /* S    open slot for hard-routines */
void dead(char **act);      /*      game over */
void input(char **act);     /*      read a string as last input */
void move(char **act);      /* NNN  move item from room {o.p.} to r.{op} */
void fdo(char **act,struct item **dlist,char *doer); /* SB  one of the do choices */
void ifinput(char **act);   /* NBB  if the last input equals $ */
void iftime(char **act);    /* IIBB if time is between values */
void items(char **act,struct item **ilist);     /* n*N  list of items in room */
void ifin(char **act);      /* NBB  if character is in room */
void go(char **act,MEBOOL eachmoved);  /* N    move character to room */
void rem(char **act);       /* S    remark */
void execute(char **act);   /* N    file will be executed */
void handle(char **act,char *filen,struct item **dlist,char *doer); /* I  standard get/drop procedure; int=weight */
void getphrase(char **act); /* S    text to take | §=actname*/
void dropphrase(char **act);/* S    text to drop */
void cantgetphrase(char **act);/*S  text id too heavy */
void setvar(char **act);    /* NI   set var to */
void addvar(char **act);    /* NI   adds const to var */
void ifvar(char **act);     /* NIIBB if var between */
void eachmove(char **act);  /* N    file is to be executed each turn */
void multi(char **act);     /* n*N  files include several things */
void thing(char **act,struct item **firstinfile,char *thingy);     /* NB   thing in file */
void printfile(char **act); /* N    prints the file */
void ifchance(char **act);  /* IBB  if rnd*100+1<I */
void doscall(char **act);   /* S    execute S like CLI */
void cprint(char **act);    /* S    centred print */
void font(char **act);      /* S    change font */
void noautowait(char **act);/*      like clicking cancel */
void printvar(char **act);  /* NIN  print value of var between texts */
void choose(char **act);    /* NB   display/make choice */
void startchoose(char **act);
void endchoose(char **act);
void locoff(char **act);
void locon(char **act);
void simpleface(char **act);/* N    simple change of user interface */
void storevars(char **act); /* Nn*N stores variables and values in file */
void getvars(char **act);   /* N    loads   " */

void main(int argc,char *argv[])
 {
  struct WBStartup *wbs;
  struct WBArg *wba;
  int i;
  LONG olddir;

  wbstart=!argc;
  ope();
  linit(NULL,KEEP);
  warn("                     Haktar V1.6 by Guido Wegener");
  warn(NULL);
  outp("Haktar is a reality simulation language interpreter.");
  outp("In other words : an adventure construction tool.");
  outp("From the menu you can get a VERY short guide of how to use Haktar.");
  outp(NULL);
  outp("This version of Haktar may only be published on");
  outlines=0;
  warn(s);
  outp("If you bought this version on a different disc, then PLEASE inform me!");
  mwait((BOOL)FALSE);
  for(i=0;i<10;i++) {outp(NULL);outlines=0;}
  if(wbstart)
   {
    wbs=(struct WBStartup *)argv;
    if(wbs->sm_NumArgs>2)
     {
      warn("Did you shift-klick ?");
      warn("Please try to start me like a normal user !");
     }
    if(wbs->sm_NumArgs==2)
     {
      wba=wbs->sm_ArgList;
      strncpy(pc.headfile,(char *)wba[1].wa_Name,(size_t)80);
      pc.headfile[80]=0;
      job=JIDLE;
      if(wba->wa_Lock) olddir=CurrentDir(wba->wa_Lock);
      doactives=TRUE;
      analyse(pc.headfile,NULL,NULL,NULL,NULL);
      if(wba->wa_Lock) CurrentDir(olddir);
     }
   }
  else if(argc==2)
   {
    strncpy(pc.headfile,argv[1],(size_t)80);
    pc.headfile[80]=0;
    job=JIDLE;
    doactives=TRUE;
    analyse(pc.headfile,NULL,NULL,NULL,NULL);
   }
  wmain();
  clos(NULL);
 }

/* -------------------------------------------------------------------- */

void wmain()
 {
  ULONG class;
  BOOL cont;
  
  cont=(printdum+16==VALIDCOL);
  while(cont)
   {
    outlines=0;
    outmode=0;
    Wait(1L<<MyWindow->UserPort->mp_SigBit);
    while(msg=(struct IntuiMessage *)GetMsg(MyWindow->UserPort))
     {
      donotkilllist=FALSE;
      class=msg->Class;
      switch(class)
       {
        case CLOSEWINDOW : cont=FALSE;break;
        case GADGETUP    : if(job!=JDEAD) gadup(msg,0);break;
        case MENUPICK    : cont=menupick(msg);break;
        case GADGETDOWN  : propey(msg);msg=NULL;break;
        case REQSET      : ActivateGadget(&inpgad,MyWindow,&inpreq);break;
        case VANILLAKEY  : keyboard(msg);break;
        default : warn("Unknown Messsage Class !");break;
       }
      if(msg)
       {
        ReplyMsg((struct Message *)msg);
        msg=NULL;
       }
     }
    if(!cont) cont=!AutoRequest(MyWindow,&reqtexts[0],&reqtexts[1],
                                &reqtexts[2],0L,0L,220L,50L);
   }
 }

void keyboard(struct IntuiMessage *msg)
 {
  int c;
  
  c=msg->Code;
  if(c>='1' && c<='9') gadup(NULL,LISTBASIS+c-'1');
  else
    switch(c)
     {
      case 'r' : gadup(NULL,STANDBASIS+0);break;
      case ' ' : gadup(NULL,STANDBASIS+1);break;
      case 'i' : gadup(NULL,STANDBASIS+1);break;
      case 'n' : gadup(NULL,STANDBASIS+2);break;
      case 'v' : gadup(NULL,STANDBASIS+2);break;
      case 'u' : gadup(NULL,UPGAD);break;
      case 'd' : gadup(NULL,DOWNGAD);break;
      default  : DisplayBeep(NULL);
     }
 }

BOOL menupick(struct IntuiMessage *msg)
 {
  USHORT select;
  BOOL cont;
  char buf[80];
  int i;
  
  cont=TRUE;
  select=msg->Code;
  switch(MENUNUM(select))
   {
    case 0 : switch(ITEMNUM(select))
              {
               case 0 : pc.raum[0]=0;
                        job=JDEAD;
                        linit(NULL,TURNED);
                        for(i=0;i<9;i++) {outp(NULL);outlines=0;}
                        freeem();
                        initpc();
                        pc.firstroom=AllocMem(sizeof(struct raum),MEMF_CLEAR);
                        if(!pc.firstroom) clos("No memory for inventory !");
                        *((pc.firstroom)->name)=0;
                        job=JIDLE;
                        doactives=TRUE;
                        analyse(pc.headfile,NULL,NULL,NULL,NULL);
                        if(pc.locflag) SetWindowTitles(MyWindow,pc.outraum,(char *)-1);
                        break;
               case 1 : reqinp(JINPSTART);break;
               case 2 : reqinp(JINPLOAD);break;
               case 3 : reqinp(JINPSAVE);break;
               case 4 : about();break;
               case 5 : crap();break;
               case 6 : instr();break;
               case 7 : cont=FALSE;break;
               default: warn("Unknown ItemNum in Menu 0 !");break;
              }
             break;
    case 1 : switch(ITEMNUM(select))
              {
               case 0 : reqinp(JINPHEAD);break;
               case 1 : strcpy(pc.headpath,pc.realheadpath);
                        strcpy((char *)inpgadinf.Buffer,pc.headpath);
                        headex();
                        break;
               default: warn("Unknown ItemNum in menu 1 !");break;
              }
             break;
    case 31 : switch(ITEMNUM(select))
               {
                case 63 : break;
                default : warn("Unknown Menu !");break;
               }
              break;
    default: warn("Unknown Menu !");
             if(!wbstart) printf("menu%d,item%d\n",(int)MENUNUM(select),(int)ITEMNUM(select));
             break;
   }
  return cont;
 }

void reqinp(int jobflag)
 {
  char fname[70];
  
  job=jobflag;
  if(job==JINPHEAD)
   {
    Request(&inpreq,MyWindow);
    outp(NULL);
   }
  else
   {
    getfilename(fname);
    switch(job)
     {
      case JINPSTART:
                      freeem();
                      initpc();
                      outlines=0;
                      outmode=0;
                      pc.firstroom=AllocMem(sizeof(struct raum),MEMF_CLEAR);
                      if(!pc.firstroom) clos("No memory for inventory !");
                      *((pc.firstroom)->name)=0;
                      if(!*fname) break;
                      strncpy(pc.headfile,fname,(size_t)80);
                      job=JIDLE;
                      doactives=TRUE;
                      analyse(pc.headfile,NULL,NULL,NULL,NULL);
                      if(pc.locflag) SetWindowTitles(MyWindow,pc.outraum,(char *)-1);
                      break;
      case JINPLOAD : job=JIDLE;load(fname);gadup(NULL,STANDBASIS);break;
      case JINPSAVE : job=JIDLE;save(fname);gadup(NULL,STANDBASIS);break;
     }
   }
 }

void turnover(MEBOOL eachmoved)
 {
  int len;

  dechoose();
  *lastgetphrase=0;
  *lastdropphrase=0;
  if(!eachmoved)
   {
    if(pc.eachmovemem)
     {
      doactives=TRUE;
      analyse(NULL,NULL,NULL,NULL,NULL);
     }
    if(pc.raum[0])
     {
      outp(NULL);
      warn(pc.outraum);
      outp(NULL);
     }
   }
  if(job!=JDEAD && pc.locflag) SetWindowTitles(MyWindow,pc.outraum,(char *)-1);
 }

void linit(struct item *li,int clear)
 {
  int i;
  struct item *p;
  
  if(donotkilllist) return;
  if(freedisplist) {clearlist(displist);displist=NULL;}
  if(!li && clear)
   {
    turnover(FALSE);
    if(job!=JDEAD) job=JIDLE;
   }
  apos=lpos;
  displist=li;
  lpos=0;
  lanz=0;
  p=displist;
  while(p)
   {
    p=p->nextitem;
    lanz++;
   }
  if(!clear && apos+LISTANZ<=lanz) lpos=apos;
  ldisp(TRUE);
 }

void fnamecpy(char *dest,char *sour)
 {
  int i,j;
  BOOL show;
  
  show=TRUE;
  j=0;
  for(i=0;i<80;i++)
   {
    if(sour[i]=='§') show=show ? show=FALSE : TRUE;
    else if(show || !sour[i])
     {
      dest[j]=sour[i];
      j++;
     }
   }
 }

void ldisp(long refresh)
 {
  struct item *p;
  int i;
  char dumb[81];

  p=displist;
  for(i=0;i<lpos && p;i++) p=p->nextitem;
  SetAPen(rp,0L);
  RectFill(rp,17L,12L,634L,84L);
  SetAPen(rp,1L);
  while(i<lpos+LISTANZ)
   {
    if(p)
     {
      fnamecpy(dumb,(char *)(p->name));
      ITDummy.IText=(UBYTE *)dumb;
      PrintIText(rp,&ITDummy,18L,(long)(13+(i-lpos)*8));
      p=p->nextitem;
     }
    i++;
   }

  if(refresh)
   {  
    if(lanz-LISTANZ>0)
      NewModifyProp(&propgad,MyWindow,NULL,(long)(PROPBORDERLESS | AUTOKNOB | FREEVERT),
                    0L,(long)MAXBODY*lpos/(lanz-LISTANZ),
                    (long)MAXBODY,(long)MAXBODY*LISTANZ/lanz,1L);
    else
      NewModifyProp(&propgad,MyWindow,NULL,(long)(PROPBORDERLESS | AUTOKNOB | FREEVERT),
                    0L,(long)MAXBODY,(long)MAXBODY,(long)MAXBODY,1L);
    RefreshGList(&propgad,MyWindow,NULL,1L);
   }
 }

void propey(struct IntuiMessage *msg)
 {
  USHORT id;
  int altlpos;
  volatile USHORT *p;
  
  p=&(((struct PropInfo *)((struct Gadget *)msg->IAddress)->SpecialInfo)->VertPot);
  ReplyMsg((struct Message *)msg);
  msg=NULL;
  id=((struct Gadget *)msg->IAddress)->GadgetID;
  switch(id)
   {
    case PROPGAD : while(!(msg=(struct IntuiMessage *)GetMsg(MyWindow->UserPort)))
                    {
                     altlpos=lpos;
                     lpos=lanz<=LISTANZ ? 0 : (*p)*(long)(lanz-LISTANZ)/MAXBODY;
                     if(altlpos!=lpos) ldisp(FALSE);
                    }
                   ReplyMsg((struct Message *)msg);
                   msg=NULL;
                   lpos=lanz<=LISTANZ ? 0 : (*p)*(long)(lanz-LISTANZ)/MAXBODY;
                   if(altlpos!=lpos) ldisp(FALSE);
                   break;
   }
 }

void gadup(struct IntuiMessage *msg,USHORT id)
 {
  struct item *p,*dlist,*ilist;
  struct raum *r;
  int i;

  if(msg && !id) id=((struct Gadget *)msg->IAddress)->GadgetID;
  if(id>=STANDBASIS && id<STANDBASIS+99)
   {
    id-=STANDBASIS;
    switch(id)
     {
      case 0  : dlist=NULL;
                doactives=FALSE;
                analyse(pc.raum,NULL,&dlist,NULL,NULL);
                linit(dlist,KEEP);
                freedisplist=TRUE;
                job=JCROOMDO;
                break;
      case 1  : r=pc.firstroom;
                while(r && strcmp(r->name,pc.raum)) r=r->nextraum;
                if(r)
                 {
                  iteml(r->firstitem);
                  freedisplist=FALSE;
                 }
                else
                 {
                  ilist=NULL;
                  doactives=FALSE;
                  analyse(pc.raum,&ilist,NULL,NULL,NULL);
                  iteml(ilist);
                  freedisplist=TRUE;
                 }
                job=JCITEM;
                break;
      case 2  : r=pc.firstroom;
                while(r->nextraum) r=r->nextraum;
                iteml(r->firstitem);
                freedisplist=FALSE;
                job=JCINVITEM;
                break;
      case 3  : break;
      case 4  : break;
      case 5  : dechoose();job=JIDLE;if(job!=JIDLE);linit(NULL,TURNED);break;
      default : warn("Strange standard gadget id !");break;
     }
   }
  else if(id>=LISTBASIS && id<LISTBASIS+99)
   {
    id+=lpos-LISTBASIS;
    p=displist;
    while(id>0 && p)
     {
      id--;
      p=p->nextitem;
     }
    if(*(p->name))
     {
      switch(job)
       {
        case JCROOMDO : strcpy(actitem,pc.raum);
                        strcpy(docop,p->name);
                        doactives=TRUE;
                        analyse(pc.raum,NULL,NULL,p->name,NULL);
                        if(job==JCHOOSE) break;
                        if(strcmp(actitem,pc.raum)) linit(NULL,TURNED);
                        else
                         {
                          turnover(FALSE);
                          dlist=NULL;
                          doactives=TRUE;
                          analyse(pc.raum,NULL,&dlist,NULL,NULL);
                          linit(dlist,KEEP);
                          freedisplist=TRUE;
                         }
                        break;
        case JCINVITEM: dlist=NULL;
                        doactives=FALSE;
                        analyse(p->name,NULL,&dlist,NULL,NULL);
                        linit(dlist,KEEP);
                        freedisplist=TRUE;
                        job=JCIIDO;
                        strcpy(actitem,p->name);
                        break;
        case JCIIDO   : doactives=TRUE;
                        analyse(actitem,NULL,NULL,p->name,NULL);
                        if(job==JCHOOSE) break;
                        if(!mifitemin(actitem,"")) linit(NULL,TURNED);
                        else
                         {
                          dlist=NULL;
                          turnover(FALSE);
                          doactives=TRUE;
                          analyse(actitem,NULL,&dlist,NULL,NULL);
                          linit(dlist,KEEP);
                          freedisplist=TRUE;
                         }
                        break;
        case JCITEM   : dlist=NULL;
                        strcpy(actitem,p->name);
                        doactives=FALSE;
                        analyse(p->name,NULL,&dlist,NULL,NULL);
                        linit(dlist,KEEP);
                        freedisplist=TRUE;
                        job=JCITEMDO;
                        break;
        case JCITEMDO : doactives=TRUE;
                        analyse(actitem,NULL,NULL,p->name,NULL);
                        strcpy(docop,p->name);
                        if(job==JCHOOSE) break;
                        if(!mifitemin(actitem,pc.raum)) linit(NULL,TURNED);
                        else
                         {
                          dlist=NULL;
                          turnover(FALSE);
                          doactives=TRUE;
                          analyse(actitem,NULL,&dlist,NULL,NULL);
                          linit(dlist,KEEP);
                          freedisplist=TRUE;
                         }
                        break;
        case JCHOOSE  : i=0;
                        while(*(choices[i])) i++;
                        strcpy(choices[i],p->name);
                        clearlist(clist);
                        clist=NULL;
                        job=JIDLE;
                        doactives=FALSE;
                        analyse(actitem,NULL,NULL,docop,NULL);
/*                        linit(NULL,TURNED);
*/                        break;
       }
     }
   }
  else
    switch(id)
     {
      case TEXTGAD : break;
      case UPGAD   : if(lpos) {lpos--;ldisp(TRUE);} break;
      case DOWNGAD : if(lpos+LISTANZ<lanz) {lpos++;ldisp(TRUE);} break;
      case PROPGAD : if(msg) lpos=lanz<=LISTANZ ? 0 : ((struct PropInfo *)((struct Gadget *)msg->IAddress)->SpecialInfo)->VertPot*(long)(lanz-LISTANZ)/MAXBODY;
                     ldisp(FALSE);
                     break;
      case INPGAD  : if(!*(inpgadinf.Buffer) && msg) break;
                     switch(job)
                      {
                       case JINPHEAD : job=JIDLE;
                                       strcpy(pc.headpath,(char *)inpgadinf.Buffer);
                                       headex();
                                       break;
                      }
                     break;
      default : warn("Unknown Gadget ID !");
     }
  if(job==JCHOOSE)
   {
    linit(clist,KEEP);
    freedisplist=FALSE;
   }
  else if(cprob)
   {
    dechoose();
    linit(NULL,TURNED);
   }
 }

void drawar()
 {
  SetAPen(rp,3L);
  Move(rp,625L,170L);
  Draw(rp,625L,180L);
  Draw(rp,620L,180L);
  Draw(rp,627L,185L);
  Draw(rp,635L,180L);
  Draw(rp,630L,180L);
  Draw(rp,630L,170L);
  Draw(rp,625L,170L);
 }

void mwait(BOOL force)
 {
  struct IntuiMessage *msg=NULL;

  outlines=0;
  if(outmode>15 && !force) return;
  SetDrMd(rp,(long)COMPLEMENT);
  drawar();
  
  while(msg=(struct IntuiMessage *)GetMsg(MyWindow->UserPort)) ReplyMsg((struct Message *)msg);
  msg=NULL;
  Wait(1L<<MyWindow->UserPort->mp_SigBit);
  while(msg=(struct IntuiMessage *)GetMsg(MyWindow->UserPort))
   {
    if(msg->Class==GADGETUP)
     {
      if(((struct Gadget *)msg->IAddress)->GadgetID==STANDBASIS+5)
       {
        outmode=20;
       }
     }
    if(msg->Class==CLOSEWINDOW)
     {
      outmode=30;
     }
    ReplyMsg((struct Message *)msg);
    msg=NULL;
   }

  drawar();
  SetDrMd(rp,(long)JAM1);
 }

void outp(char *text)
 {
  char outer[80];
  
  if(outmode>25) return;
  outlines++;
  if(outlines>=9) mwait((BOOL)FALSE);
  if(text) strncpy(outer,text,(size_t)80);
  else *outer=0;
  SetBPen(rp,0L);
  ScrollRaster(rp,0L,8L,4L,106L,635L,186L);
  ITDummy.IText=(UBYTE *)outer;
  PrintIText(rp,&ITDummy,4L,178L);
 }

void warn(char *text)
 {
  ITDummy.FrontPen=3;
  outp(text);
  ITDummy.FrontPen=1;
 }

void wope()
 {
  int i;
  
  IntuitionBase=(struct IntuitionBase *)OpenLibrary("intuition.library",0L);
  if(!IntuitionBase) clos("Can't open Intuition !");
  GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",0L);
  if(!GfxBase) clos("Can't open Graphics !");
  DiskfontBase=OpenLibrary("diskfont.library",0L);
  if(!DiskfontBase) clos("Can't open Diskfont !");
  ArpBase=(void *)OpenLibrary("arp.library",0L);
  if(!ArpBase) clos("Can't open ARP.library !");

  DOSBASE=DOSBase;
  GFXBASE=GfxBase;
  INTUITIONBASE=IntuitionBase;
  for(i=1;i<6;i++)
   {
    memcpy(&standgad[i],standgad,sizeof(struct Gadget));
    memcpy(&standitex[i],standitex,sizeof(struct IntuiText));
    standgad[i-1].NextGadget=&(standgad[i]);
    standgad[i].LeftEdge=standgad[i-1].LeftEdge+105;
    standgad[i].GadgetID=standgad[i-1].GadgetID+1;
    standgad[i].GadgetText=&(standitex[i]);
    standitex[i].IText=(UBYTE *)standnames[i];
    standitex[i].LeftEdge=standadj[i];
   }
  standitex[0].LeftEdge=standadj[0];
  standgad[i-1].NextGadget=listgad;

  for(i=1;i<LISTANZ;i++)
   {
    memcpy(&listgad[i],listgad,sizeof(struct Gadget));
    listgad[i-1].NextGadget=&(listgad[i]);
    listgad[i].TopEdge=listgad[i-1].TopEdge+8;
    listgad[i].GadgetID=listgad[i-1].GadgetID+1;
   }
  listgad[i-1].NextGadget=&propgad;
  listgad[0].TopEdge-=1;
  listgad[0].Height+=1;

  MyScreen=OpenScreen(&MyNewScreen);
  if(!MyScreen) clos("Can't open screen!");
/*  style();
*/  ITDummy.ITextFont=&xtstyle;
  myfont=OpenFont(&mytstyle);
  if(!myfont) clos("Can't open save font !");
  SetFont(rp,myfont);
 }

void restyle()
 {
  if(MyWindow && !*(pc.interface))
   {
    if(msg) ReplyMsg((struct Message *)msg);
    msg=NULL;
    if(MyWindow->MenuStrip) ClearMenuStrip(MyWindow);
    CloseWindow(MyWindow);
    if(MyScreen)
     {
      if((MyNewScreen.Depth)!=2)
       {
        CloseScreen(MyScreen);
        MyNewScreen.Depth=2;
        MyScreen=OpenScreen(&MyNewScreen);
       }
     }
   }
  MyWindow=NULL;
  pc.interface[0]=0;
  closesub();
  style();
 }

void style()
 {
  int i;
  char c[2];
  struct ViewPort *vp;

  vp=&(MyScreen->ViewPort);
  for(i=0;i<16*3;i+=3) SetRGB4(vp,(long)i/3,(long)scol[i],(long)scol[i+1],(long)scol[i+2]);
  MyNewWindow.Screen=MyScreen;
  MyWindow=OpenWindow(&MyNewWindow);
  if(!MyWindow) clos("Can't open Window !");
  fr.Window=(void *)MyWindow;
  rp=MyWindow->RPort;
  AddGList(MyWindow,&textgad,0L,-1L,NULL);
  RefreshGList(&textgad,MyWindow,NULL,-1L);
  SetDrMd(rp,(long)JAM1);
  SetAPen(rp,1L);
  Move(rp,1L,87L);   /* middle lines */
  Draw(rp,638L,87L);
  Move(rp,1L,103L);
  Draw(rp,638L,103L);
  Move(rp,4L,11L);   /* listbox */
  Draw(rp,635L,11L);
  Draw(rp,635L,85L);
  Draw(rp,4L,85L);
  Draw(rp,4L,11L);
  Move(rp,16L,11L);
  Draw(rp,16L,85L);
  Move(rp,4L,21L);   /* prop borders */
  Draw(rp,16L,21L);
  Move(rp,4L,75L);
  Draw(rp,16L,75L);
  Move(rp,10L,13L);   /* up */
  Draw(rp,10L,19L);
  Move(rp,7L,16L);
  Draw(rp,10L,13L);
  Draw(rp,13L,16L);
  Move(rp,10L,83L);   /* down */
  Draw(rp,10L,77L);
  Move(rp,7L,80L);
  Draw(rp,10L,83L);
  Draw(rp,13L,80L);
  SetMenuStrip(MyWindow,menu);
  ITDummy.FrontPen=3;
  c[1]=0;
  ITDummy.IText=(UBYTE *)c;
  *c='R';
  PrintIText(rp,&ITDummy,41L,92L);
  *c='I';
  PrintIText(rp,&ITDummy,141L,92L);
  *c='N';
  PrintIText(rp,&ITDummy,239L,92L);
  ITDummy.FrontPen=1;
 }

void getfilename(char *name)
 {
  FileRequest(&fr);
  strcpy(name,fr.Dir);
  strcpy(&(name[strlen(name)]),fr.File);
 }

void wclo()
 {
  if(subwindow)
   {
    CloseWindow(subwindow);
    if(subscreen) CloseScreen(subscreen);
   }
  if(MyWindow)
   {
    if(MyWindow->MenuStrip) ClearMenuStrip(MyWindow);
    CloseWindow(MyWindow);
   }
  if(MyScreen) CloseScreen(MyScreen);
  if(myfont) CloseFont(myfont);
  if(xfont) CloseFont(xfont);
  if(ArpBase) CloseLibrary((struct Library *)ArpBase);
  if(DiskfontBase) CloseLibrary(DiskfontBase);
  if(GfxBase) CloseLibrary(GfxBase);
  if(IntuitionBase) CloseLibrary(IntuitionBase);
 }

void about()
 {
  int i;
  
  outp(NULL);
  warn("Haktar V1.6   The Final Reality Simulation Language Interpreter");
  warn(" (c) 1992 by Guido Wegener");
  i=0;
  while(*aboutt[i])
   {
    outp(aboutt[i]);
    i++;
   }
  outp(NULL);
 }

void instr()
 {
  int i;
  
  outp(NULL);
  warn("Short Instructions for the user interface :");
  i=0;
  outp(NULL);
  while(*instrt[i])
   {
    outp(instrt[i]);
    i++;
   }
  outp(NULL);
 }

void crap()
 {
  int i;
  
  i=0;
  outp(NULL);
  while(*crapt[i])
   {
    outp(crapt[i]);
    i++;
   }
  outp(NULL);
 }

void iteml(struct item *firstitem)
 {
  linit(firstitem,KEEP);
 }

/* -------------------------------------------------------------------- */

void ope()
 {
  DOSBase=(struct DOSBase *)OpenLibrary("dos.library",0L);
  if(!DOSBase) clos("Can't open DOS !");
  pc.firstroom=AllocMem(sizeof(struct raum),MEMF_CLEAR);
  if(!pc.firstroom) clos("No memory for inventory !");
  *((pc.firstroom)->name)=0;
  wope();
  initpc();
 }

void initpc()
 {
  pc.eachmovemem=0;
  pc.eachmovesize=0;
  pc.eachmovename[0]=0;
  pc.headpath[0]=0;
  pc.locflag=TRUE;
  restyle();
  pc.interface[0]=0;
  pc.subpic[0]=0;
  if(xfont) CloseFont(xfont);
  xfont=NULL;
  if(*serie!=' ' && serie[strlen(serie)-1]!=' ') printdum=sprintf(s,serie);
  strcpy(pc.fontname,"topaz.font");
 }

void headex()
 {
  int p;
  char c;
  
  p=strlen(pc.headpath);
  if(p)
   {
    c=pc.headpath[p-1];
    if(c!=':' && c!='/')
     {
      pc.headpath[p]='/';
      p++;
      if(p>81) p=81;
      pc.headpath[p]=0;
     }
   }
 }

void dechoose()
 {
  int i;
  
  for(i=0;i<10;i++) *(choices[i])=0;
  clevel=-1;
  if(clist) clearlist(clist);
  clist=NULL;
  cprob=FALSE;
  if(job==JCHOOSE) job=JIDLE;
 }
 
void freeem()
 {
  struct raum *point,*prev;
  struct var *vpoint,*vprev;
  
  dechoose();
  if(freedisplist) clearlist(displist);
  displist=NULL;
  clearlist(pc.firstflag);
  pc.firstflag=NULL;
  point=pc.firstroom;
  while(point)
   {
    clearlist(point->firstitem);
    prev=point;
    point=point->nextraum;
    FreeMem(prev,sizeof(struct raum));
   }
  pc.firstroom=NULL;
  point=pc.firstmultifile;
  while(point)
   {
    clearlist(point->firstitem);
    prev=point;
    point=point->nextraum;
    FreeMem(prev,sizeof(struct raum));
   }
  pc.firstmultifile=NULL;
  vpoint=pc.firstvar;
  while(vpoint)
   {
    vprev=vpoint;
    vpoint=vpoint->nextvar;
    FreeMem(vprev,sizeof(struct var));
   }
  pc.firstvar=NULL;
  if(pc.eachmovemem) FreeMem(pc.eachmovemem,pc.eachmovesize);
  pc.eachmovemem=NULL;
  *pc.eachmovename=0;
  *pc.raum=0;
  *pc.outraum=0;
  *pc.lastinput=0;
  *pc.headpath=0;
  *pc.realheadpath=0;
  pc.maxweight=0;
  pc.weight=0;
  pc.time=0;
  if(xfont) CloseFont(xfont);
  xfont=0;
  *(pc.fontname)=0;
  *(pc.interface)=0;
 }

void lowcase(char *str)
 {
  while(*str)
   {
    if(*str==215 || *str==247);
    else if(*str>='A' && *str<='Z') *str+=32;
    else if(*str>=192 && *str<=222) *str+=32;
    str++;
   }
 }

void clos(char *text)
 {
  freeem();
  if(text) puts(text);
  wclo();
  if(DOSBase) CloseLibrary(DOSBase);
  exit(0);
 }

char *loaditem(char *file,long *length)
 {
  char *buffer;
  struct FileHandle *fh;
  struct FileInfoBlock *fib;
  long lock;
  long size,check;
  char fullname[162];
  char code[6];
  BOOL coded;
  register long i;
  UBYTE dcode;

  if(job==JDEAD) return NULL;
  if(!*file) return NULL;
  if(job==JDEAD) return NULL;
  strncpy(fullname,pc.headpath,(size_t)81);
  strncpy(&(fullname[strlen(fullname)]),file,(size_t)81);

  lock=Lock(fullname,-2L);
  if(!lock && fullname && *fullname)
   {
    if(!wbstart) printf("error while dealing with [%s]\n",fullname);
    warn("Unknown File Error !!!");
    warn(fullname);
    return NULL;
   }
  fib=AllocMem(sizeof(struct FileInfoBlock),NULL);
  if(!fib) {UnLock(lock);clos("loaditem() : no memory for FileInfoBlock !");}
  if(!Examine(lock,fib)) {UnLock(lock);FreeMem(fib,sizeof(struct FileInfoBlock));clos("loaditem() : trouble with Examine !");}
  UnLock(lock);
  size=(long)(fib->fib_Size);
  FreeMem(fib,sizeof(struct FileInfoBlock));

  fh=(struct FileHandle *)Open(fullname,(long)MODE_OLDFILE);
  if(!fh)
   {
    FreeMem(buffer,size+1);
    if(!wbstart) printf("error while dealing with [%s]\n",fullname);
    clos("loaditem() : can't Open file !");
   }
  check=Read((BPTR)fh,code,6L);
  if(!strncmp(code,"cOdE01",(size_t)6))
   {
    check=Read((BPTR)fh,code,4L);
    if(check!=4) {Close((BPTR)fh);clos("loaditem() : can't read Code !");}
    dcode=(code[0])+2*(code[1])+5*(code[2])+3*(code[3]);
    coded=TRUE;
    size-=10;
   }
  else
   {
    check=Seek((BPTR)fh,0L,(long)OFFSET_BEGINNING);
    coded=FALSE;
   }
  buffer=AllocMem(size+1,NULL);
  if(!buffer) clos("loaditem() : no memory for buffer !");
  check=Read((BPTR)fh,buffer,size);
  if(check!=size) {Close((BPTR)fh);clos("loaditem() : can't Read !");}
  Close((BPTR)fh);
  buffer[size]=0;
  size++;
  *length=size;
  if(coded) for(i=0;i<size-1;i++) buffer[i]=buffer[i]^((UBYTE)i+dcode);
  return buffer;
 }

void analyse(char *file,struct item **ilist,struct item **dlist,char *doer,struct item **mflist)
 {
  char *buffer;
  long size;
  char *point;
  char comand[16]; /* I know that it is spelled «command», but this way it is shorter...*/
  register int i,a;
  char *c;
  char **act;
  char *thingy;
  struct item *th;
  struct raum *mf;
  char *mffile;
  char *name;
  
  name=file;
  thingy=NULL;
  act=&c;
  mffile=NULL;
  mf=pc.firstmultifile;
  while(mf)
   {
    th=mf->firstitem;
    while(th)
     {
      if(!strcmp(file,th->name))
       {
        mffile=mf->name;
        break;
       }
      th=th->nextitem;
     }
    mf=mf->nextraum;
   }
  if(mffile)
   {
    thingy=file;
    file=mffile;
   }
  if(file) buffer=loaditem(file,&size);
  else buffer=pc.eachmovemem;

  if(!buffer) return;
  c=buffer;
  while(*c)
   {
    if(*c=='|')
     {
      a=0;
      while(a>=0 && *c)
       {
        if(*c=='[') a++;
        if(*c==']') a--;
        c++;
       }
     }
    else
    if(*c!=' ' && *c!='\n' && *c!='[' && *c!=']' && *c!='\t')
     {
      point=c;
      i=0;
      while(*point && *point!=' ' && *point!='\n' && *point!=',' && *point!=']' && *point!='|' && *point!='·' && *point!='[')
       {
        comand[i]=*point;
        point++;
        i++;
       }
      comand[i]=0;
      lowcase(comand);
      c=point;
           if(!strcmp(comand,"do")) fdo(act,dlist,doer);
      else if(!strcmp(comand,"items")         || !strcmp(comand,"i")) items(act,ilist);
      else if(!strcmp(comand,"print")         || !strcmp(comand,"?") || !strcmp(comand,"p")) print(act);
      else if(!strcmp(comand,"move")          || !strcmp(comand,"m")) move(act);
      else if(!strcmp(comand,"addtime")       || !strcmp(comand,"at")) addtime(act);
      else if(!strcmp(comand,"go")) go(act,(MEBOOL)!file);
      else if(!strcmp(comand,"wait")          || !strcmp(comand,"w")) textwait(act);
      else if(!strcmp(comand,"addweight")     || !strcmp(comand,"aw")) addweight(act);
      else if(!strcmp(comand,"rem")           || !strcmp(comand,";")) rem(act);
      else if(!strcmp(comand,"create")        || !strcmp(comand,"c")) create(act);
      else if(!strcmp(comand,"gone")          || !strcmp(comand,"g") || !strcmp(comand,"lost")) gone(act);
      else if(!strcmp(comand,"setflag")       || !strcmp(comand,"sf")) setflag(act);
      else if(!strcmp(comand,"delflag")       || !strcmp(comand,"df")) delflag(act);
      else if(!strcmp(comand,"setvar")        || !strcmp(comand,"sv")) setvar(act);
      else if(!strcmp(comand,"addvar")        || !strcmp(comand,"av")) addvar(act);
      else if(hyperif(comand,act));
      else if(!strcmp(comand,"showpic")       || !strcmp(comand,"sp")) showpic(act);
      else if(!strcmp(comand,"showpicsub")    || !strcmp(comand,"sps")) showpicsub(act);
      else if(!strcmp(comand,"settime")       || !strcmp(comand,"st")) settime(act);
      else if(!strcmp(comand,"sys")           || !strcmp(comand,"s")) sys(act);
      else if(!strcmp(comand,"dead")          || !strcmp(comand,"d")) dead(act);
      else if(!strcmp(comand,"input")         || !strcmp(comand,"inp")) input(act);
      else if(!strcmp(comand,"headpath")      || !strcmp(comand,"hp")) headpath(act);
      else if(!strcmp(comand,"maxweight")     || !strcmp(comand,"mw")) maxweight(act);
      else if(!strcmp(comand,"execute")       || !strcmp(comand,"e")) execute(act);
      else if(!strcmp(comand,"handle")        || !strcmp(comand,"h")) handle(act,name,dlist,doer);
      else if(!strcmp(comand,"multi")         || !strcmp(comand,"mf")) multi(act);
      else if(!strcmp(comand,"thing")         || !strcmp(comand,"t")) thing(act,mflist,thingy);
      else if(!strcmp(comand,"eachmove")      || !strcmp(comand,"em")) eachmove(act);
      else if(!strcmp(comand,"getphrase")     || !strcmp(comand,"gp")) getphrase(act);
      else if(!strcmp(comand,"dropphrase")    || !strcmp(comand,"dp")) dropphrase(act);
      else if(!strcmp(comand,"cantgetphrase") || !strcmp(comand,"cgp")) cantgetphrase(act);
      else if(!strcmp(comand,"printfile")     || !strcmp(comand,"pf")) printfile(act);
      else if(!strcmp(comand,"doscall")       || !strcmp(comand,"dc")) doscall(act);
      else if(!strcmp(comand,"font")          || !strcmp(comand,"fo")) font(act);
      else if(!strcmp(comand,"cprint")        || !strcmp(comand,"c?") || !strcmp(comand,"!")) cprint(act);
      else if(!strcmp(comand,"noautowait")    || !strcmp(comand,"naw")) noautowait(act);
      else if(!strcmp(comand,"printvar")      || !strcmp(comand,"pv") || !strcmp(comand,"?v")) printvar(act);
      else if(!strcmp(comand,"choose")        || !strcmp(comand,"c")) choose(act);
      else if(!strcmp(comand,"startchoose")   || !strcmp(comand,"sc")) startchoose(act);
      else if(!strcmp(comand,"endchoose")     || !strcmp(comand,"ec")) endchoose(act);
      else if(!strcmp(comand,"storevars")     || !strcmp(comand,"stv")) storevars(act);
      else if(!strcmp(comand,"getvars")       || !strcmp(comand,"gv")) getvars(act);
      else if(!strcmp(comand,"locoff")        || !strcmp(comand,"loff")) locoff(act);
      else if(!strcmp(comand,"locon")         || !strcmp(comand,"lon")) locon(act);
      else if(!strcmp(comand,"simpleface")    || !strcmp(comand,"sif")) simpleface(act);
      else
       {
        if(!wbstart) printf("Syntax Error : [%s] is no command !!!\n",comand);
        warn("Syntax Error : unknown command :");
        warn(comand);
        if(!*comand) c++;
       }
     }
    else c++;
   }
  if(file) FreeMem(buffer,size);
 }

BOOL hyperif(char *comand,char **act)
 {
  if(!strcmp(comand,"ifweight")      || !strcmp(comand,"iw")) ifweight(act);
  else if(!strcmp(comand,"ifflag")   || !strcmp(comand,"if")) ifflag(act);
  else if(!strcmp(comand,"ifvar")    || !strcmp(comand,"iv")) ifvar(act);
  else if(!strcmp(comand,"ifitemin") || !strcmp(comand,"iii")) ifitemin(act);
  else if(!strcmp(comand,"ifinput")  || !strcmp(comand,"iinp")) ifinput(act);
  else if(!strcmp(comand,"iftime")   || !strcmp(comand,"it")) iftime(act);
  else if(!strcmp(comand,"ifin")     || !strcmp(comand,"ii")) ifin(act);
  else if(!strcmp(comand,"ifchance") || !strcmp(comand,"ic")) ifchance(act);
  else return FALSE;
  return TRUE;
 }

void iffi(char **act,BOOL result)
 {
  char iftype[78];
  
  if(result)
   {
    ueberklamauf(act);
    return;
   }
  readarg(act,iftype,(UBYTE)(ATWORD|ATSHORT));
  if(!*iftype)
   {
    ueberlesenstri(act);
   }
  else if(!hyperif(iftype,act))
   {
    if(!wbstart) printf("[%s] after if !",iftype);
    warn("Normal command directly after if !");
   }
 }

void ueberklamauf(char **act)
 {
  while(**act && **act!='[') (*act)++;
 }

void ueberlesenklam(char **act)
 {
  register int a;
  
  a=0;
  while(a>=0 && **act)
   {
    if(**act=='[') a++;
    if(**act==']')
     {
      if(a==1) a=-1;
      a--;
     }
    (*act)++;
   }
 }

void ueberlesenstri(char **act)
 {
  register int a;
  
  a=0;
  while((a!=1 || **act!='|') && **act)
   {
    if(**act=='[') a++;
    if(**act==']') a--;
    (*act)++;
    if(a<0)
     {
      warn("Wrong parantheses !");
      break;
     }
   }
  (*act)++;
 }

void readarg(char **act,char *arg,UBYTE flags)
 {
  register char c;
  register int i;
  BOOL cont;
  UBYTE upflag,max;
  
  upflag=flags&(ATLONG|ATMEDIUM|ATSHORT|ATXL);
  switch (upflag)
   {
    case ATLONG   : max=80;break;
    case ATMEDIUM : max=79;break;
    case ATSHORT  : max=77;break;
    case ATXL     : max=1;break;
    default : max=80;break;
   }
  flags=flags&(255-(ATLONG|ATMEDIUM|ATSHORT|ATXL));
  c=**act;
  if(!c)
   {
    *arg=0;
    return;
   }
  if(c=='\n' || c=='·' || c==']' || c=='|' || c=='[')
   {
    *arg=0;
    if(flags=ATNAME) strcpy(arg,inv);
    (*act)++;
    return;
   }
  (*act)++;
  c=**act;
  if(!c || c=='·' || c=='\n' || c==']' || c=='|' || c=='[' || (flags!=ATSTRING && c==','))
   {
    *arg=0;
    if(flags=ATNAME) strcpy(arg,inv);
    return;
   }
  if(flags!=ATSTRING)
    while(**act==' ' && **act) (*act)++;
  i=0;
  c=**act;
  cont=TRUE;
  while(cont && c && c!='\n' && c!='·' && c!='[' && c!='|' && c!=']' && i<max)
   {
    arg[i]=c;
    if(upflag!=ATXL) i++;
    (*act)++;
    c=**act;
    if(flags==ATNAME && c==',') cont=FALSE;
    else if(flags==ATWORD && (c==' ' || c==',')) cont=FALSE;
    else if(flags==ATINTEGER && (c<'0' || c>'9') && c!='-' && c!='+') cont=FALSE;
   }
  arg[i]=0;
  i--;
  if(flags!=ATSTRING)
    while(i>=0 && arg[i]==' ')
     {
      arg[i]=0;
      i--;
     }
  if(flags==ATNAME)
   {
    if(!strcmp(arg,"ACTROOM") || *arg=='¡') strncpy(arg,pc.raum,(size_t)max);
    else if(!strcmp(arg,"INV")) *arg=0;
   }
  if(upflag!=ATXL) arg[max]=0;
 }
 
void clearlist(struct item *list)
 {
  struct item *point;
  
  while(list)
   {
    point=list;
    list=list->nextitem;
    FreeMem(point,sizeof(struct item));
   }
 }

void savelist(struct FileHandle *fh,void *point,size_t size)
 {
  long check;
  
  while(point)
   {
    check=Write((BPTR)fh,(char *)point,size);
    if(check!=size)
     {
      warn("Disk full ?");
      return;
     }
    point=*((void **)point);
   }
 }

void save(char *fn)
 {
  struct raum *rpoint;
  struct var *vpoint;
  struct FileHandle *fh;
  long check;
  
  fh=(struct FileHandle *)Open(fn,(long)MODE_NEWFILE);
  if(!fh)
   {
    warn("Can't open file !");
    return;
   }
  check=Write((BPTR)fh,mark,(size_t)strlen(mark));
  if(check!=strlen(mark))
   {
    warn("Disk full  ??");
    Close((BPTR)fh);
    return;
   }
  check=Write((BPTR)fh,(char *)&pc,sizeof(struct charakter));
  if(check!=sizeof(struct charakter))
   {
    warn("Disk full ?");
    Close((BPTR)fh);
    return;
   }
  if(pc.eachmovemem)
   {
    check=Write((BPTR)fh,pc.eachmovemem,(size_t)(pc.eachmovesize));
    if(check!=pc.eachmovesize)
     {
      warn("Disk full ? ?");
      Close((BPTR)fh);
      return;
     }
   }
  savelist(fh,pc.firstflag,sizeof(struct item));
  savelist(fh,pc.firstvar,sizeof(struct var));
  rpoint=pc.firstroom;
  while(rpoint)
   {
    check=Write((BPTR)fh,(char *)rpoint,sizeof(struct raum));
    if(check!=sizeof(struct raum))
     {
      warn("Disk full ??");
      Close((BPTR)fh);
      return;
     }
    savelist(fh,rpoint->firstitem,sizeof(struct item));
    rpoint=rpoint->nextraum;
   }
  rpoint=pc.firstmultifile;
  while(rpoint)
   {
    check=Write((BPTR)fh,(char *)rpoint,sizeof(struct raum));
    if(check!=sizeof(struct raum))
     {
      warn("Disk full ??");
      Close((BPTR)fh);
      return;
     }
    savelist(fh,rpoint->firstitem,sizeof(struct item));
    rpoint=rpoint->nextraum;
   }
  Close((BPTR)fh);
 }

void loadlist(struct FileHandle *fh,void **link,size_t size)
 {
  void **prev;
  void *point;
  long check;
  
  point=*link;
  prev=link;
  while(point)
   {
    point=AllocMem(size,MEMF_CLEAR);
    *prev=point;
    if(!point) clos("No memory for load !");
    prev=(void **)point;
    check=Read((BPTR)fh,(char *)point,size);
    if(check!=size)
     {
      *((void **)point)=NULL;
      clos("Load Error !!");
     }
    point=*((void **)point);
   }
 }

void load(char *fn)
 {
  struct raum *rpoint,**rprev;
  struct FileHandle *fh;
  long check;
  char marker[20];
  char *mem;
  long size;
  
  outlines=0;
  outmode=0;
  restyle();
  fh=(struct FileHandle *)Open(fn,(long)MODE_OLDFILE);
  if(!fh)
   {
    warn("Can't open file !");
    return;
   }
  freeem();
  check=Read((BPTR)fh,marker,(size_t)strlen(mark));
  if(check!=strlen(mark))
   {
    warn("Read Error ! ! !");
    Close((BPTR)fh);
    return;
   }
  if(strncmp(mark,marker,(size_t)strlen(mark)))
   {
    warn("That file is no HAKTAR save of this (or compatible) version !!!");
    Close((BPTR)fh);
    return;
   }
  check=Read((BPTR)fh,(char *)&pc,sizeof(struct charakter));
  if(check!=sizeof(struct charakter)) clos("Load Error !");
  if(pc.eachmovemem)
   {
    pc.eachmovemem=(char *)AllocMem(pc.eachmovesize,0L);
    if(!pc.eachmovemem)
     {
      warn("No Memory for eachmove !");
      Close((BPTR)fh);
      return;
     }
    check=Read((BPTR)fh,pc.eachmovemem,(size_t)pc.eachmovesize);
    if(check!=pc.eachmovesize)
     {
      warn("Read Error !");
      Close((BPTR)fh);
      return;
     }
   }
  loadlist(fh,(void **)&(pc.firstflag),sizeof(struct item));
  loadlist(fh,(void **)&(pc.firstvar),sizeof(struct var));
  rpoint=pc.firstroom;
  rprev=&(pc.firstroom);
  while(rpoint)
   {
    rpoint=AllocMem(sizeof(struct raum),MEMF_CLEAR);
    *rprev=rpoint;
    if(!rpoint) clos("No memory for room !");
    rprev=&(rpoint->nextraum);
    check=Read((BPTR)fh,(char *)rpoint,sizeof(struct raum));
    if(check!=sizeof(struct raum))
     {
      rpoint->nextraum=NULL;
      clos("Load Error !!!!");
     }
    loadlist(fh,(void **)&(rpoint->firstitem),sizeof(struct item));
    rpoint=rpoint->nextraum;
   }
  rpoint=pc.firstmultifile;
  rprev=&(pc.firstmultifile);
  while(rpoint)
   {
    rpoint=AllocMem(sizeof(struct raum),MEMF_CLEAR);
    *rprev=rpoint;
    if(!rpoint) clos("No memory for multifile !");
    rprev=&(rpoint->nextraum);
    check=Read((BPTR)fh,(char *)rpoint,sizeof(struct raum));
    if(check!=sizeof(struct raum))
     {
      rpoint->nextraum=NULL;
      clos("Load Error !!!!");
     }
    loadlist(fh,(void **)&(rpoint->firstitem),sizeof(struct item));
    rpoint=rpoint->nextraum;
   }
  Close((BPTR)fh);
  if(xfont) CloseFont(xfont);
  xfont=OpenDiskFont(&xtstyle);
  if(!xfont) warn("Can't open special font !");
  msimpleface();
  mem=loaditem(pc.subpic,&size);
  if(mem)
   {
    showilbm(mem,(ULONG)size,0,SHOWSUB);
    FreeMem(mem,size);
   }
 }

void choose(char **act)
 {
  char c[78];
  struct item *point,*p,**prev;
  
  if(!*(choices[clevel]) && (clevel==0 || *(choices[clevel-1])))
   {
    doactives=FALSE;
    point=AllocMem(sizeof(struct item),NULL);
    readarg(act,point->name,(UBYTE)(ATSTRING|ATSHORT));
    point->nextitem=NULL;
    p=clist;
    prev=&clist;
    while(p)
     {
      prev=&(p->nextitem);
      p=p->nextitem;
     }
    *prev=point;
    ueberlesenklam(act);
    job=JCHOOSE;
/*    strcpy(actitem,pc.raum);
*/    cprob=TRUE;
    return;
   }
  readarg(act,c,(UBYTE)(ATSTRING|ATSHORT));
  if(strcmp(c,choices[clevel]))
   {
    ueberlesenklam(act);
   }
  else doactives=TRUE;
 }

void startchoose(char **act)
 {
  clevel++;
  if(clevel>9) clos("More than 10 choose levels!");
 }

void endchoose(char **act)
 {
  clevel--;
  if(clevel<-1) clos("More endchoose-commands than startchoose-commands!");
 }

void printvar(char **act)
 {
  char text1[78],text2[78],var[81];
  char out[200];
  
  readarg(act,text1,(UBYTE)(ATNAME|ATSHORT));
  readarg(act,var,(UBYTE)(ATNAME|ATLONG));
  readarg(act,text2,(UBYTE)(ATNAME|ATSHORT));
 
  if(!doactives) return;
  sprintf(out,"%s %ld %s",text1,findvar(var)->val,text2);
  out[80]=0;
  outp(out);
 }

void noautowait(char **act)
 {
  outmode=10;
 }

void locoff(char **act)
 {
  pc.locflag=FALSE;
 }

void locon(char **act)
 {
  pc.locflag=TRUE;
 }

void font(char **act)
 {
  if(xfont) CloseFont(xfont);
  readarg(act,pc.fontname,(UBYTE)(ATSTRING|ATLONG));
  xfont=OpenDiskFont(&xtstyle);
  if(!xfont) warn("Can't open special font !");
 }
  
void printfile(char **act)
 {
  char *buffer;
  char str[81];
  long size;
  int i;
  char *point;
  
  readarg(act,str,(UBYTE)(ATSTRING|ATLONG));
  if(!doactives) return;

  buffer=loaditem(str,&size);
  if(!buffer) return;
  point=buffer;
  while(*point)
   {
    i=0;
    while(*point!='\n' && *point && i<81)
     {
      str[i]=*point;
      point++;
      i++;
     }
    str[i]=0;
    outp(str);
    if(*point) point++;
   }
  FreeMem(buffer,size);
 }

void getphrase(char **act)
 {
  readarg(act,pc.getphrase,(UBYTE)(ATSTRING|ATSHORT));
 }

void dropphrase(char **act)
 {
  readarg(act,pc.dropphrase,(UBYTE)(ATSTRING|ATSHORT));
 }

void cantgetphrase(char **act)
 {
  readarg(act,pc.nogetphrase,(UBYTE)(ATSTRING|ATMEDIUM));
 }

void multi(char **act)
 {
  char file[81];
  struct raum *multif;
  BOOL oldact;
  
  oldact=doactives;
  do
   {
    readarg(act,file,(UBYTE)(ATNAME|ATLONG));
    if(*file)
     {
      multif=AllocMem(sizeof(struct raum),MEMF_CLEAR);
      if(!multif) clos("No memory for multifilelistheadstructure !");
      multif->nextraum=pc.firstmultifile;
      pc.firstmultifile=multif;
      strcpy(multif->name,file);
      doactives=FALSE;
      analyse(file,NULL,NULL,NULL,&(multif->firstitem));
      doactives=oldact;
     }
   }
  while(*file);
 }

void thing(char **act,struct item **firstinfile,char *thingy)
 {
  char name[78];
  struct item *mfthing;
  
  if(!firstinfile && !thingy)
   {
    ueberlesenklam(act);
    return;
   }
  readarg(act,name,(UBYTE)(ATNAME|ATSHORT));
  if(thingy)
   {
    if(strcmp(name,thingy)) ueberlesenklam(act);
   }
  else if(firstinfile)
   {
    if(!findvar(name))
     {
      mfthing=AllocMem(sizeof(struct item),MEMF_CLEAR);
      if(!mfthing) clos("No memory for thing !");
      strcpy(mfthing->name,name);
      mfthing->nextitem=*firstinfile;
      *firstinfile=mfthing;
      ueberlesenklam(act);
     }
   }
 }

void eachmove(char **act)
 {
  char newname[81];
  
  readarg(act,newname,(UBYTE)(ATSTRING|ATLONG));
  
  if(strcmp(pc.eachmovename,newname))
   {
    strcpy(pc.eachmovename,newname);
    if(*newname)
     {
      pc.eachmovemem=loaditem(pc.eachmovename,&pc.eachmovesize);
      if(!pc.eachmovemem) clos("eachmove() : Can't load !");
     }
    else
     {
      FreeMem(pc.eachmovemem,pc.eachmovesize);
      pc.eachmovemem=NULL;
      pc.eachmovesize=NULL;
     }
   }
 }

struct var *findvar(char *var)
 {
  struct var *point;
  
  point=pc.firstvar;
  while(point)
   {
    if(!strcmp(var,point->name)) break;
    else point=point->nextvar;
   }
  return point;
 }

void storevars(char **act)
 {
  struct var *p;
  char file[81];
  BPTR fh;
  long check;

  readarg(act,file,(UBYTE)(ATNAME|ATLONG));
  if(!doactives) return;

  fh=Open(file,(long)MODE_NEWFILE);
  if(!fh) clos("Can't open var-file! Disk or memory full?");
  do
   {
    readarg(act,file,(UBYTE)(ATNAME|ATLONG));
    if(*file)
     {
      p=findvar(file);
      if(!p)
       {
        p=AllocMem(sizeof(struct var),NULL);
        if(!p) clos("No memory for var !O)");
        p->nextvar=pc.firstvar;
        pc.firstvar=p;
        strcpy(p->name,file);
        p->val=0;
       }
      check=Write(fh,(char *)&(p->val),(long)sizeof(long));
      if(check!=sizeof(long))
       {
        warn("Disk or RAM full!!");
        warn("This could result in some errors!");
        return;
       }
     }
   }
  while(p&&*file);
  Close(fh);
 }

void getvars(char **act)
 {
  struct var *p;
  char file[81];
  BPTR fh;
  long check;
  long val;
  BOOL cont;
  
  readarg(act,file,(UBYTE)(ATNAME|ATLONG));
  if(!doactives) return;

  fh=Open(file,(long)MODE_OLDFILE);
  if(!fh) clos("Can't find var-file!");
  do
   {
    check=Read(fh,(char *)&val,(long)sizeof(long));
    readarg(act,file,(UBYTE)(ATNAME|ATLONG));
    if(!*file) cont=FALSE;
    if(check==sizeof(long))
     {
      p=findvar(file);
      if(!p)
       {
        p=AllocMem(sizeof(struct var),NULL);
        if(!p) clos("No memory for var !-^)");
        p->nextvar=pc.firstvar;
        pc.firstvar=p;
        strcpy(p->name,file);
       }
      p->val=val;
     }
   }
  while(cont);
  Close(fh);
 }

void setvar(char **act)
 {
  char var[81],num[78];
  struct var *p;
  
  readarg(act,var,(UBYTE)(ATNAME|ATLONG));
  readarg(act,num,(UBYTE)(ATINTEGER|ATSHORT));
  
  p=findvar(var);
  if(!p)
   {
    p=AllocMem(sizeof(struct var),NULL);
    if(!p) clos("No memory for var !");
    p->nextvar=pc.firstvar;
    pc.firstvar=p;
    strcpy(p->name,var);
   }
  p->val=atol(num);
 }

void addvar(char **act)
 {
  char var[81],num[78];
  struct var *p;
  
  readarg(act,var,(UBYTE)(ATNAME|ATLONG));
  readarg(act,num,(UBYTE)(ATINTEGER|ATSHORT));
  if(!doactives) return;
  
  p=findvar(var);
  if(!p)
   {
    p=AllocMem(sizeof(struct var),NULL);
    if(!p) clos("No memory for var !");
    p->nextvar=pc.firstvar;
    pc.firstvar=p;
    strcpy(p->name,var);
    p->val=0;
   }
  p->val+=atol(num);
 }

void ifchance(char **act)
 {
  char arg[78];
  long sec,mic;

  CurrentTime(&sec,&mic);
  for(;mic>0;mic-=600) RangeRand(100L);
  readarg(act,arg,(UBYTE)(ATINTEGER|ATSHORT));
  iffi(act,(RangeRand(100L)+1)<=atol(arg));
 }

void ifvar(char **act)
 {
  char var[81],low[78],high[78];
  struct var *p;
  long val;
  
  readarg(act,var,(UBYTE)(ATNAME|ATLONG));
  readarg(act,low,(UBYTE)(ATINTEGER|ATSHORT));
  readarg(act,high,(UBYTE)(ATINTEGER|ATSHORT));
  
  p=findvar(var);
  if(!p) val=0;
  else val=p->val;
  if(*high)
   {
    iffi(act,!(atol(low)>val || atol(high)<val));
   }
  else
   {
    iffi(act,atol(low)<=val);
   }
 }

void items(char **act,struct item **list)
 {
  struct item *point,**prev;
  BOOL args;
  char dumdum[78];
  
  if(!list)
   {
    do
     {
      readarg(act,dumdum,(UBYTE)(ATNAME|ATSHORT));
     }
    while(*dumdum);
    return;
   }
  prev=list;
  if(*list)
   {
    point=*list;
    while(point)
     {
      prev=&(point->nextitem);
      point=point->nextitem;
     }
   }
  do
   {
    point=AllocMem(sizeof(struct item),NULL);
    readarg(act,point->name,(UBYTE)(ATNAME|ATSHORT));
    if(!(*(point->name)))
     {
      FreeMem(point,sizeof(struct item));
      *prev=NULL;
      args=FALSE;
     }
    else
     {
      *prev=point;
      prev=&(point->nextitem);
      args=TRUE;
     }
   }
  while(args);
 }

void fdo(char **act,struct item **list,char *doer)
 {
  struct item *point,**prev;
  char arg[78];
  
  if(!list)
   {
    if(doer)
     {
      readarg(act,arg,(UBYTE)(ATSTRING|ATSHORT));
      if(strcmp(doer,arg)) ueberlesenklam(act);
     }
    else
     {
      ueberlesenklam(act);
     }
    return;
   }
  prev=list;
  if(*list)
   {
    point=*list;
    while(point)
     {
      prev=&(point->nextitem);
      point=point->nextitem;
     }
   }
  if(!doer)
   {
    point=AllocMem(sizeof(struct item),NULL);
    readarg(act,point->name,(UBYTE)(ATSTRING|ATSHORT));
    *prev=point;
    prev=&(point->nextitem);
    point->nextitem=NULL;
    ueberlesenklam(act);
   }
  else
   {
    readarg(act,arg,(UBYTE)(ATSTRING|ATSHORT));
    if(strcmp(doer,arg)) ueberlesenklam(act);
   }
 }

void ifflag(char **act)
 {
  char arg[81];
  struct item *point;
  BOOL found;
  
  readarg(act,arg,(UBYTE)(ATNAME|ATLONG));
  
  point=pc.firstflag;
  found=FALSE;
  while(point)
   {
    if(!strcmp(arg,point->name)) found=TRUE;
    point=point->nextitem;
   }
  iffi(act,found);
 }

void iftime(char **act)
 {
  char low[78],high[78];
  long ilow,ihigh;
  
  readarg(act,low,(UBYTE)(ATINTEGER|ATSHORT));
  readarg(act,high,(UBYTE)(ATINTEGER|ATSHORT));
  
  ilow=atol(low);
  if(*high)
   {
    ihigh=atol(high);
    iffi(act,!(ilow>pc.time || ihigh<pc.time));
   }
  else iffi(act,ilow<=pc.time);
 }

void ifin(char **act)
 {
  char arg[78];
  
  readarg(act,arg,(UBYTE)(ATNAME|ATSHORT));
  iffi(act,!strcmp(arg,pc.raum));
 }

void ifinput(char **act)
 {
  char arg[81];
  
  readarg(act,arg,(UBYTE)(ATNAME|ATLONG));
  iffi(act,!strcmp(arg,pc.lastinput));
 }

void ifweight(char **act)
 {
  char arg[78];
  
  readarg(act,arg,(UBYTE)(ATINTEGER|ATSHORT));
  iffi(act,pc.weight+atol(arg)<=pc.maxweight);
  if(pc.weight+atol(arg)>pc.maxweight) ueberlesenstri(act);
 }
 
void ifitemin(char **act)
 {
  char item[78],room[78];

  readarg(act,item,(UBYTE)(ATNAME|ATSHORT));
  readarg(act,room,(UBYTE)(ATNAME|ATSHORT));
  if(!strcmp(room,"INVACT"))
   {
    if(mifitemin(item,pc.raum)) strcpy(room,pc.raum);
    else *room=0;
   }
  iffi(act,mifitemin(item,room));
 }

BOOL mifitemin(char *itm,char *room)
 {
  struct item *point,*freepoint;
  struct raum *rpoint;
  BOOL found,noroom,oldact;
  struct item *its;
  
  oldact=doactives;
  found=FALSE;
  noroom=TRUE;
  rpoint=pc.firstroom;
  while(rpoint)
   {
    if(!strcmp(rpoint->name,room))
     {
      noroom=FALSE;
      point=rpoint->firstitem;
      break;
     }
    rpoint=rpoint->nextraum;
   }
  if(noroom)
   {
    its=NULL;
    rpoint=AllocMem(sizeof(struct raum),MEMF_CLEAR);
    if(!rpoint) clos("No memory for room !");
    strncpy(rpoint->name,room,(size_t)81);
    rpoint->nextraum=pc.firstroom;
    pc.firstroom=rpoint;
    rpoint->firstitem=NULL;
    strcpy(rpoint->name,room);
    doactives=FALSE;
    analyse(room,&(rpoint->firstitem),NULL,NULL,NULL);
    doactives=oldact;
    point=rpoint->firstitem;
   }
  while(point)
   {
    if(!strcmp(point->name,itm)) found=TRUE;
    point=point->nextitem;
   }
  return found;
 }

void sys(char **act)
 {
  char specification[81];
  
  readarg(act,specification,(UBYTE)(ATSTRING|ATLONG));
  if(!doactives) return;
  if(strcmp(specification,"Xample")) warn("1-2-3-4-5 Test 1-2-3");
 }

void doscall(char **act)
 {
  char com[81];
  BPTR fhn;

  fhn=0;
  
  fhn=Open("NIL:",(long)MODE_NEWFILE);
  if(!fhn) {warn("Can't open NIL:!");return;}
  readarg(act,com,(UBYTE)(ATNAME|ATLONG));
  if(!doactives) return;
  Execute(com,0L,fhn);
  Close(fhn);
 }

void execute(char **act)
 {
  char file[81];
  
  readarg(act,file,(UBYTE)(ATNAME|ATLONG));
/*  doactives=TRUE;
*/  analyse(file,NULL,NULL,NULL,NULL);
 }

void headpath(char **act)
 {
  readarg(act,pc.realheadpath,(UBYTE)(ATNAME|ATLONG));
  if(!*(pc.headpath)) strcpy(pc.headpath,pc.realheadpath);
  headex();
 }

void maxweight(char **act)
 {
  char string[78];
  
  readarg(act,string,(UBYTE)(ATINTEGER|ATSHORT));
  pc.maxweight=atol(string);
 }

void go(char **act,MEBOOL eachmoved)
 {
  readarg(act,pc.raum,(UBYTE)(ATNAME|ATSHORT));
  fnamecpy(pc.outraum,pc.raum);
  if(pc.locflag) SetWindowTitles(MyWindow,pc.outraum,(char *)-1);
  turnover(eachmoved);
  gadup(NULL,STANDBASIS+0);
  donotkilllist=TRUE;
 }

void addweight(char **act)
 {
  char arg[78];
  
  readarg(act,arg,(UBYTE)(ATINTEGER|ATSHORT));
  if(!doactives) return;
  pc.weight+=atol(arg);
 }

void addtime(char **act)
 {
  char arg[78];
  
  readarg(act,arg,(UBYTE)(ATINTEGER|ATSHORT));
  if(!doactives) return;
  pc.time+=atol(arg);
 }

void settime(char **act)
 {
  char arg[78];
  
  readarg(act,arg,(UBYTE)(ATINTEGER|ATSHORT));
  pc.time=atol(arg);
 }

void dead(char **act)
 {
  pc.raum[0]=0;
  job=JDEAD;
  SetWindowTitles(MyWindow,"Haktar V1.6 by Guido Wegener           GAME OVER: Select Restart",(char *)-1);
  mwait((BOOL)TRUE);
  initpc();
  linit(NULL,TURNED);
  outp(NULL);
  outlines=0;
 }

void cprint(char **act)
 {
  char buffer[125];
  
  strcpy(buffer,"                                                     ");
  readarg(act,&(buffer[40]),(UBYTE)(ATSTRING|ATMEDIUM));
  if(!doactives) return;
  outp(&(buffer[strlen(&(buffer[40]))/2+1]));
 }

void print(char **act)
 {
  char buffer[80];
  
  readarg(act,buffer,(UBYTE)(ATSTRING|ATMEDIUM));
  if(!doactives) return;
  outp(buffer);
 }

void rem(char **act)
 {
  char string[2];
  
  readarg(act,string,(UBYTE)(ATSTRING|ATXL));
 }

void closesub()
 {
  if(subwindow)
   {
    CloseWindow(subwindow);
    subwindow=NULL;
   }
  if(subscreen)
   {
    CloseScreen(subscreen);
    subscreen=NULL;
   }
 }

void showpicsub(char **act)
 {
  char *mem;
  long size;
  char timelimit[78],mod;
  
  closesub();
  readarg(act,pc.subpic,(UBYTE)(ATNAME|ATLONG));
  if(!*(pc.subpic)) return;
  readarg(act,timelimit,(UBYTE)(ATINTEGER|ATSHORT));
  if(!doactives) return;

  closesub();
  mem=loaditem(pc.subpic,&size);
  if(mem)
   {
    if((GfxBase->NormalDisplayRows)>=256) mod=SHOWSUB;
    else mod=SHOWPIC;
    showilbm(mem,(ULONG)size,atoi(timelimit),mod);
    FreeMem(mem,size);
   }
 }

void showpic(char **act)
 {
  char filename[81];
  char *mem;
  long size;
  char timelimit[78];
  
  readarg(act,filename,(UBYTE)(ATNAME|ATLONG));
  readarg(act,timelimit,(UBYTE)(ATINTEGER|ATSHORT));
  if(!doactives) return;

  mem=loaditem(filename,&size);
  if(mem)
   {
    showilbm(mem,(ULONG)size,atoi(timelimit),SHOWPIC);
    FreeMem(mem,size);
   }
 }

void simpleface(char **act)
 {
  readarg(act,pc.interface,(UBYTE)(ATNAME|ATLONG));
  if(!doactives) return;
  if(*(pc.interface))
   {
    msimpleface();
   }
  else
   {
    restyle();
   }
 }

void msimpleface()
 {
  char *mem;
  long size;
  
  mem=loaditem(pc.interface,&size);
  if(mem)
   {
    showilbm(mem,(ULONG)size,0,SHOWFACE);
    FreeMem(mem,size);
   }
 }

void input(char **act)
 {
  struct IntuiMessage *imsg=NULL;

  if(!doactives) return;

  outp(NULL);
  Request(&inpreq,MyWindow);
  Wait(1L<<MyWindow->UserPort->mp_SigBit);
  ReplyMsg(GetMsg(MyWindow->UserPort));
  ActivateGadget(&inpgad,MyWindow,&inpreq);

  Wait(1L<<MyWindow->UserPort->mp_SigBit);
  while(imsg=(struct IntuiMessage *)GetMsg(MyWindow->UserPort)) ReplyMsg((struct Message *)imsg);
  
  strcpy(pc.lastinput,(char *)inpgadinf.Buffer);
 }

void setflag(char **act)
 {
  struct item *point;
  char arg[81];
  BOOL alreadythere;
  
  readarg(act,arg,(UBYTE)(ATNAME|ATLONG));
  
  alreadythere=FALSE;
  point=pc.firstflag;
  while(point)
   {
    if(!strcmp(point->name,arg))
     {
      alreadythere=TRUE;
      break;
     }
    point=point->nextitem;
   }
  
  if(!alreadythere)
   {
    point=AllocMem(sizeof(struct item),NULL);
    if(!point) clos("No Memory for new flag !");
    strncpy(point->name,arg,(size_t)81);
    point->nextitem=pc.firstflag;
    pc.firstflag=point;
   }
 }

void textwait(char **act)
 {
  if(!doactives) return;
  mwait(outmode==1);
 }

void delflag(char **act)
 {
  struct item *point,**prev;
  char arg[81];
  
  readarg(act,arg,(UBYTE)(ATNAME|ATLONG));
  
  point=pc.firstflag;
  prev=&pc.firstflag;
  while(point)
   {
    if(!strcmp(point->name,arg))
     {
      *prev=point->nextitem;
      FreeMem(point,sizeof(struct item));
      point=*prev;
     }
    else
     {
      prev=&(point->nextitem);
      point=point->nextitem;
     }
   }
 }

void mixme(char *dest,char *string,char *replacer)
 {
  int i;
  
  if(*string)
   {
    i=0;
    do
     {
      if(*string=='§')
       {
        strncpy(&(dest[i]),replacer,(size_t)(81-i));
        i+=strlen(replacer);
        string++;
       }
      else
       {
        dest[i]=*string;
        string++;
        i++;
       }
     }
    while(*string && i<81);
   }
  dest[i]=0;
 }

void handle(char **act,char *filen,struct item **list,char *doer)
 {
  struct item *point,**prev;
  char arg[78];
  long int weight;
  char fullphrase[81];
  
  readarg(act,arg,(UBYTE)(ATINTEGER|ATSHORT));
  weight=atol(arg);
  if(doer)
   {
    if(!strcmp(doer,lastgetphrase))
     {
      if(pc.weight+weight>pc.maxweight)
       {
        mixme(fullphrase,pc.nogetphrase,filen);
        outp(fullphrase);
       }
      else
       {
        mgone(filen,pc.raum);
        mcreate(filen,"");
        pc.weight+=weight;
       }
     }
    if(!strcmp(doer,lastdropphrase))
     {
      mgone(filen,"");
      mcreate(filen,pc.raum);
      pc.weight-=weight;
     }
   }
  if(list)
   {
    prev=list;
    if(*list)
     {
      point=*list;
      while(point)
       {
        prev=&(point->nextitem);
        point=point->nextitem;
       }
     }
    if(!doer)
     {
      if(mifitemin(filen,""))
       {
        point=AllocMem(sizeof(struct item),NULL);
        mixme(lastdropphrase,pc.dropphrase,filen);
        strcpy(point->name,lastdropphrase);
        *prev=point;
        prev=&(point->nextitem);
        point->nextitem=NULL;
       }
      if(mifitemin(filen,pc.raum))
       {
        point=AllocMem(sizeof(struct item),NULL);
        mixme(lastgetphrase,pc.getphrase,filen);
        strcpy(point->name,lastgetphrase);
        *prev=point;
        prev=&(point->nextitem);
        point->nextitem=NULL;
       }
     }
   }
 }

void move(char **act)
 {
  char itm[78],from[78],where[78];
  
  readarg(act,itm,(UBYTE)(ATNAME|ATSHORT));
  readarg(act,from,(UBYTE)(ATNAME|ATSHORT));
  readarg(act,where,(UBYTE)(ATNAME|ATSHORT));
  if(!doactives) return;
  
  mgone(itm,from);
  mcreate(itm,where);
 }

void gone(char **act)
 {
  char itm[78],where[78];

  readarg(act,itm,(UBYTE)(ATNAME|ATSHORT));
  readarg(act,where,(UBYTE)(ATNAME|ATSHORT));
  if(!doactives) return;
  if(!strcmp(where,"INVACT"))
   {
    if(mifitemin(itm,pc.raum)) mgone(itm,pc.raum);
    else mgone(itm,"");
   }
  else mgone(itm,where);
 }

void mgone(char *itm,char *where)
 {
  struct item *point,**prev;
  struct raum *rpoint;
  BOOL found,oldact;
  
  oldact=doactives;
  found=FALSE;
  rpoint=pc.firstroom;
  while(rpoint)
   {
    if(!strcmp(rpoint->name,where))
     {
      found=TRUE;
      point=rpoint->firstitem;
      prev=&(rpoint->firstitem);
      while(point)
       {
        if(!strcmp(point->name,itm))
         {
          *prev=point->nextitem;
          FreeMem(point,sizeof(struct item));
          break;
         }
        prev=&point->nextitem;
        point=point->nextitem;
       }
     }
    rpoint=rpoint->nextraum;
   }
  if(!found)
   {
    rpoint=AllocMem(sizeof(struct raum),MEMF_CLEAR);
    strncpy(rpoint->name,where,(size_t)81);
    rpoint->nextraum=pc.firstroom;
    pc.firstroom=rpoint;
    doactives=FALSE;
    analyse(where,&(rpoint->firstitem),NULL,NULL,NULL);
    doactives=oldact;
    point=rpoint->firstitem;
    prev=&(rpoint->firstitem);
    while(point)
     {
      if(!strcmp(point->name,itm))
       {
        *prev=point->nextitem;
        FreeMem(point,sizeof(struct item));
        break;
       }
      prev=&point->nextitem;
      point=point->nextitem;
     }
   }
 }

void create(char **act)
 {
  char itm[78],where[78];

  readarg(act,itm,(UBYTE)(ATNAME|ATSHORT));
  readarg(act,where,(UBYTE)(ATNAME|ATSHORT));
  if(!doactives) return;
  mcreate(itm,where);
 }

void mcreate(char *itm,char *where)
 {
  struct item *point;
  struct raum *rpoint;
  BOOL found,oldact;
  
  found=FALSE;
  oldact=doactives;
  rpoint=pc.firstroom;
  while(rpoint)
   {
    if(!strcmp(rpoint->name,where))
     {
      point=AllocMem(sizeof(struct item),NULL);
      strncpy(point->name,itm,(size_t)81);
      point->nextitem=rpoint->firstitem;
      rpoint->firstitem=point;
      found=TRUE;
      break;
     }
    rpoint=rpoint->nextraum;
   }
  if(!found)
   {
    rpoint=AllocMem(sizeof(struct raum),MEMF_CLEAR);
    if(!rpoint) clos("No memory for room !");
    strncpy(rpoint->name,where,(size_t)81);
    rpoint->nextraum=pc.firstroom;
    pc.firstroom=rpoint;
    rpoint->firstitem=NULL;
    strcpy(rpoint->name,where);
    doactives=FALSE;
    analyse(where,&(rpoint->firstitem),NULL,NULL,NULL);
    doactives=oldact;
    point=AllocMem(sizeof(struct item),NULL);
    if(!point) warn("No memory for new item !");
    strncpy(point->name,itm,(size_t)81);
    point->nextitem=rpoint->firstitem;
    rpoint->firstitem=point;
   }
 }

