[comp.sources.games] v02i066: umoria - single player dungeon simulation, Part01/16

games-request@tekred.TEK.COM (11/05/87)

Submitted by: "James E. Wilson" <wilson@ji.berkeley.edu>
Comp.sources.games: Volume 2, Issue 66
Archive-name: umoria/Part01

	[Here it is!  A Unix version of the popular VMS game
	 Moria.  I have called this archive 'umoria', rather
	 than 'moria' to distinguish it from the original
	 VMS version (in case somewon volunteers to send me
	 the VMS version for posting).     -br]

[[Moria is a dungeon adventure game in the manner of rogue, but
not descended from rogue.  Moria is to VMS systems, as rogue
is to UNIX.  The game has been successfully compiled on a VAX running
4.3BSD, SUN 3/50 running UNIX 4.2 Release 3.2, and a microvax running
ULTRIX 2.0.]]

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 16)."
# Contents:  README MANIFEST Highscores INSTALL moria2.c
# Wrapped by billr@tekred on Wed Nov  4 09:59:33 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README\"
else
echo shar: Extracting \"README\" \(2444 characters\)
sed "s/^X//" >README <<'END_OF_README'
XUNIX Moria 4.85
X(Differences from 4.85 to 4.84 are mostly minor bug fixes, and better
X portability.)
X
XMoria is a dungeon adventure game in the manner of rogue, but
Xnot descended from rogue.  Moria is to VMS systems, as rogue
Xis to UNIX.
X
X-------------------------------------------------------------
X
XThis is my first official release.  Work is still in progress.
XThis project started in February '87, and play testing started in early April.
XBug reports from my playtesters have become relatively infrequent,
Xso the game should be relatively stable now.
X
XPlease send bug reports and/or fixes to wilson@ernie.Berkeley.EDU
XSave file formats may change again.
X
XThis version of Moria is based on the original 4.8 VMS Pascal sources
Xwritten by Robert Koeneke, Jimmey Todd, Gary McAdoo and others at
Xthe University of Oklahoma.  I have converted the program into C
Xfor BSD Unix.  The program has since been slowly diverging from the
Xoriginal game as I have 'fixed' things that didn't seem to be right.
XMajor changes of note are incompatible save file formats (who cares?)
Xand an optional rogue-like user interface for my UNIX version as opposed
Xto a numeric keypad interface for the VMS version.
X
XTo avoid confusion, you may want to refer to this as UNIX Moria,
Xor perhaps wilson moria.
X
XMike Callahan at the University of Oklahoma (seismo!okstate!uokmax!mikec)
Xalso is working on a Unix version of Moria and is planning on posting
Xit to the net when it is finished.  This will probably be more official
Xthan my version, but I have not heard from him in a while.
X
XDon Kneller has ported the program to the IBM PC, and is calling it PCMORIA.
X
XMy thanks to Dave Chin and Dave desJardins of Berkeley for playtesting the
Xearly versions and making many suggestions.  Thanks also to Craig Norborg
Xof Purdue for rewritting the setuid/scoreboard code in a more rational
Xmanner.
X
XThere exists another port of Moria to UNIX that was done by wex@MCC.COM.
XHopefully, our two versions can be merged, but don't expect to see the result
Xfor a while.
X
X					Jim Wilson
X					wilson@ernie.Berkeley.EDU
X					ucbvax!ucbernie!wilson
X
XThe program has three options.  The -r option changes the game to 
Xuse a rogue like user interface.  The -o option forces the game to use
Xthe original user interface.  The -s option prints the scoreboard
Xand exits.
X
XThere is no man page yet, and the original VMS Moria docs should be rewritten
Xto take into account some of the changes.
X
END_OF_README
if test 2444 -ne `wc -c <README`; then
    echo shar: \"README\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f MANIFEST -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"MANIFEST\"
else
echo shar: Extracting \"MANIFEST\" \(1614 characters\)
sed "s/^X//" >MANIFEST <<'END_OF_MANIFEST'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X Highscores                1	
X INSTALL                   1	
X MANIFEST                  1	This shipping list
X MISC_NOTES                6	
X Makefile.43              16	
X Makefile.USG             12	
X Makefile.ultrix          11	
X Moria_hours              10	
X Moria_news                6	
X PROBLEMS                 15	
X README                    1	
X config.h                  2	
X constants.h              16	
X create.c                 11	
X creature.c               12	
X death.c                   7	
X desc.c                    5	
X dungeon.c                 8	
X eat.c                    16	
X externs.h                 4	
X files.c                  14	
X generate.c               14	
X help.c                    9	
X io.c                     15	
X magic.c                   6	
X main.c                   15	
X makelog                   3	
X misc1.c                  10	
X misc2.c                   9	
X monsters.c                6	
X moria.doc.1              11	
X moria.doc.2               4	
X moria1.c                  5	
X moria2.c                  1	
X potions.c                15	
X prayer.c                 16	
X save.c                   12	
X scrolls.c                10	
X sets.c                   16	
X signals.c                16	
X spells.c                  3	
X staffs.c                 16	
X store1.c                 15	
X store2.c                 13	
X treasure1.c               2	
X treasure2.c              13	
X types.h                  15	
X variables.c               7	
X wands.c                  16	
X wizard.c                  8	
END_OF_MANIFEST
if test 1614 -ne `wc -c <MANIFEST`; then
    echo shar: \"MANIFEST\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f Highscores -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"Highscores\"
else
echo shar: Extracting \"Highscores\" \(0 character\)
sed "s/^X//" >Highscores <<'END_OF_Highscores'
END_OF_Highscores
if test 0 -ne `wc -c <Highscores`; then
    echo shar: \"Highscores\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f INSTALL -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"INSTALL\"
else
echo shar: Extracting \"INSTALL\" \(1725 characters\)
sed "s/^X//" >INSTALL <<'END_OF_INSTALL'
XTo compile the program, edit the config.h file to change the
Xnames of the files the game uses and the wizard info.  For USG systems,
Xcopy Makefile.USG to Makefile.  For Ultrix (and 4.2BSD), copy Makefile.ultrix
Xto Makefile.  For 4.3BSD and SUNS copy Makefile.43 to Makefile.  Type make
Xto compile the game.  You may want to edit the 'Moria_hours' file
Xto indicate during what hours people are allowed to play the game.
XThe game needs to be installed setuid for the scoreboard to work.
XUse the command 'chmod 4511 moria' to do this.
X(Or just type 'make install' after setting BINDIR and LIBDIR in the
XMakefile to appropriate values.)
X
XThere are two choices for the key bindings, the original style and
Xa rogue-like style.  You can choose which one is to be the default
Xby changing the value of CFLAGS
X  -DKEY_BINDINGS=ORIGINAL for the original style
X  -DKEY_BINDINGS=ROGUE_LIKE for the rogue-like style
X
X
XIf the display does not look right, try adding -DBUGGY_CURSES to CFLAGS
X(as in the ultrix Makefile).  Delete io.o and moria.o, and then recompile.
X
XFor the IBM PC-RT, 3B2, 3B20, and perhaps others, you must
Xadd -DNO_SIGNED_CHARS to CFLAGS.
X
XYou can choose which default key bindings you wish to have by
Xchanging the definition of KEY_BINDINGS in the Makefile.
X  For rogue like -DKEY_BINDINGS=ROGUE_LIKE
X  For original style -DKEY_BINDINGS=ORIGINAL
X
XThe game has been successfully compiled on a VAX running 4.3BSD, 
XSUN 3/50 running UNIX 4.2 Release 3.2, and a microvax running ULTRIX 2.0.
XThe program assumes that ints are 32 bits, and that 
Xsizeof(char *) == sizeof(int).  The program passes lint
Xso further porting should not be too hard.
XBSD/UNIX dependencies are(?) limited to the files io.c, save.c, and
Xsignals.c.
X
END_OF_INSTALL
if test 1725 -ne `wc -c <INSTALL`; then
    echo shar: \"INSTALL\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f moria2.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"moria2.c\"
