/*
 *      ADVINIT.C - Initialization routines for Collosal Cave Adventure
 *      (C) 1986 Ravi Bhavnani
 *      All rights reserved
 */

#include "adv.h"

char	*decode();
char	buffer[128],
	code[128],
	outstring[128];
int	ctrly_handler();
long	iochannel;

init()
/*
 *      CHECK IF HE'S RUNNING A BOOTLEG BINARY.  IF NOT, BEGIN TO LOAD THE
 *      DATAFILES, INIT THE parrayS AND oarrayS, AND VARIOUS VARIABLES.
 */
{
int     derf;
string	s;
static $DESCRIPTOR (sys$input, "SYS$INPUT");

        check_if_bootleg();

        printf ("A few moments, please");

        if (debug)
           printf ("...\n\n");

	/* SET THE VERSION NUMBER */

	major = MAJOR;
	minor = MINOR;
	release = RELEASE;

        /* KICK THE RANDOM NUMBER GENERATOR */

        srand ((unsigned) time(NULL));

        /* LOAD DATABASE AND INIT THE ARRAYS */

        memused = 0;
        load_files();
        init_parrays();
        init_oarrays();

        /* ALL VARS ARE ZERO UNLESS OTHERWISE SPECIFIED - CAMEOTIME DONE LAST */

        arg1 = arg2 = context = null;
        here = prevloc = road;
        dwarfcount = random(3) + 3;
        clock = random(10) + 15;
        invct = 0;
        strength = 7;
        lamplife = 300;
	extended = 1;

	/* INITIALIZE SMG$ ROUTINES */

	smg$create_virtual_keyboard (&kbd_id, 0, 0, 0);
	smg$create_key_table (&ktbl_id);

	/* DISABLE CTRL/Y */

	newcmask = 0x02000000;
	lib$disable_ctrl (&newcmask, &oldcmask);
	if (sys$assign (&sys$input, &iochannel, 0, 0) != SS$_NORMAL)
	   {
	     printf ("Error in SYS$ASSIGN call");
	     exit();
	   }
	if (sys$qiow (0,iochannel,IO$_SETMODE | IO$M_CTRLCAST | IO$M_CTRLYAST,0,0,0,ctrly_handler,0,0,0,0,0)
	    != SS$_NORMAL)
	   {
	     printf ("Error in SYS$QIOW call");
	     exit();
	   }

        if (debug)
           {
             printf ("\nPress RETURN to continue... ");
             gets (s);
           }

        cls();
}


check_if_bootleg()
/*
 *      FOR NOW DON'T DO ANYTHING.
 */
{
        return;
}


