[comp.sources.games] v05i042: umoria2 - single player dungeon simulation

games@tekred.TEK.COM (07/29/88)

Submitted by: "James E. Wilson" <wilson@ji.berkeley.edu>
Comp.sources.games: Volume 5, Issue 42
Archive-name: umoria2/Part08



#! /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 8 (of 18)."
# Contents:  io.c misc1.c
# Wrapped by billr@saab on Wed Jul 13 11:16:26 1988
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'io.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'io.c'\"
else
echo shar: Extracting \"'io.c'\" \(10941 characters\)
sed "s/^X//" >'io.c' <<'END_OF_FILE'
X#include <curses.h>
X#include <sys/types.h>
X#include <sys/ioctl.h>
X#include <sys/file.h>
X
X#include "constants.h"
X#include "config.h"
X#include "types.h"
X#include "externs.h"
X
X#ifdef USG
X#include <string.h>
X#else
X#include <strings.h>
X#include <sgtty.h>
X#include <sys/wait.h>
X#endif
X
X#ifdef sun   /* correct SUN stupidity in the stdio.h file */
Xchar *sprintf();
X#endif
X
Xvtype pad_output;   /* static output string for the pad function */
X
Xchar *getenv();
X
Xvtype old_msg[SAVED_MSGS];      /* Last messages      */
Xint last_message = 0;           /* Number of last msg generated in old_msg */
Xint last_displayed_msg = 0;     /* Number of last msg printed (^M) */
Xint repeating_old_msg = 0;      /* flag which lets repeat_msg call msg_print */
X
X/* value of msg flag at start of turn */
Xextern int save_msg_flag;
X
X#ifdef USG
Xvoid exit();
Xunsigned sleep();
X#endif
X#ifdef ultrix
Xvoid exit();
Xvoid sleep();
X#endif
X
X#ifdef USG
X/* no local special characters */
X#else
Xstruct ltchars save_special_chars;
X#endif
X
X/* initializes curses routines */
Xinit_curses()
X{
X#ifdef USG
X  /* no local special characters */
X#else
X  struct ltchars buf;
X#endif
X
X#ifdef USG
X  if (initscr() == NULL)
X#else
X  if (initscr() == ERR)
X#endif
X    {
X      (void) printf("error allocating screen in curses package\n");
X      exit_game();
X    }
X  clear();
X#ifdef USG
X  saveterm();
X#endif
X#if defined(ultrix)
X  crmode();
X#else
X  cbreak();
X#endif
X  noecho();
X#ifndef BUGGY_CURSES
X  nonl();
X#endif
X  /* save old settings of the local special characters */
X#ifdef USG
X  /* no local special characters */
X#else
X  (void) ioctl(0, TIOCGLTC, (char *)&save_special_chars);
X  /* disable all of the local special characters except the suspend char */
X  /* have to disable ^Y for tunneling */
X  buf.t_suspc = (char)26;  /* control-Z */
X  buf.t_dsuspc = (char)-1;
X  buf.t_rprntc = (char)-1;
X  buf.t_flushc = (char)-1;
X  buf.t_werasc = (char)-1;
X  buf.t_lnextc = (char)-1;
X  (void) ioctl(0, TIOCSLTC, (char *)&buf);
X#endif
X}
X
X
X/* Dump IO to buffer					-RAK-	*/
Xput_buffer(out_str, row, col)
Xchar *out_str;
Xint row, col;
X{
X  vtype tmp_str;
X
X  if (mvaddstr(row, col, out_str) == ERR)
X    {
X      (void) sprintf(tmp_str, "error row = %d col = %d\n", row, col);
X      prt(tmp_str, 0, 0);
X      /* wait so user can see error */
X      (void) sleep(2);
X    }
X}
X
X
X/* Dump the IO buffer to terminal			-RAK-	*/
Xput_qio()
X{
X  refresh();
X}
X
X
Xshell_out()
X{
X  int val;
X  char *str;
X#ifdef USG
X  /* no local special characters */
X#else
X  struct ltchars buf;
X#endif
X
X  /* clear screen and print 'exit' message */
X  clear_screen(0, 0);
X  prt("[Entering shell, type 'exit' to resume your game]\n",0,0);
X  put_qio();
X
X#ifndef BUGGY_CURSES
X  nl();
X#endif
X#if defined(ultrix)
X  nocrmode();
X#else
X  nocbreak();
X#endif
X  echo();
X  ignore_signals();
X  val = fork();
X  if (val == 0)
X    {
X      default_signals();
X#ifdef USG
X      /* no local special characters */
X      resetterm();
X#else
X      (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
X#endif
X      /* close scoreboard descriptor */
X      (void) close(highscore_fd);
X      if (str = getenv("SHELL"))
X	(void) execl(str, str, (char *) 0);
X      else
X	(void) execl("/bin/sh", "sh", (char *) 0);
X      msg_print("Cannot execute shell");
X      exit(1);
X    }
X  if (val == -1)
X    {
X      msg_print("Fork failed. Try again.");
X      return;
X    }
X#ifdef USG
X  (void) wait((int *) 0);
X#else
X  (void) wait((union wait *) 0);
X#endif
X  restore_signals();
X  /* restore the cave to the screen */
X  really_clear_screen();
X  draw_cave();
X#if defined(ultrix)
X  crmode();
X#else
X  cbreak();
X#endif
X  noecho();
X#ifndef BUGGY_CURSES
X  nonl();
X#endif
X  /* disable all of the local special characters except the suspend char */
X  /* have to disable ^Y for tunneling */
X#ifdef USG
X  /* no local special characters */
X#else
X  buf.t_suspc = (char)26;  /* control-Z */
X  buf.t_dsuspc = (char)-1;
X  buf.t_rprntc = (char)-1;
X  buf.t_flushc = (char)-1;
X  buf.t_werasc = (char)-1;
X  buf.t_lnextc = (char)-1;
X  (void) ioctl(0, TIOCSLTC, (char *)&buf);
X#endif
X}
X
Xexit_game()
X{
X  /* restore the saved values of the local special chars */
X  put_qio();	/* Dump any remaining buffer	*/
X  endwin();     /* exit curses */
X  echo();
X#ifndef BUGGY_CURSES
X  nl();
X#endif
X#if defined(ultrix)
X  nocrmode();
X#else
X  nocbreak();
X#endif
X#ifdef USG
X  /* no local special characters */
X  resetterm();
X#else
X  (void) ioctl(0, TIOCSLTC, (char *)&save_special_chars);
X#endif
X  exit(0);	/* exit from game		*/
X}
X
X
X/* Gets single character from keyboard and returns		*/
Xinkey(ch)
Xchar *ch;
X{
X  put_qio();			/* Dump IO buffer		*/
X  *ch = getch();
X  msg_flag = FALSE;
X}
X
X
X/* Flush the buffer					-RAK-	*/
Xflush()
X{
X#ifdef USG
X  (void) ioctl(0, TCFLSH, 0);  /* flush the input queue */
X#else
X  int arg;
X
X  arg = FREAD;
X  (void) ioctl(0, TIOCFLUSH, (char *)&arg);   /* flush all input */
X#endif
X}
X
X
X#if 0
X/* this is no longer used anywhere */
X/* Flush buffer before input				-RAK-	*/
Xinkey_flush(x)
Xchar *x;
X{
X  if (!wizard1)  flush();
X  inkey(x);
X}
X#endif
X
X/* Clears given line of text				-RAK-	*/
Xerase_line(row, col)
Xint row;
Xint col;
X{
X  move(row, col);
X  clrtoeol();
X  if (row == MSG_LINE)
X    msg_flag = FALSE;
X}
X
X
X/* Clears screen at given row, column				*/
Xclear_screen(row, col)
Xint row, col;
X{
X  register int i;
X
X  for (i = row; i < 23; i++)
X    used_line[i] = FALSE;
X  move(row, col);
X  clrtobot();
X  msg_flag = FALSE;
X}
X
X
X/* Clears entire screen, even if there are characters that curses
X   does not know about */
Xreally_clear_screen()
X{
X  register int i;
X
X  for (i = 1; i < 23; i++)
X    used_line[i] = FALSE;
X  clear();
X  msg_flag = FALSE;
X}
X
X
X/* Outputs a line to a given interpolated y, x position	-RAK-	*/
Xprint(str_buff, row, col)
Xchar *str_buff;
Xint row;
Xint col;
X{
X  row -= panel_row_prt;/* Real co-ords convert to screen positions */
X  col -= panel_col_prt;
X  used_line[row] = TRUE;
X  put_buffer(str_buff, row, col);
X}
X
X
X/* Outputs a line to a given y, x position		-RAK-	*/
Xprt(str_buff, row, col)
Xchar *str_buff;
Xint row;
Xint col;
X{
X  move(row, col);
X  clrtoeol();
X  put_buffer(str_buff, row, col);
X}
X
X
X/* move cursor to a given y, x position */
Xmove_cursor(row, col)
Xint row, col;
X{
X  move (row, col);
X}
X
X
X/* Outputs message to top line of screen				*/
Xmsg_print(str_buff)
Xchar *str_buff;
X{
X  register int old_len;
X  char in_char;
X  register int do_flush = 0;
X
X  /* stop the character if s/he is in a run */
X  if (find_flag)
X    {
X      find_flag = FALSE;
X      move_light (char_row, char_col, char_row, char_col);
X    }
X
X  if (msg_flag)
X    {
X      old_len = strlen(old_msg[last_message]) + 1;
X      put_buffer(" -more-", MSG_LINE, old_len);
X      /* let sigint handler know that we are waiting for a space */
X      wait_for_more = 1;
X      do
X	{
X	  inkey(&in_char);
X	}
X      while ((in_char != ' ') && (in_char != '\033'));
X      wait_for_more = 0;
X      do_flush = 1;
X    }
X  move(MSG_LINE, 0);
X  clrtoeol();
X  if (do_flush)
X    put_qio();
X  put_buffer(str_buff, MSG_LINE, 0);
X
X  if (!repeating_old_msg)
X    {
X      /* increment last message pointer */
X      last_message++;
X      if (last_message == SAVED_MSGS)
X	last_message = 0;
X      last_displayed_msg = last_message;
X      (void) strcpy(old_msg[last_message], str_buff);
X    }
X  msg_flag = TRUE;
X}
X
X
X/* repeat an old message */
Xrepeat_msg ()
X{
X  repeating_old_msg = 1;
X  /* if message still visible, decrement counter to display previous one */
X  if (save_msg_flag)
X    {
X      if (last_displayed_msg == 0)
X	last_displayed_msg = SAVED_MSGS;
X      last_displayed_msg--;
X      msg_flag = FALSE;
X      msg_print (old_msg[last_displayed_msg]);
X    }
X  else  /* display current message */
X    msg_print (old_msg[last_displayed_msg]);
X  repeating_old_msg = 0;
X}
X
X/* Prompts (optional) and returns ord value of input char	*/
X/* Function returns false if <ESCAPE> is input	*/
Xget_com(prompt, command)
Xchar *prompt;
Xchar *command;
X{
X  int com_val;
X  int res;
X
X  if (strlen(prompt) > 1)
X    prt(prompt, 0, 0);
X  inkey(command);
X  com_val = (*command);
X  switch(com_val)
X    {
X    case 0: case 27:
X      res = FALSE;
X      break;
X    default:
X      res = TRUE;
X      break;
X    }
X  erase_line(MSG_LINE, 0);
X  msg_flag = FALSE;
X  return(res);
X}
X
X
X/* Gets a string terminated by <RETURN>				*/
X/* Function returns false if <ESCAPE>, CNTL/(Y, C, Z) is input	*/
Xint get_string(in_str, row, column, slen)
Xchar *in_str;
Xint row, column, slen;
X{
X  register int start_col, end_col, i;
X  char x;
X  char tmp[2];
X  int flag, abort;
X
X  abort = FALSE;
X  flag  = FALSE;
X  in_str[0] = '\0';
X  tmp[1] = '\0';
X  put_buffer(pad(in_str, " ", slen), row, column);
X  put_buffer("\0", row, column);
X  start_col = column;
X  end_col = column + slen - 1;
X  do
X    {
X      inkey(&x);
X      switch(x)
X	{
X	case 27:
X	  abort = TRUE;
X	  break;
X	case 10: case 13:
X	  flag  = TRUE;
X	  break;
X	case 127: case 8:
X	  if (column > start_col)
X	    {
X	      column--;
X	      put_buffer(" \b", row, column);
X	      in_str[strlen(in_str)-1] = '\0';
X	    }
X	  break;
X	default:
X	  tmp[0] = x;
X	  put_buffer(tmp, row, column);
X	  (void) strcat(in_str, tmp);
X	  column++;
X	  if (column > end_col)
X	    flag = TRUE;
X	  break;
X	}
X    }
X  while ((!flag) && (!abort));
X  if (abort)
X    return(FALSE);
X  else
X    {			/* Remove trailing blanks	*/
X      i = strlen(in_str);
X      if (i > 0)
X	{
X	  while ((in_str[i] == ' ') && (i > 0))
X	    i--;
X	  in_str[i+1] = '\0';
X	}
X    }
X  return(TRUE);
X}
X
X
X/* Return integer value of hex string			-RAK-	*/
Xint get_hex_value(row, col, slen)
Xint row, col, slen;
X{
X  vtype tmp_str;
X  int hex_value;
X
X  hex_value = 0;
X  if (get_string(tmp_str, row, col, slen))
X    if (strlen(tmp_str) <= 8)
X      {
X	(void) sscanf(tmp_str, "%x", &hex_value);
X      }
X  return(hex_value);
X}
X
X
X/* Pauses for user response before returning		-RAK-	*/
Xpause_line(prt_line)
Xint prt_line;
X{
X  char dummy;
X
X  prt("[Press any key to continue]", prt_line, 23);
X  inkey(&dummy);
X  erase_line(23, 0);
X}
X
X
X/* Pauses for user response before returning		-RAK-	*/
X/* NOTE: Delay is for players trying to roll up "perfect"	*/
X/*	characters.  Make them wait a bit...			*/
Xpause_exit(prt_line, delay)
Xint prt_line;
Xint delay;
X{
X  char dummy;
X
X  prt("[Press any key to continue, or Q to exit]", prt_line, 10);
X  inkey(&dummy);
X  switch(dummy)
X    {
X    case 'Q':
X      erase_line(prt_line, 0);
X      if (delay > 0)  (void) sleep((unsigned)delay);
X      exit_game();
X      break;
X    default:
X      break;
X    }
X  erase_line(prt_line, 0);
X}
X
X
X/* pad a string with fill characters to specified length */
Xchar *pad(string, fill, filllength)
Xchar *string;
Xchar *fill;
Xint filllength;
X{
X  register int length, i;
X
X  (void) strcpy(pad_output, string);
X  length = strlen(pad_output);
X  for (i = length; i < filllength; i++)
X    pad_output[i] = *fill;
X  pad_output[i] = '\0';
X  return(pad_output);
X}
X
Xint confirm()
X{
X  char command;
X
X  if (get_com("Are you sure?", &command))
X    switch(command)
X      {
X      case 'y': case 'Y':
X	return TRUE;
X	
X      default:
X	return FALSE;
X      }
X  return FALSE;
X}
X
END_OF_FILE
if test 10941 -ne `wc -c <'io.c'`; then
    echo shar: \"'io.c'\" unpacked with wrong size!
fi
# end of 'io.c'
fi
if test -f 'misc1.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'misc1.c'\"
else
echo shar: Extracting \"'misc1.c'\" \(41617 characters\)
sed "s/^X//" >'misc1.c' <<'END_OF_FILE'
X#include <time.h>
X#include <math.h>
X#include <stdio.h>
X#include <sys/types.h>
X
X#include "constants.h"
X#include "config.h"
X#include "types.h"
X/* SUN4 has a variable called class in the include file <math.h>
X   avoid a conflict by not defining my class in the file externs.h */
X#define DONT_DEFINE_CLASS
X#include "externs.h"
X
X#ifdef USG
X#include <string.h>
X#else
X#include <strings.h>
X#endif
X
Xlong time();
Xstruct tm *localtime();
Xdouble sqrt();
Xdouble cos();
Xdouble fabs();
X#if defined(ultrix) || defined(sun) || defined(USG)
Xint getuid();
Xint geteuid();
Xint getgid();
Xint getegid();
X#else
Xuid_t getuid();
Xuid_t geteuid();
Xuid_t getgid();
Xuid_t getegid();
X#endif
X
X#ifdef USG
Xlong lrand48();
Xvoid srand48();
Xunsigned short *seed48();
X#else
Xlong random();
Xchar *initstate();
Xchar *setstate();
X#endif
X
X#ifdef ultrix
Xvoid srandom();
X#endif
X
X/* gets a new random seed for the random number generator */
Xinit_seeds()
X{
X  register long clock;
X  register int euid;
X
X  /* in case game is setuid root */
X  if ((euid = geteuid()) == 0)
X    euid = (int)time((long *)0);
X
X  clock = time((long *)0);
X  clock = clock * getpid() * euid;
X#ifdef USG
X  /* only uses randes_seed */
X#else
X  (void) initstate((unsigned int)clock, randes_state, STATE_SIZE);
X#endif
X  randes_seed = (unsigned int)clock;
X
X  clock = time((long *)0);
X  clock = clock * getpid() * euid;
X#ifdef USG
X  /* only uses town_seed */
X#else
X  (void) initstate((unsigned int)clock, town_state, STATE_SIZE);
X#endif
X  town_seed = (unsigned int)clock;
X
X  clock = time((long *)0);
X#if 0
X  clock = clock * getpid() * euid * getuid();
X#endif
X#ifdef USG
X  /* can't do this, so fake it */
X  srand48(clock);
X  /* make it a little more random */
X  for (clock = randint(100); clock >= 0; clock--)
X    (void) lrand48();
X#else
X  (void) initstate((unsigned int)clock, norm_state, STATE_SIZE);
X  /* make it a little more random */
X  for (clock = randint(100); clock >= 0; clock--)
X    (void) random();
X#endif
X}
X
X#ifdef USG
X/* special array for restoring the SYS V number generator */
Xunsigned short oldseed[3];
X#endif
X
X/* change to different random number generator state */
X/*ARGSUSED*/
Xset_seed(state, seed)
Xchar *state;
Xint seed;
X{
X#ifdef USG
X  register unsigned short *pointer;
X
X  /* make phony call to get pointer to old value of seed */
X  pointer = seed48(oldseed);
X  /* copy old seed into oldseed */
X  oldseed[0] = pointer[0];
X  oldseed[1] = pointer[1];
X  oldseed[2] = pointer[2];
X
X  /* want reproducible state here, so call srand48 */
X  srand48((long)seed);
X#else
X  (void) setstate(state);
X  /* want reproducible state here, so call srandom */
X  srandom(seed);
X#endif
X}
X
X
X/* restore the normal random generator state */
Xreset_seed()
X{
X#ifdef USG
X  (void) seed48(oldseed);
X#if 0
X  /* can't do this, so just call srand() with the current time */
X  srand48((unsigned int)(time ((long *)0)));
X#endif
X#else
X  (void) setstate(norm_state);
X#endif
X}
X
X
X/* Returns the day number; 0==Sunday...6==Saturday 	-RAK-	*/
Xint day_num()
X{
X  long clock;
X  register struct tm *time_struct;
X
X  clock = time((long *)0);
X  time_struct = localtime(&clock);
X  return (time_struct->tm_wday);
X}
X
X
X/* Returns the hour number; 0==midnight...23==11 PM	-RAK-	*/
Xint hour_num()
X{
X  long clock;
X  register struct tm *time_struct;
X
X  clock = time((long *)0);
X  time_struct = localtime(&clock);
X  return (time_struct->tm_hour);
X}
X
X
X/* Check the day-time strings to see if open		-RAK-	*/
Xint check_time()
X{
X switch ((int)days[day_num()][(hour_num()+4)]) {
X   case '.':  return(FALSE);    /* Closed                */
X   case 'X':  return(TRUE);     /* Normal hours          */
X   default:   return(FALSE);    /* Other, assumed closed */
X   }
X}
X
X
X/* Generates a random integer x where 1<==X<==MAXVAL	-RAK-	*/
Xint randint(maxval)
Xint maxval;
X{
X  register long randval;
X
X#ifdef USG
X  randval = lrand48();
X#else
X  randval = random();
X#endif
X  return ((randval % maxval) + 1);
X}
X
X/* For i := 1 to y do sum := sum + randint(x) */
Xint rand_rep(num, die)
Xint num;
Xint die;
X{
X  register int sum = 0;
X  register int i;
X
X  for (i = 0; i < num; i++)
X    sum += randint(die);
X  return(sum);
X}
X
X/* Generates a random integer number of NORMAL distribution -RAK-*/
Xint randnor(mean, stand)
Xint mean;
Xint stand;
X{
X  return ((int)((sqrt(-2.0*log(randint((int)9999999)/10000000.0))*
X		 cos(6.283*(randint((int)9999999)/10000000.0))*stand) + mean));
X}
X
X
X/* Returns position of first set bit			-RAK-	*/
X/*     and clears that bit */
Xint bit_pos(test)
Xunsigned int *test;
X{
X  register int i;
X  register int mask = 0x1;
X
X  for (i = 0; i < sizeof(int)*8; i++) {
X    if (*test & mask) {
X      *test &= ~mask;
X      return(i);
X    }
X    mask <<= 1;
X  }
X
X  /* no one bits found */
X  return(-1);
X}
X
X/* Checks a co-ordinate for in bounds status		-RAK-	*/
Xint in_bounds(y, x)
Xint y, x;
X{
X  if ((y > 0) && (y < cur_height-1) && (x > 0) && (x < cur_width-1))
X    return(TRUE);
X  else
X    return(FALSE);
X}
X
X
X/* Distance between two points				-RAK-	*/
X/* there is a bessel function names y1 in the math library, ignore warning */
Xint distance(y1, x1, y2, x2)
Xint y1, x1, y2, x2;
X{
X  register int dy, dx;
X
X  dy = y1 - y2;
X  if (dy < 0)
X    dy = -dy;
X  dx = x1 - x2;
X  if (dx < 0)
X    dx = -dx;
X
X  return( (2 * (dy + dx) - (dy > dx ? dx : dy)) / 2);
X}
X
X/* Checks points north, south, east, and west for a type -RAK-	*/
Xint next_to4(y, x, elem_a, elem_b, elem_c)
Xregister int y, x;
Xint elem_a, elem_b, elem_c;
X{
X  register int i;
X
X  i = 0;
X  if (y > 0)
X    if ((cave[y-1][x].fval == elem_a) || (cave[y-1][x].fval == elem_b) ||
X	(cave[y-1][x].fval == elem_c))
X      i++;
X  if (y < cur_height-1)
X    if ((cave[y+1][x].fval == elem_a) || (cave[y+1][x].fval == elem_b) ||
X	(cave[y+1][x].fval == elem_c))
X      i++;
X  if (x > 0)
X    if ((cave[y][x-1].fval == elem_a) || (cave[y][x-1].fval == elem_b) ||
X	(cave[y][x-1].fval == elem_c))
X      i++;
X  if (x < cur_width-1)
X    if ((cave[y][x+1].fval == elem_a) || (cave[y][x+1].fval == elem_b) ||
X	(cave[y][x+1].fval == elem_c))
X      i++;
X  return(i);
X}
X
X
X/* Checks all adjacent spots for elements		-RAK-	*/
Xint next_to8(y, x, elem_a, elem_b, elem_c)
Xregister int y, x;
Xint elem_a, elem_b, elem_c;
X{
X  register int k, j, i;
X
X  i = 0;
X  for (j = (y - 1); j <= (y + 1); j++)
X    for (k = (x - 1); k <= (x + 1); k++)
X      if (in_bounds(j, k))
X	if ((cave[j][k].fval == elem_a) || (cave[j][k].fval == elem_b) ||
X	    (cave[j][k].fval == elem_c))
X	  i++;
X  return(i);
X}
X
X
X/* Link all free space in treasure list together 		*/
Xtlink()
X{
X  register int i;
X
X  for (i = 0; i < MAX_TALLOC; i++)
X    {
X      t_list[i] = blank_treasure;
X      t_list[i].p1 = i - 1;
X    }
X  tcptr = MAX_TALLOC - 1;
X}
X
X
X/* Link all free space in monster list together			*/
Xmlink()
X{
X  register int i;
X
X  for (i = 0; i < MAX_MALLOC; i++)
X    {
X      m_list[i] = blank_monster;
X      m_list[i].nptr = i - 1;
X    }
X  m_list[1].nptr = 0;
X  muptr = 0;
X  mfptr = MAX_MALLOC - 1;
X}
X
X
X/* Initializes M_LEVEL array for use with PLACE_MONSTER	-RAK-	*/
Xinit_m_level()
X{
X  register int i, j, k;
X
X  i = 0;
X  j = 0;
X  k = MAX_CREATURES - WIN_MON_TOT;
X  while (j <= MAX_MONS_LEVEL) {
X    m_level[j] = 0;
X    while ((i < k) && (c_list[i].level == j))
X      {
X	m_level[j]++;
X	i++;
X      }
X    j++;
X  }
X  for (i = 2; i <= MAX_MONS_LEVEL; i++)
X    m_level[i] += m_level[i-1];
X}
X
X
X/* Initializes T_LEVEL array for use with PLACE_OBJECT	-RAK-	*/
Xinit_t_level()
X{
X  register int i, j;
X
X  i = 0;
X  j = 0;
X  while ((j <= MAX_OBJ_LEVEL) && (i < MAX_OBJECTS))
X    {
X      while ((i < MAX_OBJECTS) && (object_list[i].level == j))
X	{
X	  t_level[j]++;
X	  i++;
X	}
X      j++;
X    }
X  for (i = 1; i <= MAX_OBJ_LEVEL; i++)
X    t_level[i] += t_level[i-1];
X}
X
X
X/* Adjust prices of objects				-RAK-	*/
Xprice_adjust()
X{
X  register int i;
X
X  for (i = 0; i < MAX_OBJECTS; i++)
X    object_list[i].cost = object_list[i].cost*COST_ADJ + 0.99;
X  for (i = 0; i < INVEN_INIT_MAX; i++)
X    inventory_init[i].cost = inventory_init[i].cost*COST_ADJ + 0.99;
X}
X
X
X/* Converts input string into a dice roll		-RAK-	*/
X/*       Normal input string will look like "2d6", "3d8"... etc. */
Xint damroll(dice)
Xchar *dice;
X{
X  int num, sides;
X
X  num = 0;
X  sides = 0;
X  (void) sscanf(dice, "%d d %d", &num, &sides);
X  return(rand_rep(num, sides));
X}
X
X
X/* Returns true if no obstructions between two given points -RAK-*/
X/* there is a bessel function names y1 in the math library, ignore warning */
Xint los(y1, x1, y2, x2)
Xint y1, x1, y2, x2;
X{
X  register int ty, tx, stepy, stepx;
X  int aty, atx, p1, p2;
X  double slp, tmp;
X  int flag;
X
X  ty = (y1 - y2);
X  tx = (x1 - x2);
X  flag = TRUE;
X  if ((ty != 0) || (tx != 0))
X    {
X      if (ty < 0)
X	{
X	  stepy = -1;
X	  aty = -ty;
X	}
X      else
X	{
X	  stepy = 1;
X	  aty = ty;
X	}
X      if (tx < 0)
X	{
X	  stepx = -1;
X	  atx = -tx;
X	}
X      else
X	{
X	  stepx = 1;
X	  atx = tx;
X	}
X      if (ty == 0)
X	{
X	  do
X	    {
X	      x2 += stepx;
X	      flag = cave[y2][x2].fopen;
X	    }
X	  while((x1 != x2) && (flag));
X	}
X      else if (tx == 0)
X	{
X	  do
X	    {
X	      y2 += stepy;
X	      flag = cave[y2][x2].fopen;
X	    }
X	  while((y1 != y2) && (flag));
X	}
X      else if (aty > atx)
X	{
X	  slp = ((double)atx / (double)aty) * stepx;
X	  tmp = x2;
X	  do
X	    {
X	      y2 += stepy;
X	      tmp += slp;
X              /* round to nearest integer */
X	      p1 = (int)floor(tmp - 0.1 + 0.5);
X	      p2 = (int)floor(tmp + 0.1 + 0.5);
X	      if ((!cave[y2][p1].fopen) && (!cave[y2][p2].fopen))
X		  flag = FALSE;
X	    }
X	  while((y1 != y2) && (flag));
X	}
X      else
X	{
X	  slp = ((double)aty / (double)atx) * stepy;
X	  tmp = y2;
X	  do
X	    {
X	      x2 += stepx;
X	      tmp += slp;
X              /* round to nearest integer */
X	      p1 = (int)floor(tmp - 0.1 + 0.5);
X	      p2 = (int)floor(tmp + 0.1 + 0.5);
X	      if ((!cave[p1][x2].fopen) && (!cave[p2][x2].fopen))
X		flag = FALSE;
X	    }
X	  while((x1 != x2) && (flag));
X	}
X    }
X  return(flag);
X}
X
X
X/* Returns symbol for given row, column			-RAK-	*/
Xloc_symbol(y, x, sym)
Xint y, x;
Xchar *sym;
X{
X  register cave_type *cave_ptr;
X  register monster_type *mon_ptr;
X
X  cave_ptr = &cave[y][x];
X  if ((cave_ptr->cptr == 1) && (!find_flag))
X    *sym = '@';
X  else if (py.flags.blind > 0)
X    *sym = ' ';
X  else
X    {
X      if (cave_ptr->cptr > 1)
X	{
X	  mon_ptr = &m_list[cave_ptr->cptr];
X	  if ((mon_ptr->ml) &&
X	      (((c_list[mon_ptr->mptr].cmove & 0x00010000) == 0) ||
X	       (py.flags.see_inv)))
X	    *sym = c_list[mon_ptr->mptr].cchar;
X	  else if (cave_ptr->tptr != 0)
X	    *sym = t_list[cave_ptr->tptr].tchar;
X	  else if (cave_ptr->fval < 10)
X	    *sym = '.';
X	  else
X	    *sym = '#';
X	}
X      else if (cave_ptr->tptr != 0)
X	*sym = t_list[cave_ptr->tptr].tchar;
X      else if (cave_ptr->fval < 10)
X	*sym = '.';
X      else
X	*sym = '#';
X    }
X}
X
X
X/* Tests a spot for light or field mark status		-RAK-	*/
Xint test_light(y, x)
Xint y, x;
X{
X  register cave_type *cave_ptr;
X
X  cave_ptr = &cave[y][x];
X  if ((cave_ptr->pl) || (cave_ptr->fm) || (cave_ptr->tl))
X    return(TRUE);
X  else
X    return(FALSE);
X}
X
X
X/* Prints the map of the dungeon 			-RAK-	*/
Xprt_map()
X{
X  register int i, j, k;
X  int l, m;
X  int ypos, isp;
X  /* this eliminates lint warning: xpos may be used before set */
X  int xpos = 0;
X  vtype floor_str;
X  char tmp_char[2];
X  int flag;
X  register cave_type *cave_ptr;
X
X  k = 0;                          /* Used for erasing dirty lines  */
X  l = 13;                         /* Erasure starts in this column */
X  for (i = panel_row_min; i <= panel_row_max; i++)  /* Top to bottom */
X    {
X      k++;                     /* Increment dirty line ctr      */
X      if (used_line[k])        /* If line is dirty...           */
X	{
X	  erase_line(k, l);        /* erase it.                    */
X	  used_line[k] = FALSE;   /* Now it's a clean line         */
X	}
X      floor_str[0] = '\0';              /* Floor_str is string to be printed*/
X      ypos = i;                   /* Save row                      */
X      flag = FALSE;                /* False until floor_str != ""   */
X      isp = 0;                     /* Number of blanks encountered  */
X      for (j = panel_col_min; j <= panel_col_max; j++)  /* Left to right */
X	{
X	  cave_ptr = &cave[i][j];    /* Get character for location    */
X	  if (cave_ptr->pl || cave_ptr->fm || cave_ptr->tl)
X	    loc_symbol(i, j, tmp_char);
X	  else if ((cave_ptr->cptr == 1) && (!find_flag))
X	    tmp_char[0] = '@';
X	  else if (cave_ptr->cptr > 1)
X	    if (m_list[cave_ptr->cptr].ml)
X	      loc_symbol(i, j, tmp_char);
X	    else
X	      tmp_char[0] = ' ';
X	  else
X	    tmp_char[0] = ' ';
X	  if (py.flags.image > 0)
X	    if (randint(12) == 1)
X	      tmp_char[0] = (randint(95) + 31);
X	  if (tmp_char[0] == ' ') /* If blank...                   */
X	    {
X	      if (flag)       /* If floor_str != ""        */
X		{
X		  isp++;      /* Increment blank ctr           */
X		  if (isp > 3)        /* Too many blanks, print*/
X		    {                 /* floor_str and reset   */
X		      print(floor_str, ypos, xpos);
X		      flag = FALSE;
X		      isp = 0;
X		    }
X		}
X	    }
X	  else
X	    {
X	      if (flag)       /* Floor_str != ""               */
X		{
X		  if (isp > 0)        /* Add on the blanks     */
X		    {
X		      for (m = 0; m < isp; m++)
X			(void) strcat(floor_str, " ");
X		      isp = 0;
X		    }                  /* Add on the character  */
X		  tmp_char[1] = '\0';
X		  (void) strcat(floor_str, tmp_char);
X		}
X	      else
X		{             /* Floor_str == ""                */
X		  xpos = j;     /* Save column for printing      */
X		  flag = TRUE;   /* Set flag to true              */
X		  floor_str[0] = tmp_char[0];  /* Floor_str != ""       */
X		  floor_str[1] = '\0';
X		}
X	    }
X	}
X      if (flag)                 /* Print remainder, if any       */
X	print(floor_str, ypos, xpos);
X    }
X}
X
X
X/* Compact monsters					-RAK-	*/
Xcompact_monsters()
X{
X  register int i, j, k;
X  int cur_dis;
X  int delete_1, delete_any;
X  register monster_type *mon_ptr;
X
X  cur_dis = 66;
X  delete_any = FALSE;
X  do
X    {
X      i = muptr;
X      j = 0;
X      while (i > 0)
X	{
X	  delete_1 = FALSE;
X	  k = m_list[i].nptr;
X	  mon_ptr = &m_list[i];
X	  if (cur_dis > mon_ptr->cdis)
X	    if (randint(3) == 1)
X	      {
X		if (j == 0)
X		  muptr = k;
X		else
X		  m_list[j].nptr = k;
X		cave[mon_ptr->fy][mon_ptr->fx].cptr = 0;
X		m_list[i] = blank_monster;
X		m_list[i].nptr = mfptr;
X		mfptr = i;
X		delete_1 = TRUE;
X		delete_any = TRUE;
X	      }
X	  if (!delete_1)
X	    j = i;
X	  i = k;
X	}
X      if (!delete_any)
X	cur_dis -= 6;
X    }
X  while (!delete_any);
X  if (cur_dis < 66)
X    prt_map();
X}
X
X
X/* Returns a pointer to next free space			-RAK-	*/
Xpopm(x)
Xregister int *x;
X{
X  if (mfptr <= 1)
X    compact_monsters();
X  *x = mfptr;
X  mfptr = m_list[*x].nptr;
X}
X
X
X/* Pushs a record back onto free space list		-RAK-	*/
Xpushm(x)
Xregister int x;
X{
X  m_list[x] = blank_monster;
X  m_list[x].nptr = mfptr;
X  mfptr = x;
X}
X
X
X/* Gives Max hit points					-RAK-	*/
Xint max_hp(hp_str)
Xchar *hp_str;
X{
X  int num, die;
X
X  (void) sscanf(hp_str, "%d d %d", &num, &die);
X  return(num*die);
X}
X
X
X/* Places a monster at given location			-RAK-	*/
Xplace_monster(y, x, z, slp)
Xregister int y, x, z;
Xint slp;
X{
X  int cur_pos;
X  register monster_type *mon_ptr;
X
X  popm(&cur_pos);
X  mon_ptr = &m_list[cur_pos];
X  mon_ptr->fy = y;
X  mon_ptr->fx = x;
X  mon_ptr->mptr = z;
X  mon_ptr->nptr = muptr;
X  muptr = cur_pos;
X  if (c_list[z].cdefense & 0x4000)
X    mon_ptr->hp = max_hp(c_list[z].hd);
X  else
X    mon_ptr->hp = damroll(c_list[z].hd);
X  mon_ptr->cspeed = c_list[z].speed + py.flags.speed;
X  mon_ptr->stunned = 0;
X  mon_ptr->cdis = distance(char_row, char_col,y,x);
X  cave[y][x].cptr = cur_pos;
X  if (slp)
X    {
X      if (c_list[z].sleep == 0)
X	mon_ptr->csleep = 0;
X      else
X	mon_ptr->csleep = (c_list[z].sleep/5.0) + randint(c_list[z].sleep);
X    }
X  else
X    mon_ptr->csleep = 0;
X}
X
X
X/* Places a monster at given location			-RAK-	*/
Xplace_win_monster()
X{
X  int cur_pos;
X  register int y, x;
X  register monster_type *mon_ptr;
X
X  if (!total_winner)
X    {
X      popm(&cur_pos);
X      mon_ptr = &m_list[cur_pos];
X      do
X	{
X	  y = randint(cur_height-2);
X	  x = randint(cur_width-2);
X	}
X      while (((cave[y][x].fval != 1) && (cave[y][x].fval != 2) &&
X		(cave[y][x].fval != 4)) ||
X	     (cave[y][x].cptr != 0) ||
X	     (cave[y][x].tptr != 0) ||
X	     (distance(y,x,char_row, char_col) <= MAX_SIGHT));
X      mon_ptr->fy = y;
X      mon_ptr->fx = x;
X      mon_ptr->mptr = randint(WIN_MON_TOT) - 1 + m_level[MAX_MONS_LEVEL] +
X	m_level[0];
X      mon_ptr->nptr = muptr;
X      muptr = cur_pos;
X      if (c_list[mon_ptr->mptr].cdefense & 0x4000)
X	mon_ptr->hp = max_hp(c_list[mon_ptr->mptr].hd);
X      else
X	mon_ptr->hp = damroll(c_list[mon_ptr->mptr].hd);
X      mon_ptr->cspeed = c_list[mon_ptr->mptr].speed + py.flags.speed;
X      mon_ptr->stunned = 0;
X      mon_ptr->cdis = distance(char_row, char_col,y,x);
X      cave[y][x].cptr = cur_pos;
X      mon_ptr->csleep = 0;
X    }
X}
X
X/* Allocates a random monster				-RAK-	*/
Xalloc_monster(alloc_set, num, dis, slp)
Xint (*alloc_set)();
Xint num, dis;
Xint slp;
X{
X  register int y, x, i, j, k;
X
X  for (i = 0; i < num; i++)
X    {
X      do
X	{
X	  y = randint(cur_height-2);
X	  x = randint(cur_width-2);
X	}
X      while ((!(*alloc_set)(cave[y][x].fval)) ||
X		 (cave[y][x].cptr != 0) ||
X		 (!cave[y][x].fopen) ||
X		 (distance(y,x,char_row, char_col) <= dis));
X      if (dun_level == 0)
X	j = randint(m_level[0]) - 1;
X      else if (dun_level >= MAX_MONS_LEVEL)
X	j = randint(m_level[MAX_MONS_LEVEL]) - 1 + m_level[0];
X      else if (randint(MON_NASTY) == 1)
X	{
X	  /* abs may be a macro, don't call it with randnor as a parameter */
X	  k = randnor(0, 4);
X	  j = dun_level + abs(k) + 1;
X	  if (j > MAX_MONS_LEVEL)
X	    j = MAX_MONS_LEVEL;
X	  k = m_level[j] - m_level[j-1];
X	  j = randint(k) - 1 + m_level[j-1];
X	}
X      else
X	j = randint(m_level[dun_level]) - 1 + m_level[0];
X      place_monster(y, x, j, slp);
X    }
X}
X
X
X/* Places creature adjacent to given location		-RAK-	*/
Xint summon_monster(y, x, slp)
Xint *y, *x;
Xint slp;
X{
X  register int i, j, k;
X  int l, m;
X  register cave_type *cave_ptr;
X  int summon;
X
X  i = 0;
X  m = dun_level + MON_SUMMON_ADJ;
X  summon = FALSE;
X  if (m > MAX_MONS_LEVEL)
X    l = MAX_MONS_LEVEL;
X  else
X    l = m;
X  if (dun_level == 0)
X    l = randint(m_level[0]) - 1;
X  else
X    l = randint(m_level[l]) - 1 + m_level[0];
X  do
X    {
X      j = *y - 2 + randint(3);
X      k = *x - 2 + randint(3);
X      if (in_bounds(j, k))
X	{
X	  cave_ptr = &cave[j][k];
X	  if ((cave_ptr->fval == 1) || (cave_ptr->fval == 2) ||
X	      (cave_ptr->fval == 4) || (cave_ptr->fval == 5))
X	    if (cave_ptr->cptr == 0)
X	      if (cave_ptr->fopen)
X		{
X		  place_monster(j, k, l, slp);
X		  summon = TRUE;
X		  i = 9;
X		  *y = j;
X		  *x = k;
X		}
X	}
X      i++;
X    }
X  while (i <= 9);
X  return(summon);
X}
X
X
X/* Places undead adjacent to given location		-RAK-	*/
Xint summon_undead(y, x)
Xint *y, *x;
X{
X  register int i, j, k;
X  int l, m, ctr;
X  int summon;
X  register cave_type *cave_ptr;
X
X  i = 0;
X  summon = FALSE;
X  l = m_level[MAX_MONS_LEVEL] + m_level[0];
X  do
X    {
X      m = randint(l) - 1;
X      ctr = 0;
X      do
X	{
X	  if (c_list[m].cdefense & 0x0008)
X	    {
X	      ctr = 20;
X	      l  = 0;
X	    }
X	  else
X	    {
X	      m++;
X	      if (m > l)
X		ctr = 20;
X	      else
X		ctr++;
X	    }
X	}
X      while (ctr <= 19);
X    }
X  while(l != 0);
X  do
X    {
X      j = *y - 2 + randint(3);
X      k = *x - 2 + randint(3);
X      if (in_bounds(j, k))
X	{
X	  cave_ptr = &cave[j][k];
X	  if ((cave_ptr->fval == 1) || (cave_ptr->fval == 2) ||
X	      (cave_ptr->fval == 4) || (cave_ptr->fval == 5))
X	    if ((cave_ptr->cptr == 0) && (cave_ptr->fopen))
X	      {
X		place_monster(j, k, m, FALSE);
X		summon = TRUE;
X		i = 9;
X		*y = j;
X		*x = k;
X	      }
X	}
X      i++;
X    }
X  while(i <= 9);
X  return(summon);
X}
X
X
X/* If too many objects on floor level, delete some of them-RAK-	*/
Xcompact_objects()
X{
X  register int i, j;
X  int ctr, cur_dis;
X  int flag;
X  register cave_type *cave_ptr;
X  register treasure_type *t_ptr;
X
X  ctr = 0;
X  cur_dis = 66;
X  do
X    {
X      for (i = 0; i < cur_height; i++)
X	for (j = 0; j < cur_width; j++)
X	  {
X	    cave_ptr = &cave[i][j];
X	    if (cave_ptr->tptr != 0)
X	      if (distance(i, j, char_row, char_col) > cur_dis)
X		{
X		  flag = FALSE;
X		  t_ptr = &t_list[cave_ptr->tptr];
X		  switch(t_ptr->tval)
X		    {
X		    case 102:
X		      if ((t_ptr->subval == 1) || (t_ptr->subval == 6) ||
X			  (t_ptr->subval == 9))
X			flag = TRUE;
X		      else if (randint(4) == 1)
X			flag = TRUE;
X		      break;
X		    case 103:
X		      flag = TRUE;
X		      break;
X		    case 104: case 105:
X		      /* doors */
X		      if (randint(4) == 1)  flag = TRUE;
X		      break;
X		    case 107: case 108:
X		      /* stairs, don't delete them */
X		      break;
X		    case 110:
X		      /* shop doors, don't delete them */
X		      break;
X		    default:
X		      if (randint(8) == 1)  flag = TRUE;
X		    }
X		  if (flag)
X		    {
X		      cave_ptr->fopen = TRUE;
X		      t_list[cave_ptr->tptr] = blank_treasure;
X		      t_list[cave_ptr->tptr].p1 = tcptr;
X		      tcptr = cave_ptr->tptr;
X		      cave_ptr->tptr = 0;
X		      ctr++;
X		    }
X		}
X	    if (ctr == 0)  cur_dis -= 6;
X	  }
X    }
X  while (ctr <= 0);
X  if (cur_dis < 66)  prt_map();
X}
X
X
X
X/* Gives pointer to next free space			-RAK-	*/
Xpopt(x)
Xint *x;
X{
X  if (tcptr < 1)
X    compact_objects();
X  *x = tcptr;
X  tcptr = t_list[*x].p1;
X}
X
X
X/* Pushs a record back onto free space list		-RAK-	*/
Xpusht(x)
Xregister int x;
X{
X  t_list[x] = blank_treasure;
X  t_list[x].p1 = tcptr;
X  tcptr = x;
X}
X
X
X/* Order the treasure list by level			-RAK-	*/
Xsort_objects()
X{
X  register int i, j, k, gap;
X  treasure_type tmp;
X
X  gap = MAX_OBJECTS / 2;
X  while (gap > 0)
X    {
X      for (i = gap; i < MAX_OBJECTS; i++)
X	{
X	  j = i - gap;
X	  while (j >= 0)
X	    {
X	      k = j + gap;
X	      if (object_list[j].level > object_list[k].level)
X		{
X		  tmp = object_list[j];
X		  object_list[j] = object_list[k];
X		  object_list[k] = tmp;
X		}
X	      else
X		j = -1;
X	      j -= gap;
X	    }
X	}
X      gap = gap / 2;
X    }
X}
X
X
X/* Boolean : is object enchanted 	  -RAK- */
Xint magik(chance)
Xint chance;
X{
X  if (randint(100) <= chance)
X    return(TRUE);
X  else
X    return(FALSE);
X}
X
X
X/* Enchant a bonus based on degree desired -RAK- */
Xint m_bonus(base, max_std, level)
Xint base, max_std, level;
X{
X  register int x, stand_dev;
X  register int tmp;
X
X  stand_dev = (OBJ_STD_ADJ*level) + OBJ_STD_MIN;
X  if (stand_dev > max_std)
X    stand_dev = max_std;
X  /* abs may be a macro, don't call it with randnor as a parameter */
X  tmp = randnor(0, stand_dev);
X  x = (abs(tmp)/10.0) + base;
X  if (x < base)
X    return(base);
X  else
X    return(x);
X}
X
X
X/* Chance of treasure having magic abilities		-RAK-	*/
X/* Chance increases with each dungeon level                      */
Xmagic_treasure(x, level)
Xint x, level;
X{
X  register treasure_type *t_ptr;
X  register int chance, special, cursed, i;
X
X  chance = OBJ_BASE_MAGIC + level;
X  if (chance > OBJ_BASE_MAX)
X    chance = OBJ_BASE_MAX;
X  special = (chance/OBJ_DIV_SPECIAL);
X  cursed  = (chance/OBJ_DIV_CURSED);
X  t_ptr = &t_list[x];
X/*  I vehemently disagree with this!! */
X/*  t_ptr->level = level;  */
X  /* Depending on treasure type, it can have certain magical properties*/
X  switch (t_ptr->tval)
X    {
X    case 34: case 35: case 36:  /* Armor and shields*/
X      if (magik(chance))
X	{
X	  t_ptr->toac = m_bonus(1, 30, level);
X	  if (magik(special))
X	    switch(randint(9))
X	      {
X	      case 1:
X		t_ptr->flags |= 0x02380000;
X		(void) strcat(t_ptr->name, " (R)");
X		t_ptr->toac += 5;
X		t_ptr->cost += 2500;
X		break;
X	      case 2:    /* Resist Acid   */
X		t_ptr->flags |= 0x00100000;
X		(void) strcat(t_ptr->name, " (RA)");
X		t_ptr->cost += 1000;
X		break;
X	      case 3: case 4:    /* Resist Fire   */
X		t_ptr->flags |= 0x00080000;
X		(void) strcat(t_ptr->name, " (RF)");
X		t_ptr->cost += 600;
X		break;
X	      case 5: case 6:   /* Resist Cold   */
X		t_ptr->flags |= 0x00200000;
X		(void) strcat(t_ptr->name, " (RC)");
X		t_ptr->cost += 600;
X		break;
X	      case 7: case 8: case 9:  /* Resist Lightning*/
X		t_ptr->flags |= 0x02000000;
X		(void) strcat(t_ptr->name, " (RL)");
X		t_ptr->cost += 500;
X		break;
X	      }
X	}
X      else if (magik(cursed))
X	{
X	  t_ptr->toac = -m_bonus(1, 40, level);
X	  t_ptr->cost = 0;
X	  t_ptr->flags |= 0x80000000;
X	}
X      break;
X
X    case 21: case 22: case 23:  /* Weapons       */
X      if (magik(chance))
X	{
X	  t_ptr->tohit = m_bonus(0, 40, level);
X	  t_ptr->todam = m_bonus(0, 40, level);
X	  if (magik(special))
X	    switch(randint(16))
X	      {
X		case 1:   /* Holy Avenger  */
X		t_ptr->flags |= 0x01418001;
X		t_ptr->tohit += 5;
X		t_ptr->todam += 5;
X		t_ptr->toac  = randint(4);
X		/* the value in p1 is used for strength increase */
X		t_ptr->p1    = randint(4);
X		(void) strcat(t_ptr->name, " [%P4] (HA) (%P1 to STR)");
X		t_ptr->cost += t_ptr->p1*500;
X		t_ptr->cost += 10000;
X		break;
X	      case 2:   /* Defender      */
X		t_ptr->flags |= 0x07B80900;
X		t_ptr->tohit += 3;
X		t_ptr->todam += 3;
X		t_ptr->toac  = 5 + randint(5);
X		(void) strcat(t_ptr->name, " [%P4] (DF)");
X		/* note that the value in p1 is unused */
X		t_ptr->p1    = randint(3);
X		t_ptr->cost += t_ptr->p1*500;
X		t_ptr->cost += 7500;
X		break;
X	      case 3: case 4:    /* Slay Monster  */
X		t_ptr->flags |= 0x01004000;
X		t_ptr->tohit += 3;
X		t_ptr->todam += 3;
X		(void) strcat(t_ptr->name, " (SM)");
X		t_ptr->cost += 5000;
X		break;
X	      case 5: case 6:   /* Slay Dragon   */
X		t_ptr->flags |= 0x00002000;
X		t_ptr->tohit += 3;
X		t_ptr->todam += 3;
X		(void) strcat(t_ptr->name, " (SD)");
X		t_ptr->cost += 4000;
X		break;
X	      case 7: case 8:     /* Slay Evil     */
X		t_ptr->flags |= 0x00008000;
X		t_ptr->tohit += 3;
X		t_ptr->todam += 3;
X		(void) strcat(t_ptr->name, " (SE)");
X		t_ptr->cost += 4000;
X		break;
X	      case 9: case 10:   /* Slay Undead   */
X		t_ptr->flags |= 0x00010000;
X		t_ptr->tohit += 2;
X		t_ptr->todam += 2;
X		(void) strcat(t_ptr->name, " (SU)");
X		t_ptr->cost += 3000;
X		break;
X	      case 11: case 12: case 13:   /* Flame Tongue  */
X		t_ptr->flags |= 0x00040000;
X		t_ptr->tohit++;
X		t_ptr->todam += 3;
X		(void) strcat(t_ptr->name, " (FT)");
X		t_ptr->cost += 2000;
X		break;
X	      case 14: case 15: case 16:   /* Frost Brand   */
X		t_ptr->flags |= 0x00020000;
X		t_ptr->tohit++;
X		t_ptr->todam++;
X		(void) strcat(t_ptr->name, " (FB)");
X		t_ptr->cost += 1200;
X		break;
X	      }
X	}
X      else if (magik(cursed))
X	{
X	  t_ptr->tohit = -m_bonus(1, 55, level);
X	  t_ptr->todam = -m_bonus(1, 55, level);
X	  t_ptr->flags |= 0x80000000;
X	  t_ptr->cost = 0;
X	}
X      break;
X
X    case 20:  /* Bows, crossbows, and slings   */
X      if (magik(chance))
X	t_ptr->tohit = m_bonus(1, 30, level);
X      else if (magik(cursed))
X	{
X	  t_ptr->tohit = -m_bonus(1, 50, level);
X	  t_ptr->flags |= 0x80000000;
X	  t_ptr->cost = 0;
X	}
X      break;
X
X    case 25:  /* Digging tools         */
X      if (magik(chance))
X	switch(randint(3))
X	  {
X	  case 1: case 2:
X	    t_ptr->p1 = m_bonus(2, 25, level);
X	    t_ptr->cost += t_ptr->p1*100;
X	    break;
X	  case 3:
X	    t_ptr->p1 = -m_bonus(1, 30, level);
X	    t_ptr->cost = 0;
X	    t_ptr->flags |= 0x80000000;
X	  }
X      break;
X
X    case 31:  /* Gloves and Gauntlets  */
X      if (magik(chance))
X	{
X	  t_ptr->toac = m_bonus(1, 20, level);
X	  if (magik(special))
X	    switch(randint(2))
X	      {
X	      case 1:
X		t_ptr->flags |= 0x00800000;
X		(void) strcat(t_ptr->name, " of Free Action");
X		t_ptr->cost += 1000;
X		break;
X	      case 2:
X		t_ptr->tohit = 1 + randint(3);
X		t_ptr->todam = 1 + randint(3);
X		(void) strcat(t_ptr->name, " of Slaying (%P2,%P3)");
X		t_ptr->cost += (t_ptr->tohit+t_ptr->todam)*250;
X		break;
X	      }
X	}
X      else if (magik(cursed))
X	{
X	  if (magik(special))
X	    switch(randint(2))
X	      {
X	      case 1:
X		t_ptr->flags |= 0x80000002;
X		(void) strcat(t_ptr->name, " of Clumsiness");
X		t_ptr->p1 = 1;
X		break;
X	      case 2:
X		t_ptr->flags |= 0x80000001;
X		(void) strcat(t_ptr->name, " of Weakness");
X		t_ptr->p1 = 1;
X		break;
X	      }
X	  t_ptr->toac = -m_bonus(1, 40, level);
X	  t_ptr->p1   = -m_bonus(1, 10, level);
X	  t_ptr->flags |= 0x80000000;
X	  t_ptr->cost = 0;
X	}
X      break;
X
X    case 30:  /* Boots */
X      if (magik(chance))
X	{
X	  t_ptr->toac = m_bonus(1, 20, level);
X	  if (magik(special))
X	    switch(randint(12))
X	      {
X	      case 1:
X		t_ptr->flags |= 0x00001000;
X		(void) strcat(t_ptr->name, " of Speed");
X		t_ptr->p1 = 1;
X		t_ptr->cost += 5000;
X		break;
X	      case 2: case 3: case 4: case 5:
X		t_ptr->flags |= 0x00000100;
X		t_ptr->p1 = randint(3);
X		(void) strcat(t_ptr->name, " of Stealth (%P1)");
X		t_ptr->cost += 500;
X		break;
X	      default:
X		t_ptr->flags |= 0x04000000;
X		(void) strcat(t_ptr->name, " of Slow descent");
X		t_ptr->cost += 250;
X		break;
X	      }
X	}
X      else if (magik(cursed))
X	{
X	switch(randint(3))
X	  {
X	    case 1:
X	    t_ptr->flags |= 0x80001000;
X	    (void) strcat(t_ptr->name, " of Slowness");
X	    t_ptr->p1 = -1;
X	    break;
X	  case 2:
X	    t_ptr->flags |= 0x80000200;
X	    (void) strcat(t_ptr->name, " of Noise");
X	    break;
X	  case 3:
X	    t_ptr->flags |= 0x80000000;
X	    (void) strcat(t_ptr->name, " of Great Mass");
X	    t_ptr->weight = t_ptr->weight * 5;
X	    break;
X	  }
X	t_ptr->cost = 0;
X	t_ptr->ac = -m_bonus(2, 45, level);
X      }
X      break;
X
X    case 33:  /* Helms */
X      if (magik(chance))
X	{
X	  t_ptr->toac = m_bonus(1, 20, level);
X	  if (magik(special))
X	    switch(t_ptr->subval)
X	      {
X	      case 1: case 2: case 3: case 4: case 5:
X		switch(randint(3))
X		  {
X		  case 1:
X		    t_ptr->p1 = randint(2);
X		    t_ptr->flags |= 0x00000008;
X		    (void) strcat(t_ptr->name, " of Intelligence (%P1)");
X		    t_ptr->cost += t_ptr->p1*500;
X		    break;
X		  case 2:
X		    t_ptr->p1 = randint(2);
X		    t_ptr->flags |= 0x00000010;
X		      (void) strcat(t_ptr->name, " of Wisdom (%P1)");
X		    t_ptr->cost += t_ptr->p1*500;
X		    break;
X		  case 3:
X		    t_ptr->p1 = 1 + randint(4);
X		    t_ptr->flags |= 0x40000000;
X		    (void) strcat(t_ptr->name, " of Infra-Vision (%P1)");
X		    t_ptr->cost += t_ptr->p1*250;
X		    break;
X		  }
X		break;
X	      case 6: case 7: case 8:
X		switch(randint(6))
X		  {
X		  case 1:
X		    t_ptr->p1 = randint(3);
X		    t_ptr->flags |= 0x00800007;
X		    (void) strcat(t_ptr->name, " of Might (%P1)");
X		    t_ptr->cost += 1000 + t_ptr->p1*500;
X		    break;
X		  case 2:
X		    t_ptr->p1 = randint(3);
X		    t_ptr->flags |= 0x00000030;
X		    (void) strcat(t_ptr->name, " of Lordliness (%P1)");
X		    t_ptr->cost += 1000 + t_ptr->p1*500;
X		    break;
X		  case 3:
X		    t_ptr->p1 = randint(3);
X		    t_ptr->flags |= 0x01380008;
X		    (void) strcat(t_ptr->name, " of the Magi (%P1)");
X		    t_ptr->cost += 3000 + t_ptr->p1*500;
X		    break;
X		  case 4:
X		    t_ptr->p1 = randint(3);
X		    t_ptr->flags |= 0x00000020;
X		    (void) strcat(t_ptr->name, " of Beauty (%P1)");
X		    t_ptr->cost += 750;
X		    break;
X		  case 5:
X		    t_ptr->p1 = 1 + randint(4);
X		    t_ptr->flags |= 0x01000040;
X		    (void) strcat(t_ptr->name, " of Seeing (%P1)");
X		    t_ptr->cost += 1000 + t_ptr->p1*100;
X		    break;
X		  case 6:
X		    t_ptr->flags |= 0x00000800;
X		    (void) strcat(t_ptr->name, " of Regeneration");
X		    t_ptr->cost += 1500;
X		    break;
X		  }
X		break;
X	      }
X	  else if (magik(cursed))
X	    {
X	      t_ptr->toac = -m_bonus(1, 45, level);
X	      t_ptr->flags |= 0x80000000;
X	      t_ptr->cost = 0;
X	      if (magik(special))
X	      switch(randint(7))
X		{
X		case 1:
X		  t_ptr->p1 = -1;
X		  t_ptr->flags |= 0x00000008;
X		  (void) strcat(t_ptr->name, " of Stupidity");
X		  break;
X		case 2:
X		  t_ptr->p1 = -1;
X		  t_ptr->flags |= 0x00000010;
X		  (void) strcat(t_ptr->name, " of Dullness");
X		  break;
X		case 3:
X		  t_ptr->flags |= 0x08000000;
X		  (void) strcat(t_ptr->name, " of Blindness");
X		  break;
X		case 4:
X		  t_ptr->flags |= 0x10000000;
X		  (void) strcat(t_ptr->name, " of Timidness");
X		  break;
X		case 5:
X		  t_ptr->p1 = -1;
X		  t_ptr->flags |= 0x00000001;
X		  (void) strcat(t_ptr->name, " of Weakness");
X		  break;
X		case 6:
X		  t_ptr->flags |= 0x00000400;
X		  (void) strcat(t_ptr->name, " of Teleportation");
X		  break;
X		case 7:
X		  t_ptr->p1 = -1;
X		  t_ptr->flags |= 0x00000020;
X		  (void) strcat(t_ptr->name, " of Ugliness");
X		  break;
X		}
X	      t_ptr->p1 = t_ptr->p1 * randint (5);
X	    }
X	}
X      break;
X
X    case 45: /* Rings         */
X      switch(t_ptr->subval)
X	{
X	case 1: case 2: case 3: case 4: case 5: case 6:
X	  if (magik(cursed))
X	    {
X	      t_ptr->p1 = -m_bonus(1, 20, level);
X	      t_ptr->flags |= 0x80000000;
X	      t_ptr->cost = -t_ptr->cost;
X	    }
X	  else
X	    {
X	      t_ptr->p1 = m_bonus(1, 10, level);
X	      t_ptr->cost += t_ptr->p1*100;
X	    }
X	  break;
X	case 7:
X	  if (magik(cursed))
X	    {
X	      t_ptr->p1 = -randint(3);
X	      t_ptr->flags |= 0x80000000;
X	      t_ptr->cost = -t_ptr->cost;
X	    }
X	  else
X	    t_ptr->p1 = 1;
X	  break;
X	case 8:
X	  t_ptr->p1 = 5*m_bonus(1, 20, level);
X	  t_ptr->cost += t_ptr->p1*100;
X	  break;
X	case 22:     /* Increase damage       */
X	  t_ptr->todam = m_bonus(1, 20, level);
X	  t_ptr->cost += t_ptr->todam*100;
X	  if (magik(cursed))
X	    {
X	      t_ptr->todam = -t_ptr->todam;
X	      t_ptr->flags |= 0x80000000;
X	      t_ptr->cost = -t_ptr->cost;
X	    }
X	  break;
X	case 23:     /* Increase To-Hit       */
X	  t_ptr->tohit = m_bonus(1, 20, level);
X	  t_ptr->cost += t_ptr->tohit*100;
X	  if (magik(cursed))
X	    {
X	      t_ptr->tohit = -t_ptr->tohit;
X	      t_ptr->flags |= 0x80000000;
X	      t_ptr->cost = -t_ptr->cost;
X	    }
X	  break;
X	case 24:     /* Protection            */
X	  t_ptr->toac = m_bonus(1, 20, level);
X	  t_ptr->cost += t_ptr->toac*100;
X	  if (magik(cursed))
X	    {
X	      t_ptr->toac = -t_ptr->toac;
X	      t_ptr->flags |= 0x80000000;
X	      t_ptr->cost = -t_ptr->cost;
X	    }
X	  break;
X	case 33:     /* Slaying       */
X	  t_ptr->todam = m_bonus(1, 25, level);
X	  t_ptr->tohit = m_bonus(1, 25, level);
X	  t_ptr->cost += (t_ptr->tohit+t_ptr->todam)*100;
X	  if (magik(cursed))
X	    {
X	      t_ptr->tohit = -t_ptr->tohit;
X	      t_ptr->todam = -t_ptr->todam;
X	      t_ptr->flags |= 0x80000000;
X	      t_ptr->cost = -t_ptr->cost;
X	    }
X	  break;
X	default:
X	  break;
X	}
X      break;
X
X    case 40: /* Amulets       */
X      switch(t_ptr->subval)
X	{
X	case 1: case 2: case 3: case 4: case 5: case 6:
X	  if (magik(cursed))
X	    {
X	      t_ptr->p1 = -m_bonus(1, 20, level);
X	      t_ptr->flags |= 0x80000000;
X	      t_ptr->cost = -t_ptr->cost;
X	    }
X	  else
X	    {
X	      t_ptr->p1 = m_bonus(1, 10, level);
X	      t_ptr->cost += t_ptr->p1*100;
X	    }
X	  break;
X	case 7:
X	  t_ptr->p1 = 5*m_bonus(1, 25, level);
X	  if (magik(cursed))
X	    {
X	      t_ptr->p1 = -t_ptr->p1;
X	      t_ptr->cost = -t_ptr->cost;
X	      t_ptr->flags |= 0x80000000;
X	    }
X	  else
X	    t_ptr->cost += 20*t_ptr->p1;
X	  break;
X	default:
X	  break;
X	}
X      break;
X
X      /* Subval should be even for store, odd for dungeon*/
X      /* Dungeon found ones will be partially charged    */
X    case 15: /* Lamps and torches*/
X      if ((t_ptr->subval % 2) == 1)
X	t_ptr->p1 = randint(t_ptr->p1);
X      break;
X
X    case 65: /* Wands         */
X      switch(t_ptr->subval)
X	{
X	case 1:   t_ptr->p1 = randint(10) + 	 6; break;
X	case 2:   t_ptr->p1 = randint(8)  + 	 6; break;
X	case 3:   t_ptr->p1 = randint(5)  + 	 6; break;
X	case 4:   t_ptr->p1 = randint(8)  + 	 6; break;
X	case 5:   t_ptr->p1 = randint(4)  + 	 3; break;
X	case 6:   t_ptr->p1 = randint(8)  + 	 6; break;
X	case 7:   t_ptr->p1 = randint(20) + 	 12; break;
X	case 8:   t_ptr->p1 = randint(20) + 	 12; break;
X	case 9:   t_ptr->p1 = randint(10) + 	 6; break;
X	case 10:   t_ptr->p1 = randint(12) + 	 6; break;
X	case 11:   t_ptr->p1 = randint(10) + 	 12; break;
X	case 12:   t_ptr->p1 = randint(3)  + 	 3; break;
X	case 13:   t_ptr->p1 = randint(8)  + 	 6; break;
X	case 14:   t_ptr->p1 = randint(10) + 	 6; break;
X	case 15:   t_ptr->p1 = randint(5)  + 	 3; break;
X	case 16:   t_ptr->p1 = randint(5)  + 	 3; break;
X	case 17:   t_ptr->p1 = randint(5)  + 	 6; break;
X	case 18:   t_ptr->p1 = randint(5)  + 	 4; break;
X	case 19:   t_ptr->p1 = randint(8)  + 	 4; break;
X	case 20:   t_ptr->p1 = randint(6)  + 	 2; break;
X	case 21:   t_ptr->p1 = randint(4)  + 	 2; break;
X	case 22:   t_ptr->p1 = randint(8)  + 	 6; break;
X	case 23:   t_ptr->p1 = randint(5)  + 	 2; break;
X	case 24:   t_ptr->p1 = randint(12) + 12; break;
X	default:
X	  break;
X	}
X      break;
X
X    case 55: /* Staffs        */
X      switch(t_ptr->subval)
X	{
X	case 1:   t_ptr->p1 = randint(20) + 	 12; break;
X	case 2:   t_ptr->p1 = randint(8)  + 	 6; break;
X	case 3:   t_ptr->p1 = randint(5)  + 	 6; break;
X	case 4:   t_ptr->p1 = randint(20) + 	 12; break;
X	case 5:   t_ptr->p1 = randint(15) + 	 6; break;
X	case 6:   t_ptr->p1 = randint(4)  + 	 5; break;
X	case 7:   t_ptr->p1 = randint(5)  + 	 3; break;
X	case 8:   t_ptr->p1 = randint(3)  + 	 1; break;
X	case 9:   t_ptr->p1 = randint(3)  + 	 1; break;
X	case 10:   t_ptr->p1 = randint(3)  + 	 1; break;
X	case 11:   t_ptr->p1 = randint(5)  + 	 6; break;
X	case 12:   t_ptr->p1 = randint(10) + 	 12; break;
X	case 13:   t_ptr->p1 = randint(5)  + 	 6; break;
X	case 14:   t_ptr->p1 = randint(5)  + 	 6; break;
X	case 15:   t_ptr->p1 = randint(5)  + 	 6; break;
X	case 16:   t_ptr->p1 = randint(10) + 	 12; break;
X	case 17:   t_ptr->p1 = randint(3)  + 	 4; break;
X	case 18:   t_ptr->p1 = randint(5)  + 	 6; break;
X	case 19:   t_ptr->p1 = randint(5)  + 	 6; break;
X	case 20:   t_ptr->p1 = randint(3)  + 	 4; break;
X	case 21:   t_ptr->p1 = randint(10) + 	 12; break;
X	case 22:   t_ptr->p1 = randint(3)  + 	 4; break;
X	case 23:   t_ptr->p1 = randint(3)  + 	 4; break;
X	case 24:   t_ptr->p1 = randint(3)  + 	 1; break;
X	case 25:   t_ptr->p1 = randint(10) + 6; break;
X	default:
X	  break;
X	}
X      break;
X
X    case 32: /* Cloaks        */
X      if (magik(chance))
X	{
X	  if (magik(special))
X	    switch(randint(2))
X	      {
X	      case 1:
X		(void) strcat(t_ptr->name, " of Protection");
X		t_ptr->toac = m_bonus(2, 40, level);
X		t_ptr->cost += 250;
X		break;
X	      case 2:
X		t_ptr->toac = m_bonus(1, 20, level);
X		t_ptr->p1 = randint(3);
X		t_ptr->flags |= 0x00000100;
X		(void) strcat(t_ptr->name, " of Stealth (%P1)");
X		t_ptr->cost += 500;
X		break;
X	      }
X	  else
X	    t_ptr->toac = m_bonus(1, 20, level);
X	}
X      else if (magik(cursed))
X	switch(randint(3))
X	  {
X	  case 1:
X	    t_ptr->flags |= 0x80000200;
X	    (void) strcat(t_ptr->name, " of Irritation");
X	    t_ptr->ac   =  0;
X	    t_ptr->toac  = -m_bonus(1, 10, level);
X	    t_ptr->tohit = -m_bonus(1, 10, level);
X	    t_ptr->todam = -m_bonus(1, 10, level);
X	    t_ptr->cost =  0;
X	    break;
X	  case 2:
X	    t_ptr->flags |= 0x80000000;
X	    (void) strcat(t_ptr->name, " of Vulnerability");
X	    t_ptr->ac   = 0;
X	    t_ptr->toac = -m_bonus(10, 100, level+50);
X	    t_ptr->cost = 0;
X	    break;
X	  case 3:
X	    t_ptr->flags |= 0x80000000;
X	    (void) strcat(t_ptr->name, " of Enveloping");
X	    t_ptr->toac  = -m_bonus(1, 10, level);
X	    t_ptr->tohit = -m_bonus(2, 40, level+10);
X	    t_ptr->todam = -m_bonus(2, 40, level+10);
X	    t_ptr->cost = 0;
X	    break;
X	  }
X      break;
X
X    case 2: /* Chests        */
X      switch(randint(level+4))
X	{
X	case 1:
X	  t_ptr->flags = 0;
X	  (void) strcat(t_ptr->name, "^ (Empty)");
X	  break;
X	case 2:
X	  t_ptr->flags |= 0x00000001;
X	  (void) strcat(t_ptr->name, "^ (Locked)");
X	  break;
X	case 3: case 4:
X	  t_ptr->flags |= 0x00000011;
X	  (void) strcat(t_ptr->name, "^ (Poison Needle)");
X	  break;
X	case 5: case 6:
X	  t_ptr->flags |= 0x00000021;
X	  (void) strcat(t_ptr->name, "^ (Poison Needle)");
X	  break;
X	case 7: case 8: case 9:
X	  t_ptr->flags |= 0x00000041;
X	  (void) strcat(t_ptr->name, "^ (Gas Trap)");
X	  break;
X	case 10: case 11:
X	  t_ptr->flags |= 0x00000081;
X	  (void) strcat(t_ptr->name, "^ (Explosion Device)");
X	  break;
X	case 12: case 13: case 14:
X	  t_ptr->flags |= 0x00000101;
X	  (void) strcat(t_ptr->name, "^ (Summoning Runes)");
X	  break;
X	case 15: case 16: case 17:
X	  t_ptr->flags |= 0x00000071;
X	  (void) strcat(t_ptr->name, "^ (Multiple Traps)");
X	  break;
X	default:
X	  t_ptr->flags |= 0x00000181;
X	  (void) strcat(t_ptr->name, "^ (Multiple Traps)");
X	  break;
X	}
X      break;
X
X    case 10: case 11: case 12: case 13:  /* Arrows, bolts, ammo, and spikes */
X      if ((t_ptr->tval == 11) || (t_ptr->tval == 12))
X	if (magik(chance))
X	  {
X	    t_ptr->tohit = m_bonus(1, 35, level);
X	    t_ptr->todam = m_bonus(1, 35, level);
X	    if (magik(special))
X	      switch(t_ptr->tval)  /*SWITCH 1*/
X		{
X		case 11: case 12:
X		  switch(randint(10))   /*SWITCH 2*/
X		    {
X		    case 1: case 2: case 3:
X		      (void) strcat(t_ptr->name, " of Slaying");
X		      t_ptr->tohit += 5;
X		      t_ptr->todam += 5;
X		      t_ptr->cost += 20;
X		      break;
X		    case 4: case 5:
X		      t_ptr->flags |= 0x00040000;
X		      t_ptr->tohit += 2;
X		      t_ptr->todam += 4;
X		      (void) strcat(t_ptr->name, " of Fire");
X		      t_ptr->cost += 25;
X		      break;
X		    case 6: case 7:
X		      t_ptr->flags |= 0x00008000;
X		      t_ptr->tohit += 3;
X		      t_ptr->todam += 3;
X		      (void) strcat(t_ptr->name, " of Slay Evil");
X		      t_ptr->cost += 25;
X		      break;
X		    case 8: case 9:
X		      t_ptr->flags |= 0x01004000;
X		      t_ptr->tohit += 2;
X		      t_ptr->todam += 2;
X		      (void) strcat(t_ptr->name, " of Slay Monster");
X		      t_ptr->cost += 30;
X		      break;
X		    case 10:
X		      t_ptr->flags |= 0x00002000;
X		      t_ptr->tohit += 10;
X		      t_ptr->todam += 10;
X		      (void) strcat(t_ptr->name, " of Dragon Slaying");
X		      t_ptr->cost += 35;
X		      break;
X		    } /*SWITCH 2*/
X		default:
X		  break;
X		}  /*SWITCH 1*/
X	  }
X	else if (magik(cursed))
X	  {
X	    t_ptr->tohit = -m_bonus(5, 55, level);
X	    t_ptr->todam = -m_bonus(5, 55, level);
X	    t_ptr->flags |= 0x80000000;
X	    t_ptr->cost = 0;
X	  }
X
X      t_ptr->number = 0;
X      for (i = 0; i < 7; i++)
X	t_ptr->number += randint(6);
X      missile_ctr++;
X      if (missile_ctr > 65000)
X	missile_ctr = 1;
X      t_ptr->subval = missile_ctr + 512;
X      break;
X
X    default:
X      break;
X    }
X}
X
X
END_OF_FILE
if test 41617 -ne `wc -c <'misc1.c'`; then
    echo shar: \"'misc1.c'\" unpacked with wrong size!
fi
# end of 'misc1.c'
fi
echo shar: End of archive 8 \(of 18\).
cp /dev/null ark8isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 18 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