else
echo shar: Extracting \"moria2.c\" \(47938 characters\)
sed "s/^X//" >moria2.c <<'END_OF_moria2.c'
X#include <stdio.h>
X#ifdef USG
X#include <string.h>
X#else
X#include <strings.h>
X#endif
X
X#include "constants.h"
X#include "types.h"
X#include "externs.h"
X
X#ifdef sun   /* correct SUN stupidity in the stdio.h file */
Xchar *sprintf();
X#endif
X
X/* global flags */
Xextern int moria_flag;        /* Next level when true  */
Xextern int search_flag;       /* Player is searching   */
Xextern int teleport_flag;     /* Handle teleport traps  */
Xextern int player_light;      /* Player carrying light */
Xextern int cave_flag;         /* used in get_panel */
Xextern int light_flag;        /* used in move_light */
X
Xchar cur_char1();
X
X
X/* Teleport the player to a new location 		-RAK-	*/
Xteleport(dis)
Xint dis;
X{
X  int y, x;
X  cave_type *c_ptr;
X  int i, j;
X
X  do
X    {
X      y = randint(cur_height) - 1;
X      x = randint(cur_width) - 1;
X      while (distance(y, x, char_row, char_col) > dis)
X	{
X	  y += ((char_row-y)/2);
X	  x += ((char_col-x)/2);
X	}
X    }
X  while ((!cave[y][x].fopen) || (cave[y][x].cptr >= 2));
X  move_rec(char_row, char_col, y, x);
X  for (i = char_row-1; i <= char_row+1; i++)
X    for (j = char_col-1; j <= char_col+1; j++)
X      {
X	c_ptr = &cave[i][j];
X	c_ptr->tl = FALSE;
X	if (!test_light(i, j)) 
X	  unlite_spot(i, j);
X      }
X  if (test_light(char_row, char_col)) 
X    lite_spot(char_row, char_col);
X  char_row = y;
X  char_col = x;
X  move_char(5);
X  creatures(FALSE);
X  teleport_flag = FALSE;
X}
X
X
X/* Player hit a trap...	(Chuckle)			-RAK-	*/
Xhit_trap(y, x)
Xint *y, *x;
X{
X  int i, ty, tx;
X  int dam;
X  cave_type *c_ptr;
X  struct misc *p_ptr;
X  
X  change_trap(*y, *x);
X  lite_spot(char_row, char_col);
X  find_flag = FALSE;
X  c_ptr = &cave[*y][*x];
X  p_ptr = &py.misc;
X  dam = damroll(t_list[c_ptr->tptr].damage);
X  switch(t_list[c_ptr->tptr].subval)
X    {
X    case 1:  /* Open pit*/ 
X      msg_print("You fell into a pit!");
X      if (py.flags.ffall) 
X	msg_print("You gently float down.");
X      else
X	take_hit(dam, "an open pit.");
X      break;
X    case 2: /* Arrow trap*/ 
X      if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac)) 
X	{
X	  take_hit(dam, "an arrow trap.");
X	  msg_print("An arrow hits you.");
X	}
X      else
X	msg_print("An arrow barely misses you.");
X      break;
X    case 3: /* Covered pit*/
X      msg_print("You fell into a covered pit.");
X      if (py.flags.ffall) 
X	msg_print("You gently float down.");
X      else
X	take_hit(dam, "a covered pit.");
X      place_trap(*y, *x, 2, 1);
X      break;
X    case 4: /* Trap door*/
X      msg_print("You fell through a trap door!");
X      msg_print(" ");
X      moria_flag = TRUE;
X      dun_level++;
X      if (py.flags.ffall) 
X	msg_print("You gently float down.");
X      else
X	take_hit(dam, "a trap door.");
X      break;
X    case 5: /* Sleep gas*/
X      if (py.flags.paralysis == 0) 
X	{
X	  msg_print("A strange white mist surrounds you!");
X	  if (py.flags.free_act) 
X	    msg_print("You are unaffected.");
X	  else
X	    {
X	      msg_print("You fall asleep.");
X	      py.flags.paralysis += randint(10) + 4;
X	    }
X	}
X      break;
X    case 6: /* Hid Obj*/
X      c_ptr->fm = FALSE;
X      pusht((int)c_ptr->tptr);
X      place_object(*y, *x);
X      msg_print("Hmmm, there was something under this rock.");
X      break;
X    case 7:  /* STR Dart*/
X      if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac)) 
X	{
X	  if (!py.flags.sustain_str) 
X	    {
X	      py.stats.cstr = de_statp(py.stats.cstr);
X	      take_hit(dam, "a dart trap.");
X	      print_stat |= 0x0001;
X	      msg_print("A small dart weakens you!");
X	    }
X	  else
X	    msg_print("A small dart hits you.");
X	}
X      else
X	msg_print("A small dart barely misses you.");
X      break;
X    case 8: /* Teleport*/
X      teleport_flag = TRUE;
X      msg_print("You hit a teleport trap!");
X      break;
X    case 9: /* Rockfall*/
X      take_hit(dam, "falling rock.");
X      pusht((int)c_ptr->tptr);
X      place_rubble(*y, *x);
X      msg_print("You are hit by falling rock");
X      break;
X    case 10: /* Corrode gas*/
X      corrode_gas("corrosion gas.");
X      msg_print("A strange red gas surrounds you.");
X      break;
X    case 11: /* Summon mon*/
X      c_ptr->fm = FALSE;        /* Rune disappears...    */
X      pusht((int)c_ptr->tptr);
X      c_ptr->tptr = 0;
X      for (i = 0; i < (2+randint(3)); i++)
X	{
X	  ty = char_row;
X	  tx = char_col;
X	  (void) summon_monster(&ty, &tx, FALSE);
X	}
X      break;
X    case 12: /* Fire trap*/
X      fire_dam(dam, "a fire trap.");
X      msg_print("You are enveloped in flames!");
X      break;
X    case 13: /* Acid trap*/
X      acid_dam(dam, "an acid trap.");
X      msg_print("You are splashed with acid!");
X      break;
X    case 14: /* Poison gas*/
X      poison_gas(dam, "a poison gas trap.");
X      msg_print("A pungent green gas surrounds you!");
X      break;
X    case 15: /* Blind Gas */
X      msg_print("A black gas surrounds you!");
X      py.flags.blind += randint(50) + 50;
X      break;
X    case 16: /* Confuse Gas*/
X      msg_print("A gas of scintillating colors surrounds you!");
X      py.flags.confused += randint(15) + 15;
X      break;
X    case 17: /* Slow Dart*/
X      if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac)) 
X	{
X	  take_hit(dam, "a dart trap.");
X	  msg_print("A small dart hits you!");
X	  py.flags.slow += randint(20) + 10;
X	}
X      else
X	msg_print("A small dart barely misses you.");
X      break;
X    case 18: /* CON Dart*/
X      if (test_hit(125, 0, 0, p_ptr->pac+p_ptr->ptoac)) 
X	{
X	  if (!py.flags.sustain_con) 
X	    {
X	      py.stats.ccon = de_statp(py.stats.ccon);
X	      take_hit(dam, "a dart trap.");
X	      print_stat |= 0x0004;
X	      msg_print("A small dart weakens you!");
X	    }
X	  else
X	    msg_print("A small dart hits you.");
X	}
X      else
X	msg_print("A small dart barely misses you.");
X      break;
X    case 19: /*Secret Door*/
X      break;
X    case 99: /* Scare Mon*/
X      break;
X
X      /* Town level traps are special,  the stores...	*/
X    case 101: /* General    */
X      enter_store(0);
X      break;
X    case 102: /* Armory     */
X      enter_store(1);
X      break;
X    case 103: /* Weaponsmith*/
X      enter_store(2);
X      break;
X    case 104: /* Temple     */
X      enter_store(3);
X      break;
X    case 105: /* Alchemy    */
X      enter_store(4);
X      break;
X    case 106: /* Magic-User */
X      enter_store(5);
X      break;
X      
X    default:
X      msg_print("Unknown trap value");
X      break;
X    }
X}
X
X
X/* Return spell number and failure chance		-RAK-	*/
X/* returns -1 if no spells in book
X   returns 1 if choose a spell in book to cast
X   returns 0 if don't choose a spell, i.e. exit with an escape */
Xint cast_spell(prompt, item_val, sn, sc, redraw)
Xchar *prompt;
Xint item_val;
Xint *sn, *sc;
Xint *redraw;
X{
X  unsigned int j;
X  int i, k;
X  spl_type spell;
X  int cast;
X  spell_type *s_ptr;
X
X  cast = -1;
X  i = 0;
X  j = inventory[item_val].flags;
X  do
X    {
X      k = bit_pos(&j);
X      if (k >= 0) 
X	{
X	  s_ptr = &magic_spell[py.misc.pclass][k];
X	  if (s_ptr->slevel <= py.misc.lev) 
X	    if (s_ptr->learned) 
X	      {
X		spell[i].splnum = k;
X		i++;
X	      }
X	}
X    }
X  while (j != 0);
X  if (i > 0) 
X    cast = get_spell(spell, i, sn, sc, prompt, redraw);
X  if (*redraw) 
X    draw_cave();
X  return(cast);
X}
X
X
X/* Finds range of item in inventory list 		-RAK-	*/
Xint find_range(item1, item2, j, k)
Xint item1, item2;
Xint *j, *k;
X{
X  int i;
X  int flag;
X
X  i = 0;
X  *j = -1;
X  *k = -1;
X  flag = FALSE;
X  while(i < inven_ctr)
X    {
X      if (((inventory[i].tval == item1)  || (inventory[i].tval == item2))
X	  && (!flag)) 
X	{
X	  flag = TRUE;
X	  *j = i;
X	}
X      if (((inventory[i].tval != item1) && (inventory[i].tval != item2))
X	  && (flag) && (*k == -1)) 
X	*k = i - 1;
X      i++;
X    }
X  if ((flag) && (*k == -1)) 
X    *k = inven_ctr - 1;
X  return(flag);
X}
X
X
X/* Examine a Book					-RAK-	*/
Xexamine_book()
X{
X  unsigned int j;
X  int i, k, item_val;
X  int redraw, flag;
X  char dummy;
X  vtype out_val;
X  treasure_type *i_ptr;
X  spell_type *s_ptr;
X
X  redraw = FALSE;
X  if (!find_range(90, 91, &i, &k)) 
X    msg_print("You are not carrying any books.");
X  else if (get_item(&item_val, "Which Book?", &redraw, i, k)) 
X    {
X      flag = TRUE;
X      i_ptr = &inventory[item_val];
X      if (class[py.misc.pclass].mspell) 
X	{
X	  if (i_ptr->tval != 90) 
X	    {
X	      msg_print("You do not understand the language.");
X	      flag = FALSE;
X	    }
X	}
X      else if (class[py.misc.pclass].pspell) 
X	{
X	  if (i_ptr->tval != 91) 
X	    {
X	      msg_print("You do not understand the language.");
X	      flag = FALSE;
X	    }
X	}
X      else
X	{
X	  msg_print("You do not understand the language.");
X	  flag = FALSE;
X	}
X      if (flag) 
X	{
X	  redraw = TRUE;
X	  i = 0;
X	  j = inventory[item_val].flags;
X	  clear_screen(0, 0);
X	  (void) strcpy(out_val,
X		 "   Name                         Level  Mana   Known");
X	  prt(out_val, 0, 0);
X	  do
X	    {
X	      k = bit_pos(&j);
X	      if (k >= 0) 
X		s_ptr = &magic_spell[py.misc.pclass][k];
X		  {
X		    if (s_ptr->slevel < 99) 
X		      {
X			(void) sprintf(out_val, "%c) %s%d     %d   %d", 97+i,
X				pad(s_ptr->sname, " ", 30), s_ptr->slevel,
X				s_ptr->smana, s_ptr->learned);
X			prt(out_val, i+1, 0);
X		      }
X		    else
X		      prt("", i+1, 0);
X		    i++;
X		  }
X	    }
X	  while (j != 0);
X	  prt("[Press any key to continue]", 23, 19);
X	  inkey(&dummy);
X	}
X    }
X  if (redraw)  draw_cave();
X}
X
X
X/* Player is on an object.  Many things can happen BASED -RAK-	*/
X/* on the TVAL of the object.  Traps are set off, money and most */
X/* objects are picked up.  Some objects, such as open doors, just*/
X/* sit there...                                                  */
Xcarry(y, x)
Xint y, x;
X{
X  int item_val;
X  vtype out_val, tmp_str;
X  cave_type *c_ptr;
X  treasure_type *i_ptr;
X
X  find_flag = FALSE;
X  c_ptr = &cave[y][x];
X  inventory[INVEN_MAX] = t_list[c_ptr->tptr];
X  /* There's GOLD in them thar hills!      */
X  if (t_list[c_ptr->tptr].tval == 100) 
X    {
X      pusht((int)c_ptr->tptr);
X      c_ptr->tptr = 0;
X      i_ptr = &inventory[INVEN_MAX];
X      py.misc.au += i_ptr->cost;
X      (void) sprintf(out_val, "You have found %d gold pieces worth of %s.",
X	      i_ptr->cost, i_ptr->name);
X      prt_gold();
X      msg_print(out_val);
X    }
X  /* OPPS!                                 */
X  else if ((t_list[c_ptr->tptr].tval == 101) || 
X	   (t_list[c_ptr->tptr].tval == 102) ||
X	   (t_list[c_ptr->tptr].tval == 109) ||
X	   (t_list[c_ptr->tptr].tval == 110))
X    hit_trap(&y, &x);
X  /* Attempt to pick up an object.         */
X  else if (t_list[c_ptr->tptr].tval < 100) 
X    {
X      if (inven_check_weight())     /* Weight limit check    */
X	if (inven_check_num())      /* Too many objects?     */
X	  {                       /* Okay,  pick it up      */
X	    pusht((int)c_ptr->tptr);
X	    c_ptr->tptr = 0;
X	    inven_carry(&item_val);
X	    objdes(tmp_str, item_val, TRUE);
X	    (void) sprintf(out_val, "You have %s (%c%c", tmp_str, item_val+97,
X		    cur_char1(item_val));
X	    msg_print(out_val);
X	  }
X	else
X	  msg_print("You can't carry that many items.");
X      else
X	msg_print("You can't carry that much weight.");
X    }
X}
X
X
X/* Drop an object being carried				-RAK-	*/
X/* Note: Only one object per floor spot...                       */
Xdrop()
X{
X  int com_val;
X  int redraw;
X  vtype out_val, tmp_str;
X  cave_type *c_ptr;
X
X  redraw = FALSE;
X  if (inven_ctr > 0) 
X    {
X      if (get_item(&com_val, "Which one? ", &redraw, 0, inven_ctr-1)) 
X	{
X	  if (redraw)  draw_cave();
X	  c_ptr = &cave[char_row][char_col];
X	  if (c_ptr->tptr != 0) 
X	    msg_print("There is something there already.");
X	  else
X	    {
X	      inven_drop(com_val, char_row, char_col);
X	      objdes(tmp_str, INVEN_MAX, TRUE);
X	      (void) sprintf(out_val, "Dropped %s", tmp_str);
X	      msg_print(out_val);
X	    }
X	}
X      else if (redraw) 
X	draw_cave();
X    }
X  else
X    msg_print("You are not carrying anything.");
X}
X
X
X/* Deletes a monster entry from the level		-RAK-	*/
Xdelete_monster(j)
Xint j;
X{
X  int i, k;
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X
X  i = muptr;
X  k = m_list[j].nptr;
X  if (i == j) 
X    muptr = k;
X  else
X    {
X      while (m_list[i].nptr != j)
X	i = m_list[i].nptr;
X      m_list[i].nptr = k;
X    }
X  m_ptr = &m_list[j];
X  cave[m_ptr->fy][m_ptr->fx].cptr = 0;
X  if (m_ptr->ml) 
X    {
X      c_ptr = &cave[m_ptr->fy][m_ptr->fx];
X      if ((c_ptr->pl) || (c_ptr->tl)) 
X	lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
X      else
X	unlite_spot((int)m_ptr->fy, (int)m_ptr->fx);
X      pushm(j);
X    }
X  if (mon_tot_mult > 0)
X    mon_tot_mult--;
X}
X
X
X/* Makes sure new creature gets lit up			-RAK-	*/
Xcheck_mon_lite(y, x)
Xint y, x;
X{
X  cave_type *c_ptr;
X
X  c_ptr = &cave[y][x];
X  if (c_ptr->cptr > 1) 
X    if (!m_list[c_ptr->cptr].ml) 
X      if ((c_ptr->tl) || (c_ptr->pl)) 
X	if (los(char_row, char_col, y, x)) 
X	  {
X	    m_list[c_ptr->cptr].ml = TRUE;
X	    lite_spot(y, x);
X	  }
X}
X
X
X/* Places creature adjacent to given location		-RAK-	*/
X/* Rats and Flys are fun!                                        */
Xmultiply_monster(y, x, z, slp)
Xint y, x, z;
Xint slp;
X{
X  int i, j, k;
X  cave_type *c_ptr;
X
X  i = 0;
X  do
X    {
X      j = y - 2 + randint(3);
X      k = x - 2 + randint(3);
X      if (in_bounds(j, k)) 
X	{
X	  c_ptr = &cave[j][k];
X	  if ((c_ptr->fval >= 1) && (c_ptr->fval <= 7 ) && (c_ptr->fval != 3))
X	    if ((c_ptr->tptr == 0) && (c_ptr->cptr != 1)) 
X	      {
X		if (c_ptr->cptr > 1)     /* Creature there already?       */
X		  {
X		    /* Some critters are cannibalistic!       */
X		    if (c_list[z].cmove & 0x00080000)
X		      {
X			delete_monster((int)c_ptr->cptr);
X			place_monster(j, k, z, slp);
X			check_mon_lite(j, k);
X			mon_tot_mult++;
X		      }
X		  }
X		else
X		  /* All clear,  place a monster    */
X		  {
X		    place_monster(j, k, z, slp);
X		    check_mon_lite(j, k);
X		    mon_tot_mult++;
X		  }
X		i = 18;
X	      }
X	}
X      i++;
X    }
X  while (i <= 18);
X}
X
X
X/* Creates objects nearby the coordinates given		-RAK-	  */
X/* BUG: Because of the range, objects can actually be placed into */
X/*      areas closed off to the player, this is rarely noticeable, */
X/*      and never a problem to the game.                          */
Xsummon_object(y, x, num, typ)
Xint y, x, num, typ;
X{
X  int i, j, k;
X  cave_type *c_ptr;
X
X  do
X    {
X      i = 0;
X      do
X	{
X	  j = y - 3 + randint(5);
X	  k = x - 3 + randint(5);
X	  if (in_bounds(j, k)) 
X	    {
X	      c_ptr = &cave[j][k];
X	      if ((c_ptr->fval >= 1) && (c_ptr->fval <= 7) &&
X		  (c_ptr->fval != 3))
X		if (c_ptr->tptr == 0) 
X		  {
X		    switch(typ)                 /* Select type of object */
X		      {
X		      case 1:  place_object(j, k); break;
X		      case 2:  place_gold(j, k); break;
X		      case 3:
X			if (randint(100) < 50) 
X			  place_object(j, k);
X			else
X			  place_gold(j, k);
X			break;
X		      default:
X			break;
X		      }
X		    if (test_light(j, k)) 
X		      lite_spot(j, k);
X		    i = 10;
X		  }
X	    }
X	  i++;
X	}
X      while (i <= 10);
X      num--;
X    }
X  while (num != 0);
X}
X
X
X/* Deletes object from given location			-RAK-	*/
Xint delete_object(y, x)
Xint y, x;
X{
X  int delete;
X  cave_type *c_ptr;
X
X  delete = FALSE;
X  c_ptr = &cave[y][x];
X  if ((t_list[c_ptr->tptr].tval == 109) || (t_list[c_ptr->tptr].tval == 105)
X      || (t_list[c_ptr->tptr].tval == 104))
X    c_ptr->fval = corr_floor2.ftval;
X  c_ptr->fopen = TRUE;
X  pusht((int)c_ptr->tptr);
X  c_ptr->tptr = 0;
X  c_ptr->fm = FALSE;
X  if (test_light(y, x)) 
X    {
X      lite_spot(y, x);
X      delete = TRUE;
X    }
X  else
X    unlite_spot(y, x);
X  return(delete);
X}
X
X
X/* Allocates objects upon a creatures death		-RAK-	*/
X/* Oh well,  another creature bites the dust...  Reward the victor*/
X/* based on flags set in the main creature record                */
Xmonster_death(y, x, flags)
Xint y, x;
Xunsigned int flags;
X{
X  int i;
X
X  if (flags & 0x01000000)
X    i = 1;
X  else
X    i = 0;
X  if (flags & 0x02000000)
X    i += 2;
X  if (flags & 0x04000000)
X    if (randint(100) < 60) 
X      summon_object(y, x, 1, i);
X  if (flags & 0x08000000)
X    if (randint(100) < 90) 
X      summon_object(y, x, 1, i);
X  if (flags & 0x10000000)
X    summon_object(y, x, randint(2), i);
X  if (flags & 0x20000000)
X    summon_object(y, x, damroll("2d2"), i);
X  if (flags & 0x40000000)
X    summon_object(y, x, damroll("4d3"), i);
X  if (flags & 0x80000000)
X    {
X      total_winner = TRUE;
X      prt_winner();
X      msg_print("*** CONGRATULATIONS *** You have won the game...");
X      msg_print("Use <CONTROL>-K when you are ready to quit.");
X    }
X}
X
X
X/* Decreases monsters hit points and deletes monster if needed.	*/
X/* (Picking on my babies...)                             -RAK-   */
Xint mon_take_hit(monptr, dam)
Xint monptr, dam;
X{
X  int i;
X  double acc_tmp;
X  monster_type *m_ptr;
X  struct misc *p_ptr;
X  creature_type *c_ptr;
X  int m_take_hit;
X
X  m_ptr = &m_list[monptr];
X  m_ptr->hp -= dam;
X  m_ptr->csleep = 0;
X  if (m_ptr->hp < 0) 
X    {
X      monster_death((int)m_ptr->fy, (int)m_ptr->fx,c_list[m_ptr->mptr].cmove);
X      c_ptr = &c_list[m_ptr->mptr];
X      p_ptr = &py.misc;
X      acc_tmp = c_ptr->mexp*((c_ptr->level+0.1)/p_ptr->lev);
X      i = (int)(acc_tmp);
X      acc_exp += (acc_tmp - i);
X      if (acc_exp > 1) 
X	{
X	  i++;
X	  acc_exp -= 1.0;
X	}
X      p_ptr->exp += i;
X      if (i > 0)  prt_experience();
X      m_take_hit = m_ptr->mptr;
X      delete_monster(monptr);
X    }
X  else
X    m_take_hit = -1;
X  return(m_take_hit);
X}
X
X
X/* Special damage due to magical abilities of object	-RAK-	*/
Xint tot_dam(item, tdam, monster)
Xtreasure_type item;
Xint tdam;
Xcreature_type monster;
X{
X  treasure_type *i_ptr;
X  creature_type *m_ptr;
X
X  i_ptr = &item;
X  if (((i_ptr->tval >= 10) && (i_ptr->tval <= 12)) ||
X      ((i_ptr->tval >= 20) && (i_ptr->tval <= 23)) ||
X      (i_ptr->tval == 77))
X    {
X      m_ptr = &monster;
X      /* Slay Dragon  */
X      if ((m_ptr->cdefense & 0x0001) && (i_ptr->flags & 0x00002000))
X	tdam *= 4;
X      /* Slay Undead  */
X      else if ((m_ptr->cdefense & 0x0008) && (i_ptr->flags & 0x00010000)) 
X	tdam *= 3;
X      /* Slay Monster  */
X      else if ((m_ptr->cdefense & 0x0002) && (i_ptr->flags & 0x00004000)) 
X	tdam *= 2;
X      /* Slay Evil     */
X      else if ((m_ptr->cdefense & 0x0004) && (i_ptr->flags & 0x00008000)) 
X	tdam *= 2;
X      /* Frost         */
X      else if ((m_ptr->cdefense & 0x0010) && (i_ptr->flags & 0x00020000)) 
X	tdam = (tdam*1.5);
X      /* Fire         */
X      else if ((m_ptr->cdefense & 0x0020) && (i_ptr->flags & 0x00040000)) 
X	tdam = (tdam*1.5);
X    }
X  return(tdam);
X}
X
X
X/* Player attacks a (poor, defenseless) creature 	-RAK-	*/
Xint py_attack(y, x)
Xint y, x;
X{
X  int attack;
X  int i, j, k, blows, tot_tohit;
X  vtype m_name, out_val;
X  treasure_type *i_ptr;
X  struct misc *p_ptr;
X
X  attack = FALSE;
X  i = cave[y][x].cptr;
X  j = m_list[i].mptr;
X  m_list[i].csleep = 0;
X  /* Does the player know what he's fighting?      */
X  if ((0x10000 & c_list[j].cmove) && (!py.flags.see_inv)) 
X    (void) strcpy(m_name, "it");
X  else if (py.flags.blind > 0) 
X    (void) strcpy(m_name, "it");
X  else if (!m_list[i].ml) 
X    (void) strcpy(m_name, "it");
X  else
X    (void) sprintf(m_name, "the %s", c_list[j].name);
X  if (inventory[22].tval != 0)         /* Proper weapon */
X    blows = attack_blows((int)inventory[22].weight, &tot_tohit);
X  else                                    /* Bare hands?   */
X    {
X      blows = 2;
X      tot_tohit = -3;
X    }
X  if ((inventory[22].tval >= 10) && (inventory[22].tval <= 12))
X    /* Fix for arrows */
X    blows = 1;
X  tot_tohit += py.misc.ptohit;
X  /* Loop for number of blows,  trying to hit the critter...        */
X  p_ptr = &py.misc;
X  do
X    {
X      if (test_hit(p_ptr->bth, (int)p_ptr->lev, tot_tohit, (int)c_list[j].ac))
X	{
X	  (void) sprintf(out_val, "You hit %s.", m_name);
X	  msg_print(out_val);
X	  i_ptr = &inventory[22];
X	  if (i_ptr->tval != 0)           /* Weapon?       */
X	    {
X	      k = damroll(i_ptr->damage);
X	      k = tot_dam(inventory[22], k, c_list[j]);
X	      k = critical_blow((int)i_ptr->weight, tot_tohit, k);
X	    }
X	  else                        /* Bare hands!?  */
X	    {
X	      k = damroll(bare_hands);
X	      k = critical_blow(1, 0, k);
X	    }
X	  k += p_ptr->ptodam;
X	  if (k < 0)  k = 0;
X	  /* See if we done it in...                               */
X	  if (mon_take_hit(i, k) >= 0) 
X	    {
X	      (void) sprintf(out_val, "You have slain %s.", m_name);
X	      msg_print(out_val);
X	      blows = 0;
X	      attack = FALSE;
X	    }
X	  else
X	    attack = TRUE;  /* If creature hit,  but alive...*/
X	  i_ptr = &inventory[22];
X	  if ((i_ptr->tval >= 10) && (i_ptr->tval <= 12)) /* Use missiles up*/
X	    {
X	      i_ptr->number--;
X	      if (i_ptr->number == 0) 
X		{
X		  inven_weight = inven_weight - i_ptr->weight;
X		  equip_ctr--;
X		  inventory[INVEN_MAX] = inventory[22];
X		  inventory[22] = blank_treasure;
X		  py_bonuses(inventory[INVEN_MAX], -1);
X		}
X	    }
X	}
X      else
X	{
X	  (void) sprintf(out_val, "You miss %s.", m_name);
X	  msg_print(out_val);
X	}
X      blows--;
X    }
X  while (blows >= 1);
X  return(attack);
X}
X
X
X/* Moves player from one space to another...		-RAK-	*/
X/* Note: This routine has been pre-declared; see that for argument*/
Xmove_char(dir)
Xint dir;
X{
X  int test_row, test_col;
X  int i, j;
X  cave_type *c_ptr, *d_ptr;
X
X  test_row = char_row;
X  test_col = char_col;
X  if (py.flags.confused > 0)          /* Confused?             */
X    if (randint(4) > 1)               /* 75% random movement   */
X      if (dir != 5)                   /* Never random if sitting*/
X	{
X	  dir = randint(9);
X	  find_flag = FALSE;
X	}
X  if (move(dir, &test_row, &test_col))    /* Legal move?           */
X    {
X      c_ptr = &cave[test_row][test_col];
X      if (c_ptr->cptr < 2)                   /* No creature?          */
X	{
X	  if (c_ptr->fopen)                  /* Open floor spot       */
X	    {
X	      /* Move character record (-1)            */
X	      move_rec(char_row, char_col, test_row, test_col);
X	      /* Check for new panel                   */
X	      if (get_panel(test_row, test_col)) 
X		prt_map();
X	      /* Check to see if he should stop        */
X	      if (find_flag) 
X		area_affect(dir, test_row, test_col);
X	      /* Check to see if he notices something  */
X	      if (py.flags.blind < 1) 
X		if ((randint(py.misc.fos) == 1) || (search_flag)) 
X		  search(test_row, test_col, py.misc.srh);
X	      /* An object is beneath him...           */
X	      if (c_ptr->tptr != 0) 
X		carry(test_row, test_col);
X	      /* Move the light source                 */
X	      move_light(char_row, char_col, test_row, test_col);
X	      /* A room of light should be lit...      */
X	      if (c_ptr->fval == lopen_floor.ftval) 
X		{
X		  if (py.flags.blind < 1) 
X		    if (!c_ptr->pl) 
X		      light_room(test_row, test_col);
X		}
X	      /* In doorway of light-room?             */
X	      else if ((c_ptr->fval == 5) || (c_ptr->fval == 6))
X		if (py.flags.blind < 1) 
X		  {
X		    for (i = (test_row - 1); i <= (test_row + 1); i++)
X		      for (j = (test_col - 1); j <= (test_col + 1); j++)
X			if (in_bounds(i, j)) 
X			  {
X			    d_ptr = &cave[i][j];
X			    if (d_ptr->fval == lopen_floor.ftval) 
X			      if (!d_ptr->pl) 
X				light_room(i, j);
X			  }
X		  }
X	      /* Make final assignments of char co-ords*/
X	      char_row = test_row;
X	      char_col = test_col;
X	    }
X	  else    /*Can't move onto floor space*/
X	    /* Try a new direction if in find mode   */
X	    if (!pick_dir(dir)) 
X	      {
X		if (find_flag) 
X		  {
X		    find_flag = FALSE;
X		    move_char(5);
X		  }
X		else if (c_ptr->tptr != 0) 
X		  {
X		    reset_flag = TRUE;
X		    if (t_list[c_ptr->tptr].tval == 103) 
X		      msg_print("There is rubble blocking your way.");
X		    else if (t_list[c_ptr->tptr].tval == 105) 
X		      msg_print("There is a closed door blocking your way.");
X		  }
X		else
X		  reset_flag = TRUE;
X	      }
X	}
X      else        /* Attacking a creature! */
X	{
X	  if (find_flag) 
X	    {
X	      find_flag = FALSE;
X	      move_light(char_row, char_col, char_row, char_col);
X	    }
X	  if (py.flags.afraid < 1)    /* Coward?       */
X	    (void) py_attack(test_row, test_col);
X	  else                            /* Coward!       */
X	    msg_print("You are too afraid!");
X	}
X    }
X}
X
X
X/* Chests have traps too...				-RAK-	*/
X/* Note: Chest traps are based on the FLAGS value                */
Xchest_trap(y, x)
Xint y, x;
X{
X  int i, j, k;
X  treasure_type *t_ptr;
X
X  t_ptr = &t_list[cave[y][x].tptr];
X  if (0x00000010 & t_ptr->flags)
X    {
X      msg_print("A small needle has pricked you!");
X      if (!py.flags.sustain_str) 
X	{
X	  py.stats.cstr = de_statp(py.stats.cstr);
X	  take_hit(damroll("1d4"), "a poison needle.");
X	  print_stat |= 0x0001;
X	  msg_print("You feel weakened!");
X	}
X      else
X	msg_print("You are unaffected.");
X    }
X  if (0x00000020 & t_ptr->flags)
X    {
X      msg_print("A small needle has pricked you!");
X      take_hit(damroll("1d6"), "a poison needle.");
X      py.flags.poisoned += 10 + randint(20);
X    }
X  if (0x00000040 & t_ptr->flags)
X    {
X      msg_print("A puff of yellow gas surrounds you!");
X      if (py.flags.free_act) 
X	msg_print("You are unaffected.");
X      else
X	{
X	  msg_print("You choke and pass out.");
X	  py.flags.paralysis = 10 + randint(20);
X	}
X    }
X  if (0x00000080 & t_ptr->flags)
X    {
X      msg_print("There is a sudden explosion!");
X      (void) delete_object(y, x);
X      take_hit(damroll("5d8"), "an exploding chest.");
X    }
X  if (0x00000100 & t_ptr->flags)
X    {
X      for (i = 0; i < 3; i++)
X	{
X	  j = y;
X	  k = x;
X	  (void) summon_monster(&j, &k, FALSE);
X	}
X    }
X}
X
X
X/* Opens a closed door or closed chest...		-RAK-	*/
Xopenobject()
X{
X  int y, x, tmp;
X  int flag;
X  char *tmp_str;
X  cave_type *c_ptr;
X  treasure_type *t_ptr;
X  struct misc *p_ptr;
X  
X  y = char_row;
X  x = char_col;
X  if (get_dir("Which direction?", &tmp, &tmp, &y, &x)) 
X    {
X      c_ptr = &cave[y][x];
X      if (c_ptr->tptr != 0) 
X	/* Closed door           */
X	if (t_list[c_ptr->tptr].tval == 105) 
X	  {
X	    t_ptr = &t_list[c_ptr->tptr];
X	    if (t_ptr->p1 > 0)   /* It's locked...        */
X	      {
X		p_ptr = &py.misc;
X		tmp = p_ptr->disarm + p_ptr->lev + 2*todis_adj() + int_adj();
X		if (py.flags.confused > 0) 
X		  msg_print("You are too confused to pick the lock.");
X		else if ((tmp-t_ptr->p1) > randint(100)) 
X		  {
X		    msg_print("You have picked the lock.");
X		    py.misc.exp++;
X		    prt_experience();
X		    t_ptr->p1 = 0;
X		  }
X		else
X		  msg_print("You failed to pick the lock.");
X	      }
X	    else if (t_ptr->p1 < 0)      /* It's stuck    */
X	      msg_print("It appears to be stuck.");
X	    if (t_ptr->p1 == 0) 
X	      {
X		t_list[c_ptr->tptr] = door_list[0];
X		c_ptr->fopen = TRUE;
X		lite_spot(y, x);
X	      }
X	  }
X      /* Open a closed chest...                */
X	else if (t_list[c_ptr->tptr].tval == 2) 
X	  {
X	    p_ptr = &py.misc;
X	    tmp = p_ptr->disarm + p_ptr->lev + 2*todis_adj() + int_adj();
X	    t_ptr = &t_list[c_ptr->tptr];
X	    flag = FALSE;
X	    if (0x00000001 & t_ptr->flags)
X	      if (py.flags.confused > 0) 
X		msg_print("You are too confused to pick the lock.");
X	      else if ((tmp-(2*t_ptr->level)) > randint(100)) 
X		{
X		  msg_print("You have picked the lock.");
X		  flag = TRUE;
X		  py.misc.exp += t_ptr->level;
X		  prt_experience();
X		}
X	      else
X		msg_print("You failed to pick the lock.");
X	    else
X	      flag = TRUE;
X	    if (flag) 
X	      {
X		t_ptr->flags &= 0xFFFFFFFE;
X		tmp_str = index(t_ptr->name, '(');
X		if (tmp_str != 0) 
X		  tmp_str[0] = '\0';
X		(void) strcat(t_ptr->name, " (Empty)");
X		known2(t_ptr->name);
X		t_ptr->cost = 0;
X	      }
X	    flag = FALSE;
X	    /* Was chest still trapped?  (Snicker)   */
X	    if ((0x00000001 & t_ptr->flags) == 0) 
X	      {
X		chest_trap(y, x);
X		if (c_ptr->tptr != 0) 
X		  flag = TRUE;
X	      }
X	    /* Chest treasure is allocated as if a creature   */
X	    /* had been killed...                            */
X	    if (flag) 
X	      {
X		monster_death(y, x, t_list[c_ptr->tptr].flags);
X		t_list[c_ptr->tptr].flags = 0;
X	      }
X	  }
X	else
X	  msg_print("I do not see anything you can open there.");
X      else
X	msg_print("I do not see anything you can open there.");
X	}
X}
X
X
X/* Closes an open door...				-RAK-	*/
Xcloseobject()
X{
X  int y, x, tmp;
X  vtype out_val;
X  cave_type *c_ptr;
X
X  y = char_row;
X  x = char_col;
X  if (get_dir("Which direction?", &tmp, &tmp, &y, &x)) 
X    {
X      c_ptr = &cave[y][x];
X      if (c_ptr->tptr != 0) 
X	if (t_list[c_ptr->tptr].tval == 104) 
X	  if (c_ptr->cptr == 0) 
X	    if (t_list[c_ptr->tptr].p1 == 0) 
X	      {
X		t_list[c_ptr->tptr] = door_list[1];
X		c_ptr->fopen = FALSE;
X		lite_spot(y, x);
X	      }
X	    else
X	      msg_print("The door appears to be broken.");
X	  else
X	    {
X	      (void) sprintf(out_val, "The %s is in your way!",
X		      c_list[m_list[c_ptr->cptr].mptr].name);
X	      msg_print(out_val);
X	    }
X	else
X	  msg_print("I do not see anything you can close there.");
X      else
X	msg_print("I do not see anything you can close there.");
X	}
X}
X
X
X/* Go up one level					-RAK-	*/
Xgo_up()
X{
X  cave_type *c_ptr;
X
X  c_ptr = &cave[char_row][char_col];
X  if (c_ptr->tptr != 0) 
X    if (t_list[c_ptr->tptr].tval == 107) 
X      {
X	dun_level--;
X	moria_flag = TRUE;
X	msg_print("You enter a maze of up staircases.");
X	msg_print("You pass through a one-way door.");
X      }
X    else
X      msg_print("I see no up staircase here.");
X  else
X    msg_print("I see no up staircase here.");
X}
X
X
X/* Go down one level					-RAK-	*/
Xgo_down()
X{
X  cave_type *c_ptr;
X
X  c_ptr = &cave[char_row][char_col];
X  if (c_ptr->tptr != 0) 
X    if (t_list[c_ptr->tptr].tval == 108) 
X      {
X	dun_level++;
X	moria_flag = TRUE;
X	msg_print("You enter a maze of down staircases.");
X	msg_print("You pass through a one-way door.");
X      }
X    else
X      msg_print("I see no down staircase here.");
X  else
X    msg_print("I see no down staircase here.");
X}
X
X
X/* Tunneling through real wall: 10, 11, 12 		-RAK-	*/
X/* Used by TUNNEL and WALL_TO_MUD                                */
Xint twall(y, x, t1, t2)
Xint y, x, t1, t2;
X{
X  int res;
X  cave_type *c_ptr;
X
X  res = FALSE;
X  c_ptr = &cave[y][x];
X  if (t1 > t2) 
X    {
X      if (next_to4(y, x, 1, 2, -1) > 0) 
X	{
X	  c_ptr->fval  = corr_floor2.ftval;
X	  c_ptr->fopen = corr_floor2.ftopen;
X	}
X      else
X	{
X	  c_ptr->fval  = corr_floor1.ftval;
X	  c_ptr->fopen = corr_floor1.ftopen;
X	}
X      if (test_light(y, x)) 
X	if (panel_contains(y, x)) 
X	  {
X	    if (c_ptr->tptr != 0) 
X	      msg_print("You have found something!");
X	    lite_spot(y, x);
X	  }
X      c_ptr->fm = FALSE;
X      c_ptr->pl = FALSE;
X      res = TRUE;
X    }
X  return(res);
X}
X
X
X/* Tunnels through rubble and walls			-RAK-	*/
X/* Must take into account: secret doors,  special tools           */
Xtunnel(y, x)
Xint y, x;
X{
X  int i, tabil;
X  cave_type *c_ptr;
X  treasure_type *i_ptr;
X
X  c_ptr = &cave[y][x];
X  /* Compute the digging ability of player; based on       */
X  /* strength, and type of tool used                       */
X  tabil = py.stats.cstr;
X  if (inventory[22].tval != 0) 
X    {
X      i_ptr = &inventory[22];
X      if (0x20000000 & i_ptr->flags)
X	tabil += 25 + i_ptr->p1*50;
X      /* Regular walls; Granite, magma intrusion, quartz vein  */
X      /* Don't forget the boundary walls, made of titanium (255)*/
X      switch(c_ptr->fval)
X	{
X	case 10:
X	  i = randint(1200) + 80;
X	  if (twall(y, x, tabil, i)) 
X	    msg_print("You have finished the tunnel.");
X	  else
X	    msg_print("You tunnel into the granite wall.");
X	  break;
X	case 11:
X	  i = randint(600) + 10;
X	  if (twall(y, x, tabil, i)) 
X	    msg_print("You have finished the tunnel.");
X	  else
X	    msg_print("You tunnel into the magma intrusion.");
X	  break;
X	case 12:
X	  i = randint(400) + 10;
X	  if (twall(y, x, tabil, i)) 
X	    msg_print("You have finished the tunnel.");
X	  else
X	    msg_print("You tunnel into the quartz vein.");
X	  break;
X	case 15:
X	  msg_print("This seems to be permanent rock.");
X	  break;
X	default:
X	  /* Is there an object in the way?  (Rubble and secret doors)*/
X	  if (c_ptr->tptr != 0) 
X	    {
X	      /* Rubble...     */
X	      if (t_list[c_ptr->tptr].tval == 103) 
X		{
X		  if (tabil > randint(180)) 
X		    {
X		      pusht((int)c_ptr->tptr);
X		      c_ptr->tptr = 0;
X		      c_ptr->fm = FALSE;
X		      c_ptr->fopen = TRUE;
X		      msg_print("You have removed the rubble.");
X		      if (randint(10) == 1) 
X			{
X			  place_object(y, x);
X			  if (test_light(y, x)) 
X			    msg_print("You have found something!");
X			}
X		      lite_spot(y, x);
X		    }
X		  else
X		    msg_print("You dig in the rubble...");
X		}
X	      /* Secret doors...*/
X	      else if (t_list[c_ptr->tptr].tval == 109) 
X		{
X		  msg_print("You tunnel into the granite wall.");
X		  search(char_row, char_col, py.misc.srh);
X		}
X	      else
X		msg_print("You can't tunnel through that.");
X	    }
X	  else
X	    msg_print("Tunnel through what?  Empty air???");
X	  break;
X	}
X    }
X}
X
X
X/* Disarms a trap					-RAK-	*/
Xdisarm_trap()
X{
X  int y, x, i, tdir;
X  int tot, t1, t2, t3, t4, t5;
X  cave_type *c_ptr;
X  treasure_type *i_ptr;
X  char *tmp_str;
X
X  y = char_row;
X  x = char_col;
X  if (get_dir("Which direction?", &tdir, &i, &y, &x)) 
X    {
X      c_ptr = &cave[y][x];
X      if (c_ptr->tptr != 0) 
X	{
X	  t1 = py.misc.disarm; /* Ability to disarm     */
X	  t2 = py.misc.lev;    /* Level adjustment      */
X	  t3 = 2*todis_adj();    /* Dexterity adjustment  */
X	  t4 = int_adj();        /* Intelligence adjustment*/
X	  tot = t1 + t2 + t3 + t4;
X	  if (py.flags.blind > 0) 
X	    tot /= 5.0;
X	  else if (no_light()) 
X	    tot /= 2.0;
X	  if (py.flags.confused > 0) 
X	    tot /= 3.0;
X	  i = t_list[c_ptr->tptr].tval;
X	  t5 = t_list[c_ptr->tptr].level;
X	  if (i == 102)             /* Floor trap    */
X	    {
X	      i_ptr = &t_list[c_ptr->tptr];
X	      if ((tot - t5) > randint(100)) 
X		{
X		  msg_print("You have disarmed the trap.");
X		  py.misc.exp += i_ptr->p1;
X		  c_ptr->fm = FALSE;
X		  pusht((int)c_ptr->tptr);
X		  c_ptr->tptr = 0;
X		  move_char(tdir);
X		  lite_spot(y, x);
X		  prt_experience();
X		}
X	      else if (randint(tot) > 5) 
X		msg_print("You failed to disarm the trap.");
X	      else
X		{
X		  msg_print("You set the trap off!");
X		  move_char(tdir);
X		}
X	    }
X	  else if (i == 2)          /* Chest trap    */
X	    {
X	      i_ptr = &t_list[c_ptr->tptr];
X	      if (index(i_ptr->name, '^') != 0) 
X		msg_print("I don't see a trap...");
X	      else if (0x000001F0 & i_ptr->flags)
X		{
X		  if ((tot - t5) > randint(100)) 
X		    {
X		      i_ptr->flags &= 0xFFFFFE0F;
X		      tmp_str = index(i_ptr->name, '(');
X		      if (tmp_str != 0) 
X		        tmp_str[0] = '\0';
X		      if (0x00000001 & i_ptr->flags)
X			(void) strcat(i_ptr->name, " (Locked)");
X		      else
X			(void) strcat(i_ptr->name, " (Disarmed)");
X		      msg_print("You have disarmed the chest.");
X		      known2(i_ptr->name);
X		      py.misc.exp += t5;
X		      prt_experience();
X		    }
X		  else if (randint(tot) > 5) 
X		    msg_print("You failed to disarm the chest.");
X		  else
X		    {
X		      msg_print("You set a trap off!");
X		      known2(i_ptr->name);
X		      chest_trap(y, x);
X		    }
X		}
X	      else
X		msg_print("The chest was not trapped.");
X	    }
X	  else
X	    msg_print("I do not see anything to disarm there.");
X	}
X      else
X	msg_print("I do not see anything to disarm there.");
X    }
X}
X
X
X/* Look at an object,  trap,  or monster			-RAK-	*/
X/* Note: Looking is a free move,  see where invoked...            */
Xlook()
X{
X  int i, j, y, x;
X  int dir, dummy;
X  int flag;
X  char fchar;
X  cave_type *c_ptr;
X  vtype out_val, tmp_str;
X
X  flag = FALSE;
X  y = char_row;
X  x = char_col;
X  if (get_dir("Look which direction?", &dir, &dummy, &y, &x)) 
X    if (py.flags.blind < 1) 
X      {
X	y = char_row;
X	x = char_col;
X	i = 0;
X	do
X	  {
X	    (void) move(dir, &y, &x);
X	    c_ptr = &cave[y][x];
X	    if (c_ptr->cptr > 1) 
X	      if (m_list[c_ptr->cptr].ml) 
X		{
X		  j = m_list[c_ptr->cptr].mptr;
X		  fchar = c_list[j].name[0];
X		  if (is_a_vowel(fchar)) 
X		    (void) sprintf(out_val, "You see an %s.", c_list[j].name);
X		  else
X		    (void) sprintf(out_val, "You see a %s.", c_list[j].name);
X		  msg_print(out_val);
X		  flag = TRUE;
X		}
X	    if ((c_ptr->tl) || (c_ptr->pl) || (c_ptr->fm)) 
X	      {
X		if (c_ptr->tptr != 0) 
X		  if (t_list[c_ptr->tptr].tval == 109) 
X		    msg_print("You see a granite wall.");
X		  else if (t_list[c_ptr->tptr].tval != 101) 
X		    {
X		      inventory[INVEN_MAX] = t_list[c_ptr->tptr];
X		      objdes(tmp_str, INVEN_MAX, TRUE);
X		      (void) sprintf(out_val, "You see %s", tmp_str);
X		      msg_print(out_val);
X		      flag = TRUE;
X		    }
X		if (!c_ptr->fopen) 
X		  {
X		    flag = TRUE;
X		    switch(c_ptr->fval)
X		      {
X		      case 10: msg_print("You see a granite wall."); break;
X		      case 11: msg_print("You see some dark rock."); break;
X		      case 12: msg_print("You see a quartz vein."); break;
X		      case 15: msg_print("You see a granite wall."); break;
X		      default: break;
X		      }
X		  }
X	      }
X	    i++;
X	  }
X	while ((cave[y][x].fopen) && (i <= MAX_SIGHT));
X	if (!flag) 
X	  msg_print("You see nothing of interest in that direction.");
X      }
X    else
X      msg_print("You can't see a damn thing!");
X}
X
X
X/* Add to the players food time				-RAK-	*/
Xadd_food(num)
Xint num;
X{
X  struct flags *p_ptr;
X
X  p_ptr = &py.flags;
X  if (p_ptr->food < 0)  p_ptr->food = 0;
X  p_ptr->food += num;
X  if (p_ptr->food > PLAYER_FOOD_FULL)  msg_print("You are full.");
X  if (p_ptr->food > PLAYER_FOOD_MAX) 
X    {
X      msg_print("You're getting fat from eating so much.");
X      p_ptr->food = PLAYER_FOOD_MAX;
X    }
X}
X
X
X/* Describe number of remaining charges...		-RAK-	*/
Xdesc_charges(item_val)
Xint item_val;
X{
X  int rem_num;
X  vtype out_val;
X
X  if (index(inventory[item_val].name, '^') == 0) 
X    {
X      rem_num = inventory[item_val].p1;
X      (void) sprintf(out_val, "You have %d charges remaining.", rem_num);
X      msg_print(out_val);
X    }
X}
X
X
X/* Describe amount of item remaining...			-RAK-	*/
Xdesc_remain(item_val)
Xint item_val;
X{
X  vtype out_val, tmp_str;
X  treasure_type *i_ptr;
X
X  inventory[INVEN_MAX] = inventory[item_val];
X  i_ptr = &inventory[INVEN_MAX];
X  i_ptr->number--;
X  objdes(tmp_str, INVEN_MAX, TRUE);
X  tmp_str[strlen(tmp_str)-1] = '\0';
X  (void) sprintf(out_val, "You have %s.", tmp_str);
X  msg_print(out_val);
X}
X
X
Xinven_throw(item_val)
Xint item_val;
X{
X  treasure_type *i_ptr;
X
X  inventory[INVEN_MAX] = inventory[item_val];
X  inventory[INVEN_MAX].number = 1;
X  i_ptr = &inventory[item_val];
X  if ((i_ptr->number > 1) && (i_ptr->subval > 511)) 
X    {
X      i_ptr->number--;
X      inven_weight -= i_ptr->weight;
X    }
X  else
X    inven_destroy(item_val);
X}
X
X
Xfacts(tbth, tpth, tdam, tdis)
Xint *tbth, *tpth, *tdam, *tdis;
X{
X  int tmp_weight;
X  treasure_type *i_ptr;
X
X  i_ptr = &inventory[INVEN_MAX];
X  if (i_ptr->weight < 1) 
X    tmp_weight = 1;
X  else
X    tmp_weight = i_ptr->weight;
X  
X  /* Throwing objects			*/
X  *tdam = damroll(i_ptr->damage) + i_ptr->todam;
X  *tbth = (py.misc.bthb*0.75);
X  *tpth = py.misc.ptohit + i_ptr->tohit;
X  *tdis = (((py.stats.cstr+20)*10)/tmp_weight);
X  if (*tdis > 10)  *tdis = 10;
X
X  /* Using Bows,  slings,  or crossbows	*/
X  if (inventory[22].tval == 20) 
X    switch(inventory[22].p1)
X      {
X      case 1:
X	if (i_ptr->tval == 10)        /* Sling and Bullet       */
X	  {
X	    *tbth = py.misc.bthb;
X	    *tpth += inventory[22].tohit;
X	    *tdam += 2;
X	    *tdis = 20;
X	  }
X	break;
X      case 2: 
X	if (i_ptr->tval == 12)        /* Short Bow and Arrow    */
X	  {
X	    *tbth = py.misc.bthb;
X	    *tpth += inventory[22].tohit;
X	    *tdam += 2;
X	    *tdis = 25;
X	  }
X	break;
X      case 3:
X	if (i_ptr->tval == 12)        /* Long Bow and Arrow     */
X	  {
X	    *tbth = py.misc.bthb;
X	    *tpth += inventory[22].tohit;
X	    *tdam += 3;
X	    *tdis = 30;
X	  }
X	break;
X      case 4:
X	if (i_ptr->tval == 12)        /* Composite Bow and Arrow*/
X	  {
X	    *tbth = py.misc.bthb;
X	    *tpth += inventory[22].tohit;
X	    *tdam += 4;
X	    *tdis = 35;
X	  }
X	break;
X      case 5:
X	if (i_ptr->tval == 11)        /* Light Crossbow and Bolt*/
X	  {
X	    *tbth = py.misc.bthb;
X	    *tpth += inventory[22].tohit;
X	    *tdam += 2;
X	    *tdis = 25;
X	  }
X	break;
X      case 6:
X	if (i_ptr->tval == 11)        /* Heavy Crossbow and Bolt*/
X	  {
X	    *tbth = py.misc.bthb;
X	    *tpth += inventory[22].tohit;
X	    *tdam += 4;
X	    *tdis = 35;
X	    break;
X	  }
X      }
X}
X
X
Xdrop_throw(y, x)
Xint y, x;
X{
X  int i, j, k, cur_pos;
X  int flag;
X  vtype out_val, tmp_str;
X  cave_type *c_ptr;
X
X  flag = FALSE;
X  i = y;
X  j = x;
X  k = 0;
X  if (randint(10) > 1) 
X    {
X      do
X	{
X	  if (in_bounds(i, j)) 
X	    {
X	      c_ptr = &cave[i][j];
X	      if (c_ptr->fopen) 
X		if (c_ptr->tptr == 0) 
X		  flag = TRUE;
X	    }
X	  if (!flag) 
X	    {
X	      i = y + randint(3) - 2;
X	      j = x + randint(3) - 2;
X	      k++;
X	    }
X	}
X      while ((!flag) && (k <= 9));
X    }
X  if (flag) 
X    {
X      popt(&cur_pos);
X      cave[i][j].tptr = cur_pos;
X      t_list[cur_pos] = inventory[INVEN_MAX];
X      if (test_light(i, j)) 
X	lite_spot(i, j);
X    }
X  else
X    {
X      objdes(tmp_str, INVEN_MAX, FALSE);
X      (void) sprintf(out_val, "The %s disappears", tmp_str);
X      msg_print(out_val);
X    }
X}
X
X/* Throw an object across the dungeon... 		-RAK-	*/
X/* Note: Flasks of oil do fire damage                            */
X/* Note: Extra damage and chance of hitting when missiles are used*/
X/*       with correct weapon.  I.E.  wield bow and throw arrow.  */
Xthrow_object()
X{
X  int item_val, tbth, tpth, tdam, tdis, i;
X  int y_dumy, x_dumy, dumy;
X  int y, x, oldy, oldx, dir, cur_dis;
X  int redraw, flag;
X  char tchar[2];
X  vtype out_val, tmp_str;
X  treasure_type *i_ptr;
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X
X  redraw = FALSE;
X  if (inven_ctr == 0) 
X    msg_print("But you are not carrying anything.");
X  else if (get_item(&item_val, "Fire/Throw which one?", 
X		    &redraw, 0, inven_ctr-1)) 
X    {
X      if (redraw) 
X	draw_cave();
X      y_dumy = char_row;
X      x_dumy = char_col;
X      if (get_dir("Which direction?", &dir, &dumy, &y_dumy, &x_dumy)) 
X	{
X	  desc_remain(item_val);
X	  if (py.flags.confused > 0) 
X	    {
X	      msg_print("You are confused...");
X	      do
X		{
X		  dir = randint(9);
X		}
X	      while (dir == 5);
X	    }
X	  inven_throw(item_val);
X	  facts(&tbth, &tpth, &tdam, &tdis);
X	  i_ptr = &inventory[INVEN_MAX];
X	  flag = FALSE;
X	  y = char_row;
X	  x = char_col;
X	  oldy = char_row;
X	  oldx = char_col;
X	  cur_dis = 0;
X	  do
X	    {
X	      (void) move(dir, &y, &x);
X	      cur_dis++;
X	      if (test_light(oldy, oldx)) 
X		lite_spot(oldy, oldx);
X	      if (cur_dis > tdis)  flag = TRUE;
X	      c_ptr = &cave[y][x];
X	      if ((c_ptr->fopen) && (!flag)) 
X		{
X		  if (c_ptr->cptr > 1) 
X		    {
X		      flag = TRUE;
X		      m_ptr = &m_list[c_ptr->cptr];
X		      tbth = tbth - cur_dis;
X		      if (test_hit(tbth, (int)py.misc.lev, tpth, 
X				   (int)c_list[m_ptr->mptr].ac)) 
X			{
X			  i = m_ptr->mptr;
X			  objdes(tmp_str, INVEN_MAX, FALSE);
X			  (void) sprintf(out_val,"The %s hits the %s.",tmp_str,
X				  c_list[i].name);
X			  msg_print(out_val);
X			  tdam = tot_dam(inventory[INVEN_MAX], tdam, 
X					 c_list[i]);
X			  i_ptr = &inventory[INVEN_MAX];
X			  tdam = critical_blow((int)i_ptr->weight, tpth, tdam);
X			  i = mon_take_hit((int)c_ptr->cptr, tdam);
X			  if (i > 0) 
X			    {
X			      (void) sprintf(out_val,"You have killed the %s.",
X				      c_list[i].name);
X			      msg_print(out_val);
X			    }
X			}
X		      else
X			drop_throw(oldy, oldx);
X		    }
X		  else
X		    {
X		      tchar[0] = '\0';
X		      if (panel_contains(y, x)) 
X			if (test_light(y, x)) 
X			  print(tchar, y, x);
X		    }
X		}
X	      else
X		{
X		  flag = TRUE;
X		  drop_throw(oldy, oldx);
X		}
X	      oldy = y;
X	      oldx = x;
X	    }
X	  while (!flag);
X	}
X    }
X  else
X    if (redraw) 
X      draw_cave();
X}
X
X
X/* Bash open a door or chest				-RAK-	*/
X/* Note: Affected by strength and weight of character            */
Xbash()
X{
X  int y, x, tmp;
X  int old_ptodam, old_ptohit, old_bth;
X  vtype tmp_str, m_name;
X  cave_type *c_ptr;
X  treasure_type *i_ptr, *t_ptr;
X  player_type *p_ptr;
X  monster_type *m_ptr;
X
X  y = char_row;
X  x = char_col;
X  if (get_dir("Which direction?", &tmp, &tmp, &y, &x)) 
X    {
X      c_ptr = &cave[y][x];
X      if (c_ptr->cptr > 1) 
X	{
X	  if (py.flags.afraid > 0) 
X	    msg_print("You are afraid!");
X	  else
X	    {
X	      /* Save old values of attacking  */
X	      inventory[INVEN_MAX] = inventory[22];
X	      old_ptohit = py.misc.ptohit;
X	      old_ptodam = py.misc.ptodam;
X	      old_bth    = py.misc.bth;
X	      /* Use these values              */
X	      inventory[22] = blank_treasure;
X	      i_ptr = &inventory[22];
X	      (void) strcpy(i_ptr->damage, inventory[26].damage);
X	      i_ptr->weight = py.stats.cstr;
X	      i_ptr->tval   = 1;
X	      p_ptr = &py;
X	      p_ptr->misc.bth    = ((p_ptr->stats.cstr+
X					 p_ptr->misc.wt)/6.0);
X	      p_ptr->misc.ptohit = 0;
X	      p_ptr->misc.ptodam = (p_ptr->misc.wt/75.0) + 1;
X	      if (py_attack(y, x)) 
X		{
X		  m_ptr = &m_list[c_ptr->cptr];
X		  m_ptr->stunned = randint(2) + 1;
X		  if (m_ptr->stunned > 24)  m_ptr->stunned = 24;
X		  /* Does the player know what he's fighting?      */
X		  if ((0x10000 & c_list[m_ptr->mptr].cmove) &&
X		      (!py.flags.see_inv)) 
X		    (void) strcpy(m_name, "It");
X		  else if (py.flags.blind > 0) 
X		    (void) strcpy(m_name, "It");
X		  else if (!m_list[c_ptr->cptr].ml) 
X		    (void) strcpy(m_name, "It");
X		  else
X		    (void) sprintf(m_name, "The %s", c_list[m_ptr->mptr].name);
X		  (void) sprintf(tmp_str, "%s appears stunned!",
X			  m_name);
X		  msg_print(tmp_str);
X		}
X	      /* Restore old values            */
X	      inventory[22] = inventory[INVEN_MAX];
X	      py.misc.ptohit = old_ptohit;
X	      py.misc.ptodam = old_ptodam;
X	      py.misc.bth    = old_bth;
X	      if (randint(140) > py.stats.cdex) 
X		{
X		  msg_print("You are off-balance.");
X		  py.flags.paralysis = randint(3);
X		}
X	    }
X	}
X      else if (c_ptr->tptr != 0) 
X	{
X	  t_ptr = &t_list[c_ptr->tptr];
X	  if (t_ptr->tval == 105) 
X	    {
X	      msg_print("You smash into the door!");
X	      p_ptr = &py;
X	      if (test_hit((int)(p_ptr->misc.wt+p_ptr->stats.cstr), 0, 0,
X			   abs(t_ptr->p1)+150)) 
X		{
X		  msg_print("The door crashes open!");
X		  t_list[c_ptr->tptr] = door_list[0];
X		  t_ptr->p1 = 1;
X		  c_ptr->fopen = TRUE;
X		  lite_spot(y, x);
X		}
X	      else
X		{
X		  msg_print("The door holds firm.");
X		  py.flags.paralysis = 2;
X		}
X	    }
X	  else if (t_ptr->tval == 2) 
X	    {
X	      if (randint(10) == 1) 
X		{
X		  msg_print("You have destroyed the chest...");
X		  msg_print("and it's contents!");
X		  (void) strcpy(t_ptr->name, "& ruined chest");
X		  t_ptr->flags = 0;
X		}
X	      else if (0x00000001 & t_ptr->flags)
X		if (randint(10) == 1) 
X		  {
X		    msg_print("The lock breaks open!");
X		    t_ptr->flags &= 0xFFFFFFFE;
X		  }
X	    }
X	  else
X	    msg_print("I do not see anything you can bash there.");
X	}
X      else
X	msg_print("I do not see anything you can bash there.");
X    }
X}
X
X
X/* Jam a closed door					-RAK-	*/
Xjamdoor()
X{
X  int y, x, tmp;
X  int i, j;
X  cave_type *c_ptr;
X  treasure_type *t_ptr, *i_ptr;
X  char tmp_str[80];
X  
X  y = char_row;
X  x = char_col;
X  if (get_dir("Which direction?", &tmp, &tmp, &y, &x)) 
X    {
X      c_ptr = &cave[y][x];
X      if (c_ptr->tptr != 0) 
X	{
X	  t_ptr = &t_list[c_ptr->tptr];
X	  if (t_ptr->tval == 105) 
X	    if (c_ptr->cptr == 0) 
X	      {
X		if (find_range(13, -1, &i, &j)) 
X		  {
X		    msg_print("You jam the door with a spike.");
X		    i_ptr = &inventory[i];
X		    if (i_ptr->number > 1) 
X			i_ptr->number--;
X		    else
X		      inven_destroy(i);
X		    t_ptr->p1 = -abs(i_ptr->p1) - 20;
X		  }
X		else
X		  msg_print("But you have no spikes...");
X	      }
X	    else
X	      {
X		(void) sprintf(tmp_str, "The %s is in your way!",
X			c_list[m_list[c_ptr->cptr].mptr].name);
X		msg_print(tmp_str);
X		}
X	  else if (t_ptr->tval == 104) 
X	    msg_print("The door must be closed first.");
X	  else
X	    msg_print("That isn't a door!");
X	}
X      else
X	msg_print("That isn't a door!");
X    }
X}
X
X
X/* Refill the players lamp				-RAK-	*/
Xrefill_lamp()
X{
X  int i, j, k;
X  treasure_type *i_ptr;
X
X  k = inventory[32].subval;
X  if ((k > 0) && (k < 10)) 
X    if (find_range(77, -1, &i, &j)) 
X      {
X	msg_print("Your lamp is full.");
X	i_ptr = &inventory[32];
X	i_ptr->p1 += inventory[i].p1;
X	if (i_ptr->p1 > OBJ_LAMP_MAX)  i_ptr->p1 = OBJ_LAMP_MAX;
X	desc_remain(i);
X	inven_destroy(i);
X      }
X    else
X      msg_print("You have no oil.");
X  else
X    msg_print("But you are not using a lamp.");
X}
END_OF_moria2.c
if test 47938 -ne `wc -c <moria2.c`; then
    echo shar: \"moria2.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 1 \(of 16\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 16 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0