load_files()
/*
 *      LOAD MESSAGE TEXTS, LONG AND SHORT PLACE DESCRIPTIONS, VOCABULARY
 *      AND OBJECT DESCRIPTIONS.
 */
{
char	digitstring [9];
t_struct
        *tptr;          /* pointer to text structure */
int     centry,         /* current text entry # */
        pentry,         /* previous text entry # */
        nlines;         /* # lines read from file */
static $DESCRIPTOR
	(resultdesc, "");
static $DESCRIPTOR
	(in_desc, "");
static $DESCRIPTOR
	(out_desc, "");
static $DESCRIPTOR
	(buff_desc, "");
static $DESCRIPTOR
	(code_desc, "");
static int
	len;
int	derf, gronk;

	/* SETUP FILESPECS */

	resultdesc.dsc$a_pointer = dat_dir;
	resultdesc.dsc$w_length = STRINGLEN;
	if (lib$sys_trnlog (&adv$dat, &len, &resultdesc, 0, 0, 0) == SS$_NORMAL)
	   dat_dir[len] = '\0';
	else
	   {
	     strcpy (dat_dir, str);	/* str contains argv[0] put in by main() */
	     for (derf=strlen(dat_dir); (derf); derf--)
	         if (dat_dir[derf-1]==']')
	            break;
	     dat_dir[derf] = '\0';
	     for (derf=0; (derf<strlen(dat_dir)); derf++)
	         if (islower(dat_dir[derf]))
	            dat_dir[derf] -= 32;
	   }

/*	printf ("\nDatafile dir is /%s/\n", dat_dir); */

	strcpy (msgfile, dat_dir);
	strcat (msgfile, MSGFILE);
	strcpy (objfile, dat_dir);
	strcat (objfile, OBJFILE);
	strcpy (shortfile, dat_dir);
	strcat (shortfile, SHORTFILE);
	strcpy (longfile, dat_dir);
	strcat (longfile, LONGFILE);
	strcpy (vocabfile, dat_dir);
	strcat (vocabfile, VOCABFILE);

	/* CREATE CODE */

	strcpy (buffer, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.,;!?@#$%^&*()_+={}[]|\/");
	srand (1234);
	gronk=0;
	while (gronk < strlen(buffer))
	    {
	      derf = rand() % strlen(buffer);
	      if (buffer[derf] != '~')
	         {
	           code[gronk++] = buffer[derf];
	           buffer[derf]= '~';
	         }
	    }
	code [gronk] = '\0';
	strcpy (buffer, "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ.,;!?@#$%^&*()_+={}[]|\/");

	/* SETUP DESCRIPTORS FOR TRANSLATION */

	in_desc.dsc$a_pointer = str;
	out_desc.dsc$a_pointer = outstring;
	buff_desc.dsc$a_pointer = buffer;
	code_desc.dsc$a_pointer = code;
	buff_desc.dsc$w_length = strlen(buffer);
	code_desc.dsc$w_length = strlen(code);

        /* LOAD MESSAGE TEXTS */

        if ((f = fopen (msgfile, "r")) == NULL)
           bug (CANTOPENMSGFILE);
        pentry = -1;
        nlines = centry = nmsgs = 0;

        while (fgets (str, STRINGLEN, f) != NULL)
            {

	      /* DECRYPT STRING */

              nlines++;
              str [strlen(str) - 1] = '\0';

	      in_desc.dsc$w_length = strlen(str);
	      out_desc.dsc$w_length = 128;
	      str$translate (&out_desc, &in_desc, &buff_desc, &code_desc);
	      outstring [strlen(str)] = '\0';
	      strcpy (str, outstring);

              /* GET MESSAGE # */

              for (derf=0; (derf < 8); derf++)
                  digitstring [derf] = str [derf];
              digitstring [derf] = '\0';
              if (!sscanf (digitstring, "%d", &centry))
                 bug (BADMSGFILE);

              /* MAKE tptr POINT TO APPROPRIATE NODE */

              if (centry != pentry)
                 {
                   nmsgs = pentry = centry;
                   if (nmsgs == MAXMESSAGES)
                      bug (TOOMANYMSGS);
                   tptr = &(msg [nmsgs]);
                 }
              else
                 if ((tptr->next = (t_struct *)calloc (1, sizeof(t_struct))) == NULL)
                    bug (NOTENUFMSGMEM);
                 else
                    {
                      tptr = tptr->next;
                      memused += sizeof(t_struct);
                    }

              /* STORE TEXT */

              tptr->line = malloc (strlen(str)-6);
              if (tptr->line==NULL)
                 bug (NOTENUFMSGMEM);
              else
                 memused += strlen(str) -6;
              strcpy (tptr->line, &(str[8]) );

              tptr->next = NULL;
            }

        fclose (f);
        if (debug)
           printf ("%d lines, %d messages read from \"%s\"\n",nlines, nmsgs, MSGFILE);
	else
	   printf (".");

        /* LOAD LONG PLACE DESCRIPTIONS */

        if ((f = fopen (longfile, "r")) == NULL)
           bug (CANTOPENLONGFILE);
        pentry = -1;
        nlines = centry = nlongs = 0;
        while (fgets (str, STRINGLEN, f) != NULL)
            {

	      /* DECRYPT STRING */

              nlines++;
              str [strlen(str) - 1] = '\0';
	      in_desc.dsc$w_length = strlen(str);
	      out_desc.dsc$w_length = strlen(str);
	      str$translate (&out_desc, &in_desc, &buff_desc, &code_desc);
	      outstring [strlen(str)] = '\0';
	      strcpy (str, outstring);

              /* GET PLACE # */

              for (derf=0; (derf < 8); derf++)
                  digitstring [derf] = str [derf];
              digitstring [derf] = '\0';
              if (!sscanf (digitstring, "%d", &centry))
                 bug (BADLONGFILE);

              /* MAKE tptr POINT TO APPROPRIATE NODE */

              if (centry != pentry)
                 {
                   nlongs = pentry = centry;
                   if (nlongs == MAXPLACES)
                      bug (TOOMANYLONGS);
                   tptr = &(longp [nlongs]);
                 }
              else
                 if ((tptr->next = (t_struct *)calloc (1, sizeof(t_struct))) == NULL)
                    bug (NOTENUFLONGMEM);
                 else
                    {
                      tptr = tptr->next;
                      memused += sizeof(t_struct);
                    }

              /* STORE TEXT */

              tptr->line = malloc (strlen(str)-6);
              if (tptr->line==NULL)
                 bug (NOTENUFLONGMEM);
              else
                 memused += strlen(str) -6;
              strcpy (tptr->line, &(str[8]) );
              tptr->next = NULL;
            }

        fclose (f);
        if (debug)
           printf ("%d lines, %d long place descriptions read from \"%s\"\n",nlines, nlongs, LONGFILE);
	else
	   printf (".");

        /* LOAD SHORT PLACE DESCRIPTIONS */

        if ((f = fopen (shortfile, "r")) == NULL)
           bug (CANTOPENSHORTFILE);
        pentry = -1;
        nlines = centry = nshorts = 0;
        while (fgets (str, STRINGLEN, f) != NULL)
            {

	      /* DECRYPT STRING */

              nlines++;
              str [strlen(str) - 1] = '\0';
	      in_desc.dsc$w_length = strlen(str);
	      out_desc.dsc$w_length = strlen(str);
	      str$translate (&out_desc, &in_desc, &buff_desc, &code_desc);
	      outstring [strlen(str)] = '\0';
	      strcpy (str, outstring);

              /* GET PLACE # */

              for (derf=0; (derf < 8); derf++)
                  digitstring [derf] = str [derf];
              digitstring [derf] = '\0';
              if (!sscanf (digitstring, "%d", &centry))
                 bug (BADSHORTFILE);

              /* MAKE tptr POINT TO APPROPRIATE NODE */

              if (centry != pentry)
                 {
                   nshorts = pentry = centry;
                   if (nshorts == MAXPLACES)
                      bug (TOOMANYSHORTS);
                   tptr = &(shortp [nshorts]);
                 }
              else
                 if ((tptr->next = (t_struct *)calloc (1, sizeof(t_struct))) == NULL)
                    bug (NOTENUFSHORTMEM);
                 else
                    {
                      tptr = tptr->next;
                      memused += sizeof(t_struct);
                    }

              /* STORE TEXT */

              tptr->line = malloc (strlen(str)-6);
              if (tptr->line==NULL)
                 bug (NOTENUFSHORTMEM);
              else
                 memused += strlen(str) -6;
              strcpy (tptr->line, &(str[8]) );
              tptr->next = NULL;
            }

        fclose (f);
        if (debug)
           printf ("%d lines, %d short place descriptions read from \"%s\"\n",nlines, nshorts, SHORTFILE);
	else
	   printf (".");

        /* LOAD VOCABULARY */

        if ((f = fopen (vocabfile, "r")) == NULL)
           bug (CANTOPENVOCABFILE);
        nlines = centry = nvocab = 0;
        while (fgets (str, STRINGLEN, f) != NULL)
            {

	      /* DECRYPT STRING */

              nlines++;
              str [strlen(str) - 1] = '\0';
	      in_desc.dsc$w_length = strlen(str);
	      out_desc.dsc$w_length = strlen(str);
	      str$translate (&out_desc, &in_desc, &buff_desc, &code_desc);
	      outstring [strlen(str)] = '\0';
	      strcpy (str, outstring);

              /* GET WORD # */

              for (derf=0; (derf < 8); derf++)
                  digitstring [derf] = str [derf];
              digitstring [derf] = '\0';
              if (!sscanf (digitstring, "%d", &centry))
                 bug (BADVOCABFILE);

              /* STORE THE WORD AND ITS INDEX */

              if (nvocab < MAXVOCAB)
                 {
                   vocab [nvocab].meaning = centry;
                   if (strlen (&(str[8])) < WORDLEN)
                      strcpy (vocab [nvocab].word, &(str[8]) );
                   else
                      bug (BADVOCABWORD);
                   nvocab++;
                 }
              else
                 bug (VOCAB2BIG);
            }

        fclose (f);
        if (debug)
           printf ("%d lines, %d words read from \"%s\"\n", nlines, nvocab, VOCABFILE);
	else
	   printf (".");

        /* LOAD OBJECT DESCRIPTIONS */

        if ((f = fopen (objfile, "r")) == NULL)
           bug (CANTOPENOBJFILE);
        nlines = centry = nobj = 0;
        while (fgets (str, STRINGLEN, f) != NULL)
            {

	      /* DECRYPT STRING */

              nlines++;
              str [strlen(str) - 1] = '\0';
	      in_desc.dsc$w_length = strlen(str);
	      out_desc.dsc$w_length = strlen(str);
	      str$translate (&out_desc, &in_desc, &buff_desc, &code_desc);
	      outstring [strlen(str)] = '\0';
	      strcpy (str, outstring);

              /* GET OBJECT # */

              for (derf=0; (derf < 8); derf++)
                  digitstring [derf] = str [derf];
              digitstring [derf] = '\0';
              if (!sscanf (digitstring, "%d", &centry))
                 bug (BADOBJFILE);

              /* IF NEW OBJECT, STORE ITS INVENTORY DESCRIPTION */

              if (centry >= 0)
                 if (centry < MAXOBJECTS)
                    {
                      nobj = centry;
                      pentry = 0;
                      if ((obj[nobj].invdesc = malloc (strlen(str)-6)) == NULL)
                         bug (NOTENUFOBJMEM);
                      else
                         memused += strlen(str)-6;

                      strcpy (obj[nobj].invdesc, &(str[8]) );
                      for (derf=0; (derf < MAXVALS); derf++)
                          {
                            obj[nobj].vdesc[derf].line = NULL;
                            obj[nobj].vdesc[derf].next = NULL;
                          }
                    }
                 else
                    bug (TOOMANYOBJECTS);
              else

              /* ELSE STORE A NEW VIEW DESCRIPTION... */

                 if (pentry != centry)
                    {
                      pentry = centry;
                      centry = -centry - 1;
                      if (centry < MAXVALS)
                         {
                           tptr = &(obj[nobj].vdesc[centry]);
                           tptr->line = malloc (strlen(str)-6);
                           if (tptr->line==NULL)
                              bug (NOTENUFOBJMEM);
                           else
                              memused += strlen(str) -6;
                           strcpy (tptr->line, &(str[8]));
                           tptr->next = NULL;
                         }
                      else
                         bug (OBJ2MANYVALS);
                    }
                 else

              /* ...OR CONTINUE AN OLD ONE (AS THE CASE MAY BE) */

                    {
                      if ((tptr->next = (t_struct *)calloc (1, sizeof(t_struct))) == NULL)
                         bug (NOTENUFOBJMEM);
                      else
                         {
                           tptr = tptr->next;
                           memused += sizeof (t_struct);
                         }
                      tptr->line = malloc (strlen(str)-6);
                      if (tptr->line==NULL)
                         bug (NOTENUFOBJMEM);
                      else
                         memused += strlen(str) -6;
                      strcpy (tptr->line, &(str[8]));
                      tptr->next = NULL;
                    }
            }

        fclose (f);
        if (debug)
           printf ("%d lines, %d objects read from \"%s\"\n", nlines, nobj, OBJFILE);
}


init_parrays()
/*
 *      INITIALIZE THE PLACE ARRAYS.
 */
{
int     derf;

        /* FIRST, THE ASSUMPTIONS.  NOTE, THESE MAY NOT BE REQUIRED.
           CHECK YOUR COMPILER. */

        for (derf=road; (derf <= limbo); derf++)
            {
              lit [derf] = 0;
              visited [derf] = 0;
              nodwarf [derf] = 0;
              noback [derf] = 0;
              notincave [derf] = 0;
              hintable [derf] = 0;
              h2ohere [derf] = 0;
              inmaze [derf] = 0;
              onexit [derf] = 0;
              thrower [derf] = 0;
            }

        /* UNDERGROUND LOCATIONS THAT ARE OUT OF LIMITS FOR DWARVES */

        nodwarf [incave] = 1;
        nodwarf [cobbles] = 1;
        nodwarf [alcove] = 1;
        nodwarf [plover] = 1;
        nodwarf [dark] = 1;
        nodwarf [swofchasm] = 1;
        nodwarf [neofchasm] = 1;
        nodwarf [corridor] = 1;
        nodwarf [fork] = 1;
        nodwarf [warmjunction] = 1;
        nodwarf [breathtaker] = 1;
        nodwarf [boulders] = 1;
        nodwarf [limestone] = 1;
        nodwarf [barren] = 1;
        nodwarf [bearhere] = 1;
        nodwarf [mazea_26] = 1;		/* treasure chest here */
        nodwarf [eastpit] = 1;
        nodwarf [westpit] = 1;
        nodwarf [streampit] = 1;
        nodwarf [faces] = 1;
        nodwarf [by_figure] = 1;
        nodwarf [plain_1] = 1;
        nodwarf [plain_2] = 1;
        nodwarf [plain_3] = 1;
        nodwarf [nondescript] = 1;
        nodwarf [pentagram] = 1;
        nodwarf [chimney] = 1;
        nodwarf [tube] = 1;
        nodwarf [tube_slide] = 1;
        nodwarf [basque_1] = 1;
        nodwarf [basque_2] = 1;
        nodwarf [basque_fork] = 1;
        nodwarf [peelgrunt] = 1;
        nodwarf [on_steps] = 1;
        nodwarf [steps_exit] = 1;
        nodwarf [storage] = 1;
        nodwarf [fake_y2] = 1;
        nodwarf [fake_jumble] = 1;
        for (derf=catacombs_1; (derf <= catacombs_9); derf++)
            nodwarf [derf] = 1;
        nodwarf [audience] = 1;
        nodwarf [audience_e] = 1;
        nodwarf [banshee_1] = 1;
        nodwarf [golden] = 1;
        nodwarf [arabesque] = 1;
        nodwarf [translucent] = 1;
        nodwarf [reservoir_n] = 1;
        nodwarf [warm] = 1;
        nodwarf [balcony] = 1;
        nodwarf [insafe] = 1;
	nodwarf [belowtrap] = 1;
	nodwarf [emergency] = 1;
	nodwarf [southend] = 1;

        /* ALL THE ROOMS IN THE MAZES ARE noback TYPES TO GIVE THE
           ADVENTURER HEARTBURN AND A POSSIBLE ULCER, WITH THE EXCEPTION
           OF mazea_1 AND mazed_107, WHICH ARE THE ENTRANCES TO THE
           MAZES.  THIS WAY, IF HE ACCIDENTALLY WANDERS INTO A MAZE HE CAN
           ESCAPE QUICKLY BY SAYING "GO BACK". */

        for (derf=mazea_2; (derf <= mazea_26); derf++)
            noback [derf] = 1;
        for (derf=mazed_131; (derf <= mazed_140); derf++)
            noback [derf] = 1;
        noback [incline] = 1;
        noback [stalact] = 1;
        noback [swofchasm] = 1;
        noback [neofchasm] = 1;
        noback [wittsend] = 1;
        noback [alcove] = 1;
        noback [plover] = 1;
        noback [dark] = 1;
        noback [nscanyonwide] = 1;
        for (derf=icecave_1; (derf <= icecave_21); derf++)
            noback [derf] = 1;
        noback [slide] = 1;
        noback [ice] = 1;
        for (derf=catacombs_1; (derf <= catacombs_19); derf++)
            noback [derf] = 1;
        noback [faces] = 1;
        noback [plain_1] = 1;
        noback [plain_2] = 1;
        noback [basque_1] = 1;
        noback [cylinderical] = 1;
        noback [platform] = 1;
	noback [mirrorroom] = 1;

        /* SO HE CAN'T SNEAK OUT WITH THE CLAM */
        noback [shell] = 1;

        /* SO HE CAN'T RETREAT OVER THE QUICKSAND */
        noback [arch_cor_1] = 1;
        noback [arch_cor_2] = 1;

        /* THESE PLACES ARE OUTSIDE THE CAVE */

        notincave [road] = 1;
        notincave [hill] = 1;
        notincave [building] = 1;
        notincave [valley] = 1;
        notincave [forest] = 1;
        notincave [forest2] = 1;
        notincave [slit] = 1;
        notincave [depression] = 1;
        notincave [fake_slit] = 1;
	notincave [nearstove] = 1;
	notincave [hayfield] = 1;

        /* SELF ILLUMINATED ROOMS */

        for (derf=road; (derf < limbo); derf++)
            if (notincave[derf])
               lit [derf] = 1;
        lit [incave] = 1;
        lit [cobbles] = 1;
        lit [plover] = 1;
        lit [breathtaker] = 1;
        lit [shelf] = 1;
        lit [beach] = 1;
        lit [plain_2] = 1;
        lit [plain_3] = 1;
        lit [faces] = 1;
        lit [by_figure] = 1;
        lit [audience] = 1;
        lit [audience_e] = 1;
        lit [translucent] = 1;
        lit [platform] = 1;
        lit [cylinderical] = 1;
        lit [treasureroom] = 1;
        lit [balcony] = 1;
	lit [belowtrap] = 1;
	lit [emergency] = 1;

        /* HINTS ARE AVAILABLE HERE */

        for (derf=mazea_1; (derf <= mazea_26); derf++)
            hintable [derf] = 1;
        for (derf=mazed_107; (derf <= mazed_140); derf++)
            hintable [derf] = 1;
        for (derf=icecave_1; (derf <= icecave_30); derf++)
            hintable [derf] = 1;
        hintable [birdchamber] = 1;
        hintable [depression] = 1;
        hintable [mtking] = 1;
        hintable [wittsend] = 1;
        hintable [plover] = 1;
        hintable [alcove] = 1;
        hintable [dark] = 1;
        hintable [slide] = 1;
        hintable [plain_2] = 1;
	hintable [mirrorroom] = 1;
	hintable [nearstove] = 1;

        /* THESE ARE THE WATERING HOLES */

        h2ohere [building] = 1;
        h2ohere [road] = 1;
        h2ohere [valley] = 1;
        h2ohere [slit] = 1;
        h2ohere [streampit] = 1;
        h2ohere [cavern] = 1;
        h2ohere [reservoir] = 1;
        h2ohere [reservoir_n] = 1;

        /* MARK THE MAZES */

        for (derf=mazea_1; (derf <= mazea_26); derf++)
            inmaze [derf] = 1;
        for (derf=mazed_107; (derf <= mazed_140); derf++)
            inmaze [derf] = 1;
        for (derf=icecave_1; (derf <= icecave_30); derf++)
            inmaze [derf] = 1;
        inmaze [slide] = 1;

        /* SINGLE-EXIT ROOMS */

        onexit [goldroom] = 1;
        onexit [southside] = 1;
        onexit [sandstone] = 1;
        onexit [window] = 1;
        onexit [window2] = 1;
        onexit [mazea_5] = 1;
        onexit [mazea_6] = 1;
        onexit [mazea_7] = 1;
        onexit [mazea_13] = 1;
        onexit [mazea_15] = 1;
        onexit [mazea_17] = 1;
        onexit [mazea_19] = 1;
        onexit [mazea_20] = 1;
        onexit [mazea_24] = 1;
        onexit [mazea_25] = 1;
        onexit [mazea_26] = 1;
        onexit [deadend1] = 1;
        onexit [deadend2] = 1;
        onexit [deadend3] = 1;
        onexit [soft] = 1;
        onexit [culdesac] = 1;
        onexit [reservoir] = 1;
        onexit [balcony] = 1;
        onexit [mazed_140] = 1;
        onexit [insafe] = 1;
        onexit [tool] = 1;
        onexit [cubicle] = 1;
        onexit [spherical] = 1;
        onexit [icecave_1] = 1;
        onexit [icecave_3] = 1;
        onexit [icecave_7] = 1;
        onexit [icecave_8] = 1;
        onexit [icecave_13] = 1;
        onexit [icecave_14] = 1;
        onexit [crack_4] = 1;
        onexit [beach] = 1;
	onexit [southend] = 1;

        /* THROWING OBJECTS HERE SENDS THEM ELSEWHERE */

        thrower [pit] = 1;
        thrower [eastoffissur] = 1;
        thrower [westoffissur] = 1;
        thrower [wend2pit] = 1;
        thrower [eend2pit] = 1;
        thrower [lownspassage] = 1;
        thrower [window] = 1;
        thrower [window2] = 1;
        thrower [brink] = 1;
        thrower [dusty] = 1;
        thrower [mazea_16_pit] = 1;
        thrower [secretnscyn] = 1;
        thrower [secretnspas] = 1;
        thrower [secretew_tite] = 1;
        thrower [incline] = 1;
        thrower [cavern] = 1;
        thrower [misty] = 1;
        thrower [reservoir] = 1;
        thrower [reservoir_n] = 1;
        thrower [stalact] = 1;
        thrower [balcony] = 1;
        thrower [swofchasm] = 1;
        thrower [neofchasm] = 1;
        thrower [breathtaker] = 1;
        thrower [faces] = 1;
        thrower [tube] = 1;
        thrower [tube_slide] = 1;
        thrower [basque_fork] = 1;
        thrower [on_steps] = 1;
        thrower [steps_exit] = 1;
        thrower [brink_1] = 1;
        thrower [brink_2] = 1;
        thrower [brink_3] = 1;
        thrower [ice] = 1;
        thrower [shelf] = 1;
        thrower [platform] = 1;
	thrower [nslope] = 1;
}


init_oarrays()
/*
 *      INITIALIZE THE OBJECT ARRAYS.
 */
{
int     derf;

        for (derf=MINOBJECTS; (derf <= MAXOBJECTS); derf++)
            {
              portable [derf] = 1;
              seen [derf] = 0;
              valued [derf] = 0;
              mortal [derf] = 0;
              openable [derf] = 0;
              invisible [derf] = 0;
              weightless [derf] = 0;
              special1 [derf] = 0;
              special2 [derf] = 0;
              where_is [derf] = limbo;
              firstdesc [derf] = 0;
              val [derf] = 0;
            }

        /* ALL OBJECTS EXCEPT THESE ARE PORTABLE */

        portable [basilisk] = 0;
        portable [blob] = 0;
/*	portable [carpet] = 0;		snide message if he tries */
        portable [chasm] = 0;
        portable [dinghy] = 0;
        portable [djinn] = 0;
        portable [door] = 0;
        portable [dragon] = 0;
        portable [drawing] = 0;
        portable [dwarf] = 0;
        portable [fissure] = 0;
        portable [fog] = 0;
        portable [glow] = 0;
        portable [goblins] = 0;
        portable [gong] = 0;
        portable [wheatstone] = 0;
        portable [grate] = 0;
        portable [machine] = 0;
        portable [message] = 0;
        portable [mirror] = 0;
        portable [ogre] = 0;
        portable [pirate] = 0;
        portable [plant] = 0;
        portable [plant2] = 0;
        portable [quicksand] = 0;
        portable [safe] = 0;
        portable [shadow] = 0;
        portable [skeleton] = 0;
        portable [slime] = 0;
        portable [snake] = 0;
        portable [stalactite] = 0;
        portable [statue] = 0;
        portable [steps] = 0;
        portable [tablet] = 0;
        portable [throne] = 0;
        portable [tree] = 0;
        portable [troll] = 0;
        portable [troll2] = 0;
        portable [volcano] = 0;
        portable [_pentagram] = 0;
	portable [stove] = 0;
	portable [trapdoor] = 0;
	portable [mirror2] = 0;
	portable [sign] = 0;
	portable [turtle] = 0;

        /* MARK THE TREASURES */

        for (derf=MINTREASURES; (derf <= MAXTREASURES); derf++)
            valued [derf] = 1;

        /* THESE ARE KILLABLE THINGS */

        for (derf=MINMORTALS; (derf <= MAXMORTALS); derf++)
            mortal [derf] = 1;
        mortal [turtle] = 1;

        /* THESE OBJECTS CAN BE OPENED/CLOSED/UNLOCKED/LOCKED */

        openable [grate] = 1;
        openable [door] = 1;
        openable [clam] = 1;
        openable [oyster] = 1;
        openable [flask] = 1;
        openable [chain] = 1;
        openable [safe] = 1;
        openable [vial] = 1;
	openable [_pentagram] = 1;
	openable [stove] = 1;
	openable [trapdoor] = 1;

        /* THESE ARE INVISIBLE OBJECTS */

        invisible [fissure] = 1;
        invisible [pirate] = 1;
        invisible [knife] = 1;
	invisible [fog] = 1;
        invisible [plant2] = 1;
        invisible [wheatstone] = 1;
        invisible [goblins] = 1;
	invisible [scroll] = 1;
	invisible [trapdoor] = 1;
	invisible [needle] = 1;

	/* THESE OBJECTS ARE *NEVER* DESCRIBED */

	nodesc [tree] = 1;
	nodesc [mirror] = 1;
	nodesc [quicksand] = 1;
	nodesc [throne] = 1;
	nodesc [dwarf] = 1;
	nodesc [_pentagram] = 1;
	nodesc [fog] = 1;
	nodesc [glow] = 1;
	nodesc [statue] = 1;
	nodesc [blob] = 1;
	nodesc [volcano] = 1;
	nodesc [turtle] = 1;
	nodesc [carpet] = 1;
	nodesc [treasure] = 1;
	nodesc [wheatstone] = 1;	/* INITIALLY - CHANGED LATER IN CODE */
	nodesc [mirror2] = 1;
	nodesc [drawing] = 1;
        nodesc [stalactite] = 1;

        /* THESE ARE FREEBIES */

        weightless [bird] = 1;
        weightless [oil] = 1;
        weightless [water] = 1;
        weightless [bear] = 1;
        weightless [knife] = 1;

        /* THESE SHOULD BE DESCRIBED *FIRST* */

        firstdesc [slime] = 1;
        firstdesc [flask] = 1;
        firstdesc [grate] = 1;
        firstdesc [glow] = 1;
        firstdesc [snake] = 1;
        firstdesc [dragon] = 1;
        firstdesc [basilisk] = 1;
        firstdesc [steps] = 1;
        firstdesc [fissure] = 1;
        firstdesc [bear] = 1;
        firstdesc [shadow] = 1;
        firstdesc [door] = 1;
        firstdesc [tablet] = 1;
        firstdesc [plant] = 1;
        firstdesc [plant2] = 1;
        firstdesc [chasm] = 1;
/*	firstdesc [troll] = 1;		chasm should be described before troll */
        firstdesc [volcano] = 1;
        firstdesc [machine] = 1;
/*	firstdesc [carpet] = 1;		since it's nodesc[] */
        firstdesc [safe] = 1;
        firstdesc [quicksand] = 1;
        firstdesc [gong] = 1;
        firstdesc [mirror] = 1;
        firstdesc [statue] = 1;
        firstdesc [skeleton] = 1;
	firstdesc [dinghy] = 1;
	firstdesc [stove] = 1;
	firstdesc [scroll] = 1;
	firstdesc [trapdoor] = 1;
        firstdesc [mirror2] = 1;
	firstdesc [sign] = 1;

        /* INITIAL VALUES OF OBJECTS */

        val [chain] = 1;
        val [fog] = 8;
        val [flask] = 1;
	val [sculpture] = 2 * random(3);

        /* MOVE OBJECTS TO THEIR STARTING PLACES */

#define apport(x,y)     where_is [x] = y

        apport (keys, building);
        apport (lamp, building);
        apport (grate, depression);
        apport (cage, cobbles);
        apport (rod, debris);
        apport (steps, pit);
        apport (bird, birdchamber);
        apport (door, immensenspass);
        apport (pillow, soft);
        apport (snake, mtking);
        apport (fissure, eastoffissur);
        apport (tablet, dark);
        apport (clam, shell);
        apport (magazines, anteroom);
        apport (food, building);
        apport (bottle, building);
        apport (plant, westpit);
        apport (plant2, wend2pit);
        apport (stalactite, stalact);
        apport (shadow, window);
        apport (drawing, oriental);
        apport (dragon, secretnscyn);
        apport (rug, secretnscyn);
        apport (chasm, swofchasm);
        apport (troll, swofchasm);
        apport (bear, bearhere);
        apport (volcano, breathtaker);
        apport (machine, mazed_140);
        apport (carpet, soft);
        apport (gold, goldroom);
        apport (diamonds, westoffissur);
        apport (silver, lownspassage);
        apport (jewelry, southside);
        apport (coins, westside);
        apport (eggs, giant);
        apport (trident, cavern);
        apport (vase, oriental);
        apport (emerald, plover);
        apport (pyramid, dark);
        apport (spices, boulders);
        apport (chain, bearhere);
        apport (spyglass, in_jonah);
        apport (bag, beach);
        apport (dinghy, beach);
        apport (helmet, morion);
        apport (vial, spherical);
        apport (mushroom, cubicle);
        apport (sculpture, icecave_20);
        apport (casket, crack_4);
        apport (safe, vault);
        apport (quicksand, arch_cor_1);
        apport (slime, crack_2);
        apport (sword, sandstone);
        apport (ogre, glassy);
        apport (throne, audience_e);
        apport (skeleton, audience_e);
        apport (sceptre, audience_e);
        apport (crown, insafe);
        apport (statue, by_figure);
        apport (fog, plain_2);
        apport (yacht, nondescript);
        apport (bracelet, translucent);
        apport (flask, arabesque);
        apport (basilisk, basque_1);
        apport (plate, storage);
        apport (beads, balcony);
        apport (gong, reservoir_n);
        apport (mirror, mirrorcnyn);
	apport (_pentagram, pentagram);
	apport (wheatstone, breathtaker);
	apport (stove, nearstove);
	apport (scroll, nearstove);
	apport (trapdoor, nearstove);
	apport (mirror2, mirrorroom);
	apport (shovel, deadend1);
	apport (sign, belowtrap);
	apport (needle, hayfield);

	/* SETUP CAMEO APPEARANCE */

/*	cameotime = (chance(20) ? random(400) + 100 : 0);	*/
	cameotime = (chance(40) ? random(400) + 100 : 0);
}

ctrly_handler()
{
	dbg ("ctrly_handler()\n");
	sys$qiow (0,iochannel,(IO$_SETMODE | IO$M_CTRLCAST | IO$M_CTRLYAST),
	          0,0,0,ctrly_handler,0,0,0,0,0);
	finis();
}
