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

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

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




#! /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 3 (of 16)."
# Contents:  makelog spells.c
# Wrapped by billr@tekred on Wed Nov  4 09:59:39 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f makelog -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"makelog\"
else
echo shar: Extracting \"makelog\" \(1686 characters\)
sed "s/^X//" >makelog <<'END_OF_makelog'
Xcc -O -DKEY_BINDINGS=ORIGINAL -c main.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c misc1.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c misc2.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c store1.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c files.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c io.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c create.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c desc.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c generate.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c sets.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c dungeon.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c creature.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c death.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c eat.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c help.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c magic.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c potions.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c prayer.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c save.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c staffs.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c wands.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c scrolls.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c spells.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c wizard.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c store2.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c signals.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c moria1.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c moria2.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c monsters.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c treasure1.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c treasure2.c
Xcc -O -DKEY_BINDINGS=ORIGINAL -c variables.c
Xcc -o moria -O -DKEY_BINDINGS=ORIGINAL main.o misc1.o misc2.o store1.o files.o io.o create.o desc.o generate.o sets.o dungeon.o creature.o death.o eat.o help.o magic.o potions.o prayer.o save.o staffs.o wands.o scrolls.o spells.o wizard.o store2.o signals.o moria1.o moria2.o monsters.o treasure1.o treasure2.o variables.o -lm -lcurses -ltermcap
END_OF_makelog
if test 1686 -ne `wc -c <makelog`; then
    echo shar: \"makelog\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f spells.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"spells.c\"
else
echo shar: Extracting \"spells.c\" \(50992 characters\)
sed "s/^X//" >spells.c <<'END_OF_spells.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
Xextern char cur_char2();
X
X/* Following are spell procedure/functions			-RAK-	*/
X/* These routines are commonly used in the scroll, potion, wands, and    */
X/* staves routines, and are occasionally called from other areas.         */
X/* Now included are creature spells also...                      -RAK    */
X
X/* Sleep creatures adjacent to player			-RAK-	*/
Xint sleep_monsters1(y, x)
Xint y, x;
X{
X  int i, j;
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  int sleep;
X  vtype out_val;
X
X  sleep = FALSE;
X  for (i = y-1; i <= y+1; i++)
X    for (j = x-1; j <= x+1; j++)
X      {
X	c_ptr = &cave[i][j];
X	if (c_ptr->cptr > 1) 
X	  {
X	    m_ptr = &m_list[c_ptr->cptr];
X	    r_ptr = &c_list[m_ptr->mptr];
X
X	    sleep = TRUE;
X	    if ((randint(MAX_MONS_LEVEL) < r_ptr->level) ||
X		(0x1000 & r_ptr->cdefense))
X	      {
X		(void) sprintf(out_val, "The %s is unaffected.", r_ptr->name);
X		msg_print(out_val);
X	      }
X	    else
X	      {
X		(void) sprintf(out_val, "The %s falls asleep.", r_ptr->name);
X		msg_print(out_val);
X		m_ptr->csleep = 500;
X	      }
X	  }
X      }
X  return(sleep);
X}
X
X/* Detect any monsters on the current panel		-RAK-	*/
Xint detect_treasure()
X{
X  int i, j;
X  int detect;
X  cave_type *c_ptr;
X
X  detect = FALSE;
X  for (i = panel_row_min; i <= panel_row_max; i++)
X    for (j = panel_col_min; j <= panel_col_max; j++)
X      {
X	c_ptr = &cave[i][j];
X	if (c_ptr->tptr != 0) 
X	  if (t_list[c_ptr->tptr].tval == 100) 
X	    if (!test_light(i, j)) 
X	      {
X		lite_spot(i, j);
X		c_ptr->tl = TRUE;
X		detect = TRUE;
X	      }
X      }
X  return(detect);
X}
X
X
X/* Detect all objects on the current panel		-RAK-	*/
Xint detect_object()
X{
X  int i, j;
X  int detect;
X  cave_type *c_ptr;
X
X  detect = FALSE;
X  for (i = panel_row_min; i <= panel_row_max; i++)
X    for (j = panel_col_min; j <= panel_col_max; j++)
X      {
X	c_ptr = &cave[i][j];
X	if (c_ptr->tptr != 0) 
X	  if (t_list[c_ptr->tptr].tval < 100) 
X	    if (!test_light(i, j)) 
X	      {
X		lite_spot(i, j);
X		c_ptr->tl = TRUE;
X		detect = TRUE;
X	      }
X      }
X  return(detect);
X}
X
X
X/* Locates and displays traps on current panel		-RAK-	*/
Xint detect_trap()
X{
X  int i, j;
X  int detect;
X  cave_type *c_ptr;
X  treasure_type *t_ptr;
X
X  detect = FALSE;
X  for (i = panel_row_min; i <= panel_row_max; i++)
X    for (j = panel_col_min; j <= panel_col_max; j++)
X      {
X	c_ptr = &cave[i][j];
X	if (c_ptr->tptr != 0) 
X	  if (t_list[c_ptr->tptr].tval == 101) 
X	    {
X	      change_trap(i, j);
X	      c_ptr->fm = TRUE;
X	      detect = TRUE;
X	    }
X	  else if (t_list[c_ptr->tptr].tval == 2) 
X	    {
X	      t_ptr = &t_list[c_ptr->tptr];
X	      known2(t_ptr->name);
X	    }
X      }
X  return(detect);
X}
X
X
X/* Locates and displays all secret doors on current panel -RAK-	*/
Xint detect_sdoor()
X{
X  int i, j;
X  int detect;
X  cave_type *c_ptr;
X  
X  detect = FALSE;
X  for (i = panel_row_min; i <= panel_row_max; i++)
X    for (j = panel_col_min; j <= panel_col_max; j++)
X      {
X	c_ptr = &cave[i][j];
X	if (c_ptr->tptr != 0) 
X	  /* Secret doors  */
X	  if (t_list[c_ptr->tptr].tval == 109) 
X	    {
X	      c_ptr->fval = corr_floor3.ftval;
X	      change_trap(i, j);
X	      c_ptr->fm = TRUE;
X	      detect = TRUE;
X	    }
X	/* Staircases    */
X	  else if ((t_list[c_ptr->tptr].tval == 107) || 
X		   (t_list[c_ptr->tptr].tval == 108)) 
X	    if (!c_ptr->fm) 
X	      {
X		c_ptr->fm = TRUE;
X		lite_spot(i, j);
X		detect = TRUE;
X	      }
X      }
X  return(detect);
X}
X
X
X/* Locates and displays all invisible creatures on current panel -RAK-*/
Xint detect_invisible()
X{
X  int i;
X  int flag;
X  char tmp_str[2];
X  monster_type *m_ptr;
X
X  flag = FALSE;
X  i = muptr;
X  while (i > 0)
X    {
X      m_ptr = &m_list[i];
X      if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx)) 
X	if (0x10000 & c_list[m_ptr->mptr].cmove)
X	  {
X	    m_ptr->ml = TRUE;
X	    tmp_str[0] = c_list[m_ptr->mptr].cchar;
X	    tmp_str[1] = '\0';
X	    print(tmp_str, (int)m_ptr->fy, (int)m_ptr->fx);
X	    flag = TRUE;
X	  }
X      i = m_list[i].nptr;
X    }
X  if (flag) 
X    {
X      msg_print("You sense the presence of invisible creatures!");
X      msg_print(" ");
X      msg_flag = FALSE;
X    }
X  return(flag);
X}
X
X
X/* Light an area: 1.  If corridor  light immediate area -RAK-*/
X/*                2.  If room  light entire room.            */
Xint light_area(y, x)
Xint y, x;
X{
X  int i, j;
X  int light;
X
X  msg_print("You are surrounded by a white light.");
X  light = TRUE;
X  if (((cave[y][x].fval == 1) || (cave[y][x].fval == 2)) && (dun_level > 0)) 
X    light_room(y, x);
X  else
X    for (i = y-1; i <= y+1; i++)
X      for (j = x-1; j <=  x+1; j++)
X	if (in_bounds(i, j)) 
X	  {
X	    if (!test_light(i, j)) 
X	      lite_spot(i, j);
X	    cave[i][j].pl = TRUE;
X	  }
X  return(light);
X}
X
X
X/* Darken an area, opposite of light area		-RAK-	*/
Xint unlight_area(y, x)
Xint y, x;
X{
X  int i, j, k, tmp1, tmp2;
X  int start_row, start_col;
X  int end_row, end_col;
X  int flag;
X  int unlight;
X  cave_type *c_ptr;
X  vtype out_val;
X
X  flag = FALSE;
X  if (((cave[y][x].fval == 1) || (cave[y][x].fval == 2)) && (dun_level > 0)) 
X    {
X      tmp1 = (SCREEN_HEIGHT/2);
X      tmp2 = (SCREEN_WIDTH /2);
X      start_row = (y/tmp1)*tmp1 + 1;
X      start_col = (x/tmp2)*tmp2 + 1;
X      end_row = start_row + tmp1 - 1;
X      end_col = start_col + tmp2 - 1;
X      for (i = start_row; i <= end_row; i++)
X	{
X	  out_val[0] = '\0';
X	  k = 0;
X	  for (j = start_col; j <= end_col; j++)
X	    {
X	      c_ptr = &cave[i][j];
X	      if ((c_ptr->fval == 1) || (c_ptr->fval == 2))
X		{
X		  c_ptr->pl = FALSE;
X		  c_ptr->fval = 1;
X		  if (!test_light(i, j)) 
X		    {
X		      if (k == 0) 
X			k = j;
X		      (void) strcat(out_val, " ");
X		    }
X		  else if (k > 0) 
X		    {
X		      flag = TRUE;
X		      print(out_val, i, k);
X		      out_val[0] = '\0';
X		      k = 0;
X		    }
X		}
X	      else if (k > 0) 
X		{
X		  flag = TRUE;
X		  print(out_val, i, k);
X		  out_val[0] = '\0';
X		  k = 0;
X		}
X	      if (k > 0) 
X		{
X		  flag = TRUE;
X		  print(out_val, i, k);
X		}
X	    }
X	}
X    }
X  else
X    for (i = y-1; i <= y+1; i++)
X      for (j = x-1; j <= x+1; j++)
X	if (in_bounds(i, j)) 
X	  {
X	    c_ptr = &cave[i][j];
X	    if ((c_ptr->fval == 4) || (c_ptr->fval == 5) || (c_ptr->fval ==6)) 
X	      if (c_ptr->pl) 
X		{
X		  c_ptr->pl = FALSE;
X		  flag = TRUE;
X		}
X	    if (flag) 
X	      {
X		msg_print("Darkness surrounds you...");
X		unlight = TRUE;
X	      }
X	  }
X	else
X	  unlight = FALSE;
X  return(unlight);
X}
X
X
X/* Map the current area plus some			-RAK-	*/
Xint map_area()
X{
X  int i, j, k, l, m, n, i7, i8;
X  int map;
X  cave_type *c_ptr;
X
X  map = TRUE;
X  i = panel_row_min - randint(10);
X  j = panel_row_max + randint(10);
X  k = panel_col_min - randint(20);
X  l = panel_col_max + randint(20);
X  for (m = i; m <= j; m++)
X    for (n = k; n <= l; n++)
X      if (in_bounds(m, n)) 
X	if (set_floor(cave[m][n].fval))
X	  for (i7 = m-1; i7 <= m+1; i7++)
X	    for (i8 = n-1; i8 <= n+1; i8++)
X	      {
X		c_ptr = &cave[i7][i8];
X		if (((c_ptr->fval >= 10) && (c_ptr->fval <= 12)) ||
X		    (c_ptr->fval == 15))
X		  c_ptr->pl = TRUE;
X		else if (c_ptr->tptr != 0) 
X		  if ((t_list[c_ptr->tptr].tval >= 102) && 
X		      (t_list[c_ptr->tptr].tval <= 110) && 
X		      (t_list[c_ptr->tptr].tval != 106))
X		    c_ptr->fm = TRUE;
X	      }
X  prt_map();
X  return(map);
X}
X
X
X/* Identify an object					-RAK-	*/
Xint ident_spell()
X{
X  int item_val;
X  vtype out_val, tmp_str;
X  int redraw;
X  int ident;
X  treasure_type *i_ptr;
X  
X  ident = FALSE;
X  redraw = FALSE;
X  if (get_item(&item_val, "Item you wish identified?",
X	       &redraw, 0, inven_ctr-1))
X    {
X      i_ptr = &inventory[item_val];
X      ident = TRUE;
X      identify(inventory[item_val]);
X      known2(i_ptr->name);
X      objdes(tmp_str, item_val, TRUE);
X      (void) sprintf(out_val, "%c%c %s", item_val+97, cur_char2(item_val),
X		     tmp_str);
X      msg_print(out_val);
X    }
X  if (redraw) 
X    {
X      msg_print(" ");
X      draw_cave();
X    }
X  return(ident);
X}
X
X
X/* Get all the monsters on the level pissed off...	-RAK-	*/
Xint aggravate_monster  (dis_affect)
Xint dis_affect;
X{
X  int i;
X  int aggravate;
X  monster_type *m_ptr;
X
X  aggravate = TRUE;
X  i = muptr;
X  while (i > 0)
X    {
X      m_ptr = &m_list[i];
X      m_ptr->csleep = 0;
X      if (m_ptr->cdis <= dis_affect) 
X	if (m_ptr->cspeed < 2) 
X	  m_ptr->cspeed++;
X      i = m_list[i].nptr;
X    }
X  return(aggravate);
X}
X
X
X/* Surround the fool with traps (chuckle)		-RAK-	*/
Xint trap_creation()
X{
X  int i, j;
X  int trap;
X  cave_type *c_ptr;
X
X  trap = TRUE;
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	if (set_floor(c_ptr->fval))
X	  {
X	    if (c_ptr->tptr != 0) 
X	      (void) delete_object(i, j);
X	    place_trap(i, j, 1, randint(MAX_TRAPA)-1);
X	  }
X      }
X  return(trap);
X}
X
X
X/* Surround the player with doors...			-RAK-	*/
Xint door_creation()
X{
X  int i, j, k;
X  int door;
X  cave_type *c_ptr;
X  
X  door = TRUE;
X  for (i = char_row-1; i <= char_row+1; i++)
X    for (j = char_col-1; j <=  char_col+1; j++)
X      if ((i != char_row) || (j != char_col)) 
X	{
X	  c_ptr = &cave[i][j];
X	  if (set_floor(c_ptr->fval))
X	    {
X	      popt(&k);
X	      if (c_ptr->tptr != 0) 
X		(void) delete_object(i, j);
X	      c_ptr->fopen = FALSE;
X	      c_ptr->tptr = k;
X	      t_list[k] = door_list[1];
X	      if (test_light(i, j)) 
X		lite_spot(i, j);
X	    }
X	}
X  return(door);
X}
X
X
X/* Destroys any adjacent door(s)/trap(s) 		-RAK-	*/
Xint td_destroy()
X{
X  int i, j;
X  int destroy;
X  cave_type *c_ptr;
X  
X  destroy = FALSE;
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	if (c_ptr->tptr != 0) 
X	  {
X	    if (((t_list[c_ptr->tptr].tval >= 101) &&
X		 (t_list[c_ptr->tptr].tval <= 105) &&
X		 (t_list[c_ptr->tptr].tval != 103)) ||
X		(t_list[c_ptr->tptr].tval == 109))
X	      {
X		if (delete_object(i, j)) 
X		  destroy = TRUE;
X	      }
X	    else if (t_list[c_ptr->tptr].tval == 2)
X	      /* destroy traps on chest and unlock */
X	      t_list[c_ptr->tptr].flags &= 0xFF000000;
X	  }
X      }
X  return(destroy);
X}
X
X
X/* Display all creatures on the current panel		-RAK-	*/
Xint detect_monsters()
X{
X  int i;
X  int flag;
X  int detect;
X  char tmp_str[2];
X  monster_type *m_ptr;
X
X  flag = FALSE;
X  i = muptr;
X  while (i > 0)
X    {
X      m_ptr = &m_list[i];
X      if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx)) 
X	if ((0x10000 & c_list[m_ptr->mptr].cmove) == 0) 
X	  {
X	    m_ptr->ml = TRUE;
X	    tmp_str[0] = c_list[m_ptr->mptr].cchar;
X	    tmp_str[1] = '\0';
X	    print(tmp_str, (int)m_ptr->fy, (int)m_ptr->fx);
X	    flag = TRUE;
X	  }
X      i = m_list[i].nptr;
X    }
X  if (flag) 
X    {
X      msg_print("You sense the presence of monsters!");
X      msg_print(" ");
X      msg_flag = FALSE;
X      detect = TRUE;
X    }
X  detect = flag;
X  return(detect);
X}
X
X
X/* Leave a line of light in given dir, blue light can sometimes	*/
X/* hurt creatures...                                     -RAK-   */
Xlight_line(dir, y, x)
Xint dir, y, x;
X{
X  int i;
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  vtype out_val;
X
X  while (cave[y][x].fopen)
X    {
X      c_ptr = &cave[y][x];
X      if (panel_contains(y, x)) 
X	{
X	  if ((!c_ptr->tl) && (!c_ptr->pl))
X	    if (c_ptr->fval == 2) 
X	      light_room(y, x);
X	    else
X	      lite_spot(y, x);
X	  if (c_ptr->cptr > 1) 
X	    {
X	      m_ptr = &m_list[c_ptr->cptr];
X	      r_ptr = &c_list[m_ptr->mptr];
X	      if (0x0100 & r_ptr->cdefense)
X		{
X		  (void) sprintf(out_val, "The %s wails out in pain!",
X				 r_ptr->name);
X		  msg_print(out_val);
X		  i = mon_take_hit((int)c_ptr->cptr, damroll("2d8"));
X		  if (i > 0) 
X		    {
X		      (void) sprintf(out_val, "The %s dies in a fit of agony.",
X			      r_ptr->name);
X		      msg_print(out_val);
X		    }
X		}
X	    }
X	  c_ptr->pl = TRUE;
X	}
X      (void) move(dir, &y, &x);
X    }
X}
X
X
X/* Light line in all directions				-RAK-	*/
Xint starlite(y, x)
Xint y, x;
X{
X  int i;
X
X  msg_print("The end of the staff bursts into a blue shimmering light.");
X  for (i = 1; i <= 9; i++)
X    if (i != 5) 
X      light_line(i, y, x);
X  return(TRUE);
X}
X
X
X/* Disarms all traps/chests in a given direction 	-RAK-	*/
Xint disarm_all(dir, y, x)
Xint dir, y, x;
X{
X  int i, oldy, oldx;
X  int disarm;
X  cave_type *c_ptr;
X  treasure_type *t_ptr;
X  char *string;
X  
X  disarm = FALSE;
X  do
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 == 101) || (t_ptr->tval == 102)) 
X	    {
X	      if (delete_object(y, x)) 
X		disarm = TRUE;
X	    }
X	  else if (t_ptr->tval == 105) 
X	    {
X	      t_ptr->p1 = 0;
X	    }
X	  else if (t_ptr->tval == 109) 
X	    {
X	      c_ptr->fval = corr_floor3.ftval;
X	      change_trap(y, x);
X	      c_ptr->fm = TRUE;
X	      disarm = TRUE;
X	    }
X	  else if (t_ptr->tval == 2) 
X	    if (t_ptr->flags != 0) 
X	      {
X		msg_print("Click!");
X		t_ptr->flags = 0;
X		disarm = TRUE;
X		string = index(t_ptr->name, '(');
X		if (string)
X		  i = strlen(t_ptr->name) - strlen(string);
X		else
X		  i = -1;
X		if (i >= 0) 
X		  t_ptr->name[i] = '\0';
X		(void) strcat(t_ptr->name, " (Unlocked)");
X		known2(t_ptr->name);
X	      }
X	}
X      oldy = y;
X      oldx = x;
X      (void) move(dir, &y, &x);
X    }
X  while (cave[oldy][oldx].fopen);
X  return(disarm);
X}
X
X
X/* Return flags for given type area affect		-RAK-	*/
Xget_flags(typ, weapon_type, harm_type, destroy)
Xint typ;
Xint *weapon_type, *harm_type;
Xint (**destroy)();
X{
X  int set_null(), set_fire_destroy(), set_frost_destroy();
X  int set_acid_destroy(), set_lightning_destroy();
X
X  switch(typ)
X    {
X    case 1:      /* Lightning     */
X      *weapon_type = 0x00080000;
X      *harm_type   = 0x0100;
X      *destroy     = set_lightning_destroy;
X      break;
X    case 2:      /* Poison Gas    */
X      *weapon_type = 0x00100000;
X      *harm_type   = 0x0040;
X      *destroy     = set_null;
X      break;
X    case 3:      /* Acid          */
X      *weapon_type = 0x00200000;
X      *harm_type   = 0x0080;
X      *destroy     = set_acid_destroy;
X      break;
X    case 4:      /* Frost         */
X      *weapon_type = 0x00400000;
X      *harm_type   = 0x0010;
X      *destroy     = set_frost_destroy;
X      break;
X    case 5:      /* Fire          */
X      *weapon_type = 0x00800000;
X      *harm_type   = 0x0020;
X      *destroy     = set_fire_destroy;
X      break;
X    case 6:      /* Holy Orb      */
X      *weapon_type = 0x00000000;
X      *harm_type   = 0x0004;
X      *destroy     = set_null;
X      break;
X    default:
X      *weapon_type = 0;
X      *harm_type   = 0;
X      *destroy     = set_null;
X    }
X}
X
X
X/* Shoot a bolt in a given direction			-RAK-	*/
Xint fire_bolt(typ, dir, y, x, dam, bolt_typ)
Xint typ, dir, y, x, dam;
Xctype bolt_typ;
X{
X  int i, oldy, oldx, dist;
X  int weapon_type, harm_type;
X  int flag;
X  int (*dummy)();
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  vtype out_val;
X  char tmp_str[2];
X
X  flag = FALSE;
X  get_flags(typ, &weapon_type, &harm_type, &dummy);
X  oldy = y;
X  oldx = x;
X  dist = 0;
X  do
X    {
X      (void) move(dir, &y, &x);
X      if (test_light(oldy, oldx)) 
X	lite_spot(oldy, oldx);
X      else
X	unlite_spot(oldy, oldx);
X      dist++;
X      if (dist > OBJ_BOLT_RANGE) 
X	flag = TRUE;
X      else
X	{
X	  c_ptr = &cave[y][x];
X	  if (c_ptr->fopen) 
X	    {
X	      if (c_ptr->cptr > 1) 
X		{
X		  flag = TRUE;
X		  m_ptr = &m_list[c_ptr->cptr];
X		  r_ptr = &c_list[m_ptr->mptr];
X		  (void) sprintf(out_val, "The %s strikes the %s.", bolt_typ,
X			  r_ptr->name);
X		  msg_print(out_val);
X		  if (harm_type & r_ptr->cdefense)
X		    dam = dam*2;
X		  else if (weapon_type & r_ptr->spells)
X		    dam = (dam/4.0);
X		  i = mon_take_hit((int)c_ptr->cptr, dam);
X		  if (i > 0) 
X		    {
X		      (void) sprintf(out_val, "The %s dies in a fit of agony.",
X			      c_list[i].name);
X		      msg_print(out_val);
X		    }
X		  else
X		    {
X		      if (panel_contains(y, x)) 
X			{
X			  tmp_str[0] = c_list[m_ptr->mptr].cchar;
X			  tmp_str[1] = '\0';
X			  print(tmp_str, y, x);
X			  m_list[c_ptr->cptr].ml = TRUE;
X			}
X		    }
X		}
X	      else if (panel_contains(y, x)) 
X		print("*", y, x);
X	    }
X	  else
X	    flag = TRUE;
X	}
X      oldy = y;
X      oldx = x;
X    }
X  while (!flag);
X}
X
X
X/* Shoot a ball in a given direction.  Note that balls have an	*/
X/* area affect....                                       -RAK-   */
Xint fire_ball(typ, dir, y, x, dam_hp, descrip)
Xint typ, dir, y, x, dam_hp;
Xctype descrip;
X{
X  int i, j, k;
X  int dam, max_dis, thit, tkill;
X  int oldy, oldx, dist;
X  int weapon_type, harm_type;
X  int flag;
X  int (*destroy)();
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  vtype out_val;
X  char tmp_str[2];
X
X  thit   = 0;
X  tkill  = 0;
X  max_dis = 2;
X  get_flags(typ, &weapon_type, &harm_type, &destroy);
X  flag = FALSE;
X  oldy = y;
X  oldx = x;
X  dist = 0;
X  do
X    {
X      (void) move(dir, &y, &x);
X      dist++;
X      if (test_light(oldy, oldx)) 
X	lite_spot(oldy, oldx);
X      else
X	unlite_spot(oldy, oldx);
X      if (dist > OBJ_BOLT_RANGE) 
X	flag = TRUE;
X      else
X	{
X	  c_ptr = &cave[y][x];
X	  if ((!c_ptr->fopen) || (c_ptr->cptr > 1)) 
X	    {
X	      flag = TRUE;
X	      if (!c_ptr->fopen) 
X		{
X		  y = oldy;
X		  x = oldx;
X		}
X	      /* The ball hits and explodes...                 */
X	      /* The explosion...                      */
X	      for (i = y-max_dis; i <= y+max_dis; i++)
X		for (j = x-max_dis; j <= x+max_dis; j++)
X		  if (in_bounds(i, j)) 
X		    if (distance(y, x, i, j) <= max_dis) 
X		      if (los(y, x, i, j))     /* FIXED BUG V4.5        */
X			{
X			  c_ptr = &cave[i][j];
X			  if (c_ptr->tptr != 0) 
X			    if (destroy(t_list[c_ptr->tptr].tval))
X			      (void) delete_object(i, j);
X			  if (c_ptr->fopen) 
X			    {
X			      if (panel_contains(i, j))  print("*", i, j);
X			      if (c_ptr->cptr > 1) 
X				{
X				  m_ptr = &m_list[c_ptr->cptr];
X				  r_ptr = &c_list[m_ptr->mptr];
X				  thit++;
X				  dam = dam_hp;
X				  if (harm_type & r_ptr->cdefense)
X				    dam = dam*2;
X				  else if (weapon_type & r_ptr->spells)
X				    dam = dam / 4;
X				  dam = (dam/(distance(i, j, y, x)+1));
X				  k = mon_take_hit((int)c_ptr->cptr, dam);
X				  if (k > 0) 
X				    tkill++;
X				  else
X				    {
X				      if (panel_contains(i, j)) 
X					{
X					  tmp_str[0] = r_ptr->cchar;
X					  tmp_str[1] = '\0';
X					  print(tmp_str, i, j);
X					  m_ptr->ml = TRUE;
X					}
X				    }
X				}
X			    }
X			}
X	      for (i = (y - 2); i <= (y + 2); i++)
X		for (j = (x - 2); j <= (x + 2); j++)
X		  if (in_bounds(i, j)) 
X		    if (panel_contains(i, j)) 
X		      if (distance(y, x, i, j) <= max_dis) 
X			{
X			  c_ptr = &cave[i][j];
X			  if (test_light(i, j)) 
X			    lite_spot(i, j);
X			  else if (c_ptr->cptr == 1) 
X			    lite_spot(i, j);
X			  else if (c_ptr->cptr > 1) 
X			    if (m_list[c_ptr->cptr].ml) 
X			      lite_spot(i, j);
X			    else
X			      unlite_spot(i, j);
X			  else
X			    unlite_spot(i, j);
X			}
X	      /* End  explosion...                     */
X	      if (thit == 1) 
X		{
X		  (void) sprintf(out_val,
X				 "The %s envelopes a creature!",
X				 descrip);
X		  msg_print(out_val);
X		}
X	      else if (thit > 1) 
X		{
X		  (void) sprintf(out_val,
X				 "The %s envelopes several creatures!",
X				 descrip);
X		  msg_print(out_val);
X		}
X	      if (tkill == 1) 
X		msg_print("There is a scream of agony!");
X	      else if (tkill > 1) 
X		msg_print("There are several screams of agony!");
X	      /* End ball hitting...                   */
X	    }
X	  else if (panel_contains(y, x)) 
X	    print("*", y, x);
X	  oldy = y;
X	  oldx = x;
X	}
X    }
X  while (!flag);
X}
X
X
X/* Breath weapon works like a fire_ball, but affects the player. */
X/* Note the area affect....                              -RAK-   */
Xbreath(typ, y, x, dam_hp, ddesc)
Xint typ, y, x, dam_hp;
Xchar *ddesc;
X{
X  int i, j;
X  int dam, max_dis;
X  int weapon_type, harm_type;
X  int (*destroy)();
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X
X  max_dis = 2;
X  get_flags(typ, &weapon_type, &harm_type, &destroy);
X  for (i = y-2; i <= y+2; i++)
X    for (j = x-2; j <= x+2; j++)
X      if (in_bounds(i, j)) 
X	if (distance(y, x, i, j) <= max_dis) 
X	  {
X	    c_ptr = &cave[i][j];
X	    if (c_ptr->tptr != 0) 
X	      if (destroy(t_list[c_ptr->tptr].tval))
X		(void) delete_object(i, j);
X	    if (c_ptr->fopen) 
X	      {
X		if (panel_contains(i, j)) 
X		  print("*", i, j);
X		if (c_ptr->cptr > 1) 
X		  {
X		    m_ptr = &m_list[c_ptr->cptr];
X		    r_ptr = &c_list[m_ptr->mptr];
X		    dam = dam_hp;
X		    if (harm_type & r_ptr->cdefense)
X		      dam = dam*2;
X		    else if (weapon_type & r_ptr->spells)
X		      dam = (dam/4.0);
X		    dam = (dam/(distance(i, j, y, x)+1));
X		    m_ptr->hp = 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,
X				      r_ptr->cmove);
X			delete_monster((int)c_ptr->cptr);
X		      }
X		  }
X		else if (c_ptr->cptr == 1) 
X		  {
X		    dam = (dam_hp/(distance(i, j, y, x)+1));
X		    /* let's do at least one point of damage */
X                    /* prevents randint(0) problem with poison_gas, also */
X                    if (dam == 0)
X                      dam = 1;
X		    switch(typ)
X		      {
X		      case 1: light_dam(dam, ddesc); break;
X		      case 2: poison_gas(dam, ddesc); break;
X		      case 3: acid_dam(dam, ddesc); break;
X		      case 4: cold_dam(dam, ddesc); break;
X		      case 5: fire_dam(dam, ddesc); break;
X		      }
X		  }
X	      }
X	  }
X  for (i = (y - 2); i <= (y + 2); i++)
X    for (j = (x - 2); j <= (x + 2); j++)
X      if (in_bounds(i, j)) 
X	if (panel_contains(i, j)) 
X	  if (distance(y, x, i, j) <= max_dis) 
X	    {
X	      c_ptr = &cave[i][j];
X	      if (test_light(i, j)) 
X		lite_spot(i, j);
X	      else if (c_ptr->cptr == 1) 
X		lite_spot(i, j);
X	      else if (c_ptr->cptr > 1) 
X		if (m_list[c_ptr->cptr].ml) 
X		  lite_spot(i, j);
X		else
X		  unlite_spot(i, j);
X	      else
X		unlite_spot(i, j);
X	    }
X}
X
X
X/* Recharge a wand, staff, or rod.  Sometimes the item breaks. -RAK-*/
Xint recharge(num)
Xint num;
X{
X  int item_val;
X  int redraw;
X  int res;
X  treasure_type *i_ptr;
X
X  res = FALSE;
X  redraw = FALSE;
X  if (get_item(&item_val, "Recharge which item?", &redraw, 0, inven_ctr-1)) 
X    {
X      i_ptr = &inventory[item_val];
X      if ((i_ptr->tval == 55) || (i_ptr->tval == 60) || (i_ptr->tval == 65))
X	/* recharge I = recharge(20) = 1/6 failure */
X	/* recharge II = recharge(60) = 1/10 failure */
X	if (randint((num + 40)/10) == 1)
X	  {
X	    res = TRUE;
X	    msg_print("There is a bright flash of light...");
X	    inven_destroy(item_val);
X	  }
X	else
X	  {
X	    res = TRUE;
X	    num = (num/(i_ptr->level+2)) + 1;
X	    i_ptr->p1 += 2 + randint(num);
X	    if (index(i_ptr->name, '^') == 0) 
X	      insert_str(i_ptr->name, " (%P1", "^ (%P1");
X	  }
X      if (redraw) 
X	{
X	  msg_print(" ");
X	  draw_cave();
X	}
X    }
X  return(res);
X}
X
X
X/* Increase or decrease a creatures hit points		-RAK-	*/
Xint hp_monster(dir, y, x, dam)
Xint dir, y, x, dam;
X{
X  int i;
X  int flag;
X  int monster;
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  vtype out_val;
X
X  monster = FALSE;
X  flag = FALSE;
X  do
X    {
X      (void) move(dir, &y, &x);
X      c_ptr = &cave[y][x];
X      if (c_ptr->fopen) 
X	{
X	  if (c_ptr->cptr > 1) 
X	    {
X	      flag = TRUE;
X	      m_ptr = &m_list[c_ptr->cptr];
X	      r_ptr = &c_list[m_ptr->mptr];
X	      monster = TRUE;
X	      i = mon_take_hit((int)c_ptr->cptr, dam);
X	      if (i > 0) 
X		{
X		  (void) sprintf(out_val, "The %s dies in a fit of agony.",
X			  c_list[i].name);
X		  msg_print(out_val);
X		}
X	      else
X		{
X		  if (dam > 0)
X		    {
X		      (void) sprintf(out_val, "The %s screams in agony.",
X				     r_ptr->name);
X		      msg_print(out_val);
X		    }
X		}
X	    }
X	}
X      else
X	flag = TRUE;
X    }
X  while (!flag);
X  return(monster);
X}
X
X
X/* Drains life; note it must be living...		-RAK-	*/
Xint drain_life(dir, y, x)
Xint dir, y, x;
X{
X  int i;
X  int flag;
X  int drain;
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  vtype out_val;
X
X  drain = FALSE;
X  flag = FALSE;
X  do
X    {
X      (void) move(dir, &y, &x);
X      c_ptr = &cave[y][x];
X      if (c_ptr->fopen) 
X	{
X	  if (c_ptr->cptr > 1) 
X	    {
X	      flag = TRUE;
X	      m_ptr = &m_list[c_ptr->cptr];
X	      r_ptr = &c_list[m_ptr->mptr];
X	      if ((r_ptr->cdefense & 0x0008) == 0) 
X		{
X		  drain = TRUE;
X		  i = mon_take_hit((int)c_ptr->cptr, 50);
X		  if (i > 0) 
X		    {
X		      (void) sprintf(out_val, "The %s dies in a fit of agony.",
X			      c_list[i].name);
X		      msg_print(out_val);
X		    }
X		  else
X		    {
X		      (void) sprintf(out_val, "The %s screams in agony.",
X			      r_ptr->name);
X		      msg_print(out_val);
X		    }
X		}
X	    }
X	  else
X	    flag = TRUE;
X	}
X    }
X  while (!flag);
X  return(drain);
X}
X
X
X/* Increase or decrease a creatures speed		-RAK-	*/
X/* NOTE: cannot slow a winning creature (BALROG)                 */
Xint speed_monster(dir, y, x, spd)
Xint dir, y, x, spd;
X{
X  int speed;
X  int flag;
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  vtype out_val;
X
X  speed = FALSE;
X  flag = FALSE;
X  do
X    {
X      (void) move(dir, &y, &x);
X      c_ptr = &cave[y][x];
X      if (c_ptr->fopen) 
X	{
X	  if (c_ptr->cptr > 1) 
X	    {
X	      flag = TRUE;
X	      m_ptr = &m_list[c_ptr->cptr];
X	      r_ptr = &c_list[m_ptr->mptr];
X	      if (spd > 0) 
X		{
X		  m_ptr->cspeed += spd;
X		  m_ptr->csleep = 0;
X		}
X	      else if (randint(MAX_MONS_LEVEL) > r_ptr->level) 
X		{
X		  m_ptr->cspeed += spd;
X		  m_ptr->csleep = 0;
X		}
X	      else
X		{
X		  (void) sprintf(out_val, "The %s is unaffected.",
X				 r_ptr->name);
X		  msg_print(out_val);
X		  speed = TRUE;
X		}
X	    }
X	  else
X	    flag = TRUE;
X	}
X    }
X  while (!flag);
X  return(speed);
X}
X
X
X/* Confuse a creature					-RAK-	*/
Xint confuse_monster(dir, y, x)
Xint dir, y, x;
X{
X  int flag;
X  int confuse;
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  vtype out_val;
X
X  confuse = FALSE;
X  flag = FALSE;
X  do
X    {
X      (void) move(dir, &y, &x);
X      c_ptr = &cave[y][x];
X      if (c_ptr->fopen) 
X	{
X	  if (c_ptr->cptr > 1) 
X	    {
X	      m_ptr = &m_list[c_ptr->cptr];
X	      r_ptr = &c_list[m_ptr->mptr];
X	      confuse = TRUE;
X	      flag = TRUE;
X	      if ((randint(MAX_MONS_LEVEL) < r_ptr->level) ||
X		  (0x1000 & r_ptr->cdefense))
X		{
X		  (void) sprintf(out_val, "The %s is unaffected.",
X				 r_ptr->name);
X		  msg_print(out_val);
X		}
X	      else
X		{
X		  m_ptr->confused = TRUE;
X		  m_ptr->csleep = 0;
X		  (void) sprintf(out_val, "The %s appears confused.",
X				 r_ptr->name);
X		  msg_print(out_val);
X		}
X	    }
X	}
X      else
X	flag = TRUE;
X    }
X  while (!flag);
X  return(confuse);
X}
X
X
X/* Sleep a creature...					-RAK-	*/
Xint sleep_monster(dir, y, x)
Xint dir, y, x;
X{
X  int flag;
X  int sleep;
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  vtype out_val;
X
X  sleep = FALSE;
X  flag = FALSE;
X  do
X    {
X      (void) move(dir, &y, &x);
X      c_ptr = &cave[y][x];
X      if (c_ptr->fopen) 
X	{
X	  if (c_ptr->cptr > 1) 
X	    {
X	      m_ptr = &m_list[c_ptr->cptr];
X	      r_ptr = &c_list[m_ptr->mptr];
X	      sleep = TRUE;
X	      flag = TRUE;
X	      if ((randint(MAX_MONS_LEVEL) < r_ptr->level) ||
X		  (0x1000 & r_ptr->cdefense))
X		{
X		  (void) sprintf(out_val, "The %s is unaffected.",
X				 r_ptr->name);
X		  msg_print(out_val);
X		}
X	      else
X		{
X		  m_ptr->csleep = 500;
X		  (void) sprintf(out_val, "The %s falls asleep.", r_ptr->name);
X		  msg_print(out_val);
X		}
X	    }
X	}
X      else
X	flag = TRUE;
X    }
X  while (!flag);
X  return(sleep);
X}
X
X
X/* Turn stone to mud, delete wall....			-RAK-	*/
Xint wall_to_mud(dir, y, x)
Xint dir, y, x;
X{
X  int i;
X  vtype out_val, tmp_str;
X  int flag;
X  int wall;
X  cave_type *c_ptr;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X
X  wall = FALSE;
X  flag = FALSE;
X  do
X    {
X      (void) move(dir, &y, &x);
X      c_ptr = &cave[y][x];
X      if (in_bounds(y, x)) 
X	{
X	  if ((c_ptr->fval >= 10) && (c_ptr->fval <= 12))
X	    {
X	      flag = TRUE;
X	      (void) twall(y, x, 1, 0);
X	      if (test_light(y, x)) 
X		{
X		  msg_print("The wall turns into mud.");
X		  wall = TRUE;
X		}
X	    }
X	  else if ((c_ptr->tptr != 0) && (!c_ptr->fopen)) 
X	    {
X	      flag = TRUE;
X	      if (panel_contains(y, x)) 
X		if (test_light(y, x)) 
X		  {
X		    inventory[INVEN_MAX] = t_list[c_ptr->tptr];
X		    objdes(tmp_str, INVEN_MAX, FALSE);
X		    (void) sprintf(out_val, "The %s turns into mud.", tmp_str);
X		    msg_print(out_val);
X		    wall = TRUE;
X		  }
X	      (void) delete_object(y, x);
X	    }
X	  if (c_ptr->cptr > 1) 
X	    {
X	      m_ptr = &m_list[c_ptr->cptr];
X	      r_ptr = &c_list[m_ptr->mptr];
X	      if (0x0200 & r_ptr->cdefense)
X		{
X		  i = mon_take_hit((int)c_ptr->cptr, 100);
X		  flag = TRUE;
X		  if (m_ptr->ml) 
X		    if (i > 0) 
X		      {
X			(void) sprintf(out_val,
X				       "The %s dies in a fit of agony.",
X				       r_ptr->name);
X			msg_print(out_val);
X		      }
X		    else
X		      {
X			(void) sprintf(out_val, "The %s wails out in pain!",
X				r_ptr->name);
X			msg_print(out_val);
X		      }
X		}
X	    }
X	}
X      else
X	flag = TRUE;
X    }
X  while (!flag);
X  return(wall);
X}
X
X
X/* Destroy all traps and doors in a given direction	-RAK-	*/
Xint td_destroy2(dir, y, x)
Xint dir, y, x;
X{
X  int destroy2;
X  cave_type *c_ptr;
X  treasure_type *t_ptr;
X
X  destroy2 = FALSE;
X  do
X    {
X      (void) move(dir, &y, &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 == 2) || (t_ptr->tval == 101) ||
X	      (t_ptr->tval == 102) || (t_ptr->tval == 104) ||
X	      (t_ptr->tval == 105) || (t_ptr->tval == 109))
X	    {
X	      if (delete_object(y, x)) 
X		{
X		  msg_print("There is a bright flash of light!");
X		  c_ptr->fopen = TRUE;
X		  destroy2 = TRUE;
X		}
X	    }
X	}
X    }
X  while (cave[y][x].fopen);
X  return(destroy2);
X}
X
X
X/* Polymorph a monster					-RAK-	*/
X/* NOTE: cannot polymorph a winning creature (BALROG)            */
Xint poly_monster(dir, y, x)
Xint dir, y, x;
X{
X  int dist;
X  int flag;
X  int poly;
X  cave_type *c_ptr;
X  creature_type *r_ptr;
X  vtype out_val;
X
X  poly = FALSE;
X  flag = FALSE;
X  dist = 0;
X  do
X    {
X      (void) move(dir, &y, &x);
X      dist++;
X      if (dist <= OBJ_BOLT_RANGE) 
X	{
X	  c_ptr = &cave[y][x];
X	  if (c_ptr->fopen) 
X	    {
X	      if (c_ptr->cptr > 1) 
X		{
X		  r_ptr = &c_list[m_list[c_ptr->cptr].mptr];
X		  if (randint(MAX_MONS_LEVEL) > r_ptr->level) 
X		    {
X		      flag = TRUE;
X		      delete_monster((int)c_ptr->cptr);
X		      place_monster(y, x, 
X			  randint(m_level[MAX_MONS_LEVEL]) - 1 + m_level[0],
X				    FALSE);
X		      if (panel_contains(y, x)) 
X			if (test_light(y, x)) 
X			  poly = TRUE;
X		    }
X		  else
X		    {
X		      (void) sprintf(out_val, "The %s is unaffected.",
X				     r_ptr->name);
X		      msg_print(out_val);
X		    }
X		}
X	      else
X		flag = TRUE;
X	    }
X	}
X      else
X	flag = TRUE;
X    }
X  while (!flag);
X  return(poly);
X}
X
X
X/* Create a wall...					-RAK-	*/
Xint build_wall(dir, y, x)
Xint dir, y, x;
X{
X  int i;
X  int build;
X  cave_type *c_ptr;
X
X  build = FALSE;
X  i = 0;
X  (void) move(dir, &y, &x);
X  while ((cave[y][x].fopen) && (i < 10))
X    {
X      c_ptr = &cave[y][x];
X      if (c_ptr->tptr != 0) 
X	(void) delete_object(y, x);
X      if (c_ptr->cptr > 1) 
X	/* what happens to this monster ? */
X	(void) mon_take_hit((int)c_ptr->cptr, damroll("2d8"));
X      c_ptr->fval  = rock_wall2.ftval;
X      c_ptr->fopen = rock_wall2.ftopen;
X      c_ptr->fm = FALSE;
X      if (test_light(y, x)) 
X	lite_spot(y, x);
X      i++;
X      build = TRUE;
X      (void) move(dir, &y, &x);
X    }
X  return(build);
X}
X
X
X/* Replicate a creature					-RAK-	*/
Xint clone_monster(dir, y, x)
Xint dir, y, x;
X{
X  int flag;
X  int clone;
X  cave_type *c_ptr;
X
X  flag = FALSE;
X  clone = FALSE;
X  do
X    {
X      (void) move(dir, &y, &x);
X      c_ptr = &cave[y][x];
X      if (c_ptr->cptr > 1) 
X	{
X	  multiply_monster(y, x, (int)m_list[c_ptr->cptr].mptr, FALSE);
X	  if (panel_contains(y, x)) 
X	    if (m_list[c_ptr->cptr].ml) 
X	      clone = TRUE;
X	  flag = TRUE;
X	}
X    }
X  while ((cave[y][x].fopen) && (!flag));
X  return(clone);
X}
X
X
X/* Move the creature record to a new location		-RAK-	*/
Xteleport_away(monptr, dis)
Xint monptr, dis;
X{
X  int yn, xn, ctr;
X  monster_type *m_ptr;
X
X  m_ptr = &m_list[monptr];
X  ctr = 0;
X  do
X    {
X      do
X	{
X	  yn = m_ptr->fy + (randint(2*dis+1) - (dis + 1));
X	  xn = m_ptr->fx + (randint(2*dis+1) - (dis + 1));
X	}
X      while (!in_bounds(yn, xn));
X      ctr++;
X      if (ctr > 9) 
X	{
X	  ctr = 0;
X	  dis += 5;
X	}
X    }
X  while ((!cave[yn][xn].fopen) || (cave[yn][xn].cptr != 0));
X  move_rec((int)m_ptr->fy, (int)m_ptr->fx, yn, xn);
X  if (test_light((int)m_ptr->fy, (int)m_ptr->fx)) 
X    lite_spot((int)m_ptr->fy, (int)m_ptr->fx);
X  m_ptr->fy = yn;
X  m_ptr->fx = xn;
X  m_ptr->ml = FALSE;
X}
X
X
X/* Teleport player to spell casting creature		-RAK-	*/
Xteleport_to(ny, nx)
Xint ny, nx;
X{
X  int dis, ctr, y, x, i, j;
X  cave_type *c_ptr;
X
X  dis = 1;
X  ctr = 0;
X  do
X    {
X      y = ny + (randint(2*dis+1) - (dis + 1));
X      x = nx + (randint(2*dis+1) - (dis + 1));
X      ctr++;
X      if (ctr > 9) 
X	{
X	  ctr = 0;
X	  dis = dis + 1;
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}
X
X
X/* Teleport all creatures in a given direction away	-RAK-	*/
Xint teleport_monster(dir, y, x)
Xint dir, y, x;
X{
X  int flag;
X  int teleport;
X  cave_type *c_ptr;
X
X  flag = FALSE;
X  teleport = FALSE;
X  do
X    {
X      (void) move(dir, &y, &x);
X      c_ptr = &cave[y][x];
X      if (c_ptr->cptr > 1) 
X	{
X	  teleport_away((int)c_ptr->cptr, MAX_SIGHT);
X	  teleport = TRUE;
X	}
X    }
X  while ((cave[y][x].fopen) && (!flag));
X  return(teleport);
X}
X
X
X/* Delete all creatures within max_sight distance	-RAK-	*/
X/* NOTE : Winning creatures cannot be genocided                  */
Xint mass_genocide()
X{
X  int i, j;
X  int genocide;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X
X  genocide = FALSE;
X  i = muptr;
X  while (i > 0)
X    {
X      m_ptr = &m_list[i];
X      r_ptr = &c_list[m_ptr->mptr];
X      j = m_ptr->nptr;
X      if (m_ptr->cdis <= MAX_SIGHT) 
X	if ((r_ptr->cdefense & 0x80000000) == 0) 
X	  {
X	    delete_monster(i);
X	    genocide = TRUE;
X	  }
X      i = j;
X    }
X  return(genocide);
X}
X
X
X/* Delete all creatures of a given type from level.	-RAK-	*/
X/* This does not keep creatures of type from appearing later.    */
X/* NOTE : Winning creatures that are genocided will be considered*/
X/*        as teleporting to another level.  Genocide will NOT win*/
X/*        the game...                                            */
Xint genocide()
X{
X  int i, j;
X  char typ;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  vtype out_val;
X
X  i = muptr;
X  if (get_com("Which type of creature do wish exterminated?", &typ)) 
X    while (i > 0)
X      {
X	m_ptr = &m_list[i];
X	r_ptr = &c_list[m_ptr->mptr];
X	j = m_ptr->nptr;
X	if (typ == c_list[m_ptr->mptr].cchar) 
X	  if ((r_ptr->cdefense & 0x80000000) == 0) 
X	    delete_monster(i);
X	  else
X	    {
X	      (void) sprintf(out_val, "The %s is unaffected.", r_ptr->name);
X	      msg_print(out_val);
X	    }
X	i = j;
X      }
X  return(TRUE);
X}
X
X
X/* Change speed of any creature player can see....	-RAK-	*/
X/* NOTE: cannot slow a winning creature (BALROG)                 */
Xint speed_monsters(spd)
Xint spd;
X{
X  int i, j;
X  int speed;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  vtype out_val;
X
X  i = muptr;
X  speed = FALSE;
X  while (i > 0)
X    {
X      m_ptr = &m_list[i];
X      j = m_ptr->nptr;
X      if (m_ptr->ml) 
X	{
X	  r_ptr = &c_list[m_ptr->mptr];
X	  if (spd > 0) 
X	    {
X	      m_ptr->cspeed += spd;
X	      m_ptr->csleep = 0;
X	      speed = TRUE;
X	    }
X	  else if (randint(MAX_MONS_LEVEL) > r_ptr->level) 
X	    {
X	      m_ptr->cspeed += spd;
X	      m_ptr->csleep = 0;
X	      speed = TRUE;
X	    }
X	  else
X	    {
X	      (void) sprintf(out_val, "The %s is unaffected.", r_ptr->name);
X	      msg_print(out_val);
X	    }
X	}
X      i = j;
X    }
X  return(speed);
X}
X
X
X/* Sleep any creature that player can see		-RAK-	*/
Xint sleep_monsters2()
X{
X  int i, j;
X  int sleep;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  vtype out_val;
X
X  i = muptr;
X  sleep = FALSE;
X  while (i > 0)
X    {
X      m_ptr = &m_list[i];
X      r_ptr = &c_list[m_ptr->mptr];
X      j = m_ptr->nptr;
X      sleep = TRUE;
X      if (m_ptr->ml) 
X	{
X	  if ((randint(MAX_MONS_LEVEL) < r_ptr->level) ||
X	      (0x1000 & r_ptr->cdefense))
X	    {
X	      (void) sprintf(out_val, "The %s is unaffected.", r_ptr->name);
X	      msg_print(out_val);
X	    }
X	  else
X	    m_ptr->csleep = 500;
X	}
X      i = j;
X    }
X  return(sleep);
X}
X
X
X/* Polymorph any creature that player can see... 	-RAK-	*/
X/* NOTE: cannot polymorph a winning creature (BALROG)            */
Xint mass_poly()
X{
X  int i, j, y, x;
X  int mass;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X
X  i = muptr;
X  mass = FALSE;
X  while (i > 0)
X    {
X      m_ptr = &m_list[i];
X      j = m_ptr->nptr;
X      if (m_ptr->cdis < MAX_SIGHT) 
X	{
X	  r_ptr = &c_list[m_ptr->mptr];
X	  if ((r_ptr->cdefense & 0x80000000) == 0) 
X	    {
X	      y = m_ptr->fy;
X	      x = m_ptr->fx;
X	      delete_monster(i);
X	      place_monster(y, x, randint(m_level[MAX_MONS_LEVEL]) - 1
X			    + m_level[0], FALSE);
X	      mass = TRUE;
X	    }
X	}
X      i = j;
X    }
X  return(mass);
X}
X
X
X/* Display evil creatures on current panel		-RAK-	*/
Xint detect_evil()
X{
X  int i;
X  int flag;
X  monster_type *m_ptr;
X  char temp_str[2];
X
X  flag = FALSE;
X  i = muptr;
X  while (i > 0)
X    {
X      m_ptr = &m_list[i];
X      if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx)) 
X	if (0x0004 & c_list[m_ptr->mptr].cdefense)
X	  {
X	    m_ptr->ml = TRUE;
X	    temp_str[0] = c_list[m_ptr->mptr].cchar;
X	    temp_str[1] = '\0';
X	    print(temp_str, (int)m_ptr->fy, (int)m_ptr->fx);
X	    flag = TRUE;
X	  }
X      i = m_list[i].nptr;
X    }
X  if (flag) 
X    {
X      msg_print("You sense the presence of evil!");
X      msg_print(" ");
X      msg_flag = FALSE;
X    }
X  return(flag);
X}
X
X
X/* Change players hit points in some manner		-RAK-	*/
Xint hp_player(num, kind)
Xint num;
Xchar *kind;
X{
X  int res;
X  struct misc *m_ptr;
X
X  res = FALSE;
X  m_ptr = &py.misc;
X  if (num < 0) 
X    {
X      take_hit(num, kind);
X      if (m_ptr->chp < 0) 
X	msg_print("You feel your life slipping away!");
X      res = TRUE;
X    }
X  else if (m_ptr->chp < m_ptr->mhp) 
X    {
X      m_ptr->chp += (double)num;
X      if (m_ptr->chp > m_ptr->mhp) 
X	m_ptr->chp = (double)m_ptr->mhp;
X      prt_chp();
X      switch(num/5)
X	{
X	case 0:
X	  msg_print("You feel a little better.");
X	  break;
X	case 1: case 2:
X	  msg_print("You feel better.");
X	  break;
X	case 3: case 4: case 5: case 6:
X	  msg_print("You feel much better.");
X	  break;
X	default:
X	  msg_print("You feel very good.");
X	  break;
X	}
X      res = TRUE;
X    }
X  return(res);
X}
X
X
X/* Cure players confusion				-RAK-	*/
Xint cure_confusion()
X{
X  int cure;
X  struct flags *f_ptr;
X
X  cure = FALSE;
X  f_ptr = &py.flags;
X  if (f_ptr->confused > 1) 
X    {
X      f_ptr->confused = 1;
X      cure = TRUE;
X    }
X  return(cure);
X}
X
X
X/* Cure players blindness				-RAK-	*/
Xint cure_blindness()
X{
X  int cure;
X  struct flags *f_ptr;
X
X  cure = FALSE;
X  f_ptr = &py.flags;
X  if (f_ptr->blind > 1) 
X    {
X      f_ptr->blind = 1;
X      cure = TRUE;
X    }
X  return(cure);
X}
X
X
X/* Cure poisoning					-RAK-	*/
Xint cure_poison()
X{
X  int cure;
X  struct flags *f_ptr;
X
X  cure = FALSE;
X  f_ptr = &py.flags;
X  if (f_ptr->poisoned > 1) 
X    {
X      f_ptr->poisoned = 1;
X      cure = TRUE;
X    }
X  return(cure);
X}
X
X
X/* Cure the players fear 				-RAK-	*/
Xint remove_fear()
X{
X  int remove;
X  struct flags *f_ptr;
X
X  remove = FALSE;
X  f_ptr = &py.flags;
X  if (f_ptr->afraid > 1) 
X    {
X      f_ptr->afraid = 1;
X      remove = TRUE;
X    }
X  return(remove);
X}
X
X
X/* This is a fun one.  In a given block, pick some walls and	*/
X/* turn them into open spots.  Pick some open spots and turn     */
X/* them into walls.  An "Earthquake" effect...           -RAK-   */
Xint earthquake()
X{
X  int i, j;
X  cave_type *c_ptr;
X
X  for (i = char_row-8; i <= char_row+8; i++)
X    for (j = char_col-8; j <= char_col+8; j++)
X      if ((i != char_row) || (j != char_col)) 
X	if (in_bounds(i, j)) 
X	  if (randint(8) == 1) 
X	    {
X	      c_ptr = &cave[i][j];
X	      if (c_ptr->tptr != 0) 
X		(void) delete_object(i, j);
X	      if (c_ptr->cptr > 1) 
X		/* what happens to this monster ? */
X		(void) mon_take_hit((int)c_ptr->cptr, damroll("2d8"));
X	      if ((c_ptr->fval >= 10) && (c_ptr->fval <= 12))
X		{
X		  if (next_to4(i, j, 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(i, j))
X		    unlite_spot(i, j);
X		  c_ptr->pl = FALSE;
X		  c_ptr->fm = FALSE;
X		  if (c_ptr->tl)
X		    lite_spot(i, j);
X		}
X	      else if (set_floor(c_ptr->fval))
X		{
X		  switch(randint(10))
X		    {
X		    case 1: case 2: case 3: case 4: case 5:
X		      c_ptr->fval  = rock_wall3.ftval;
X		      c_ptr->fopen = rock_wall3.ftopen;
X		      break;
X		    case 6: case 7: case 8:
X		      c_ptr->fval  = rock_wall2.ftval;
X		      c_ptr->fopen = rock_wall2.ftopen;
X		      break;
X		    case 9: case 10:
X		      c_ptr->fval  = rock_wall1.ftval;
X		      c_ptr->fopen = rock_wall1.ftopen;
X		      break;
X		    }
X		  c_ptr->fm = FALSE;
X		}
X	      if (test_light(i, j)) 
X		lite_spot(i, j);
X	    }
X  return(TRUE);
X}
X
X
X/* Evil creatures don't like this...                     -RAK-   */
Xint protect_evil()
X{
X  struct flags *f_ptr;
X
X  f_ptr = &py.flags;
X  f_ptr->protevil += randint(25) + 3*py.misc.lev;
X  return(TRUE);
X}
X
X
X/* Create some high quality mush for the player. 	-RAK-	*/
Xint create_food()
X{
X  cave_type *c_ptr;
X
X  c_ptr = &cave[char_row][char_col];
X  if (c_ptr->tptr != 0) 
X    (void) delete_object(char_row, char_col);
X  place_object(char_row, char_col);
X  t_list[c_ptr->tptr] = mush;
X  return(TRUE);
X}
X
X
X/* Attempts to destroy a type of creature.  Success depends on	*/
X/* the creatures level VS. the player's level            -RAK-   */
Xint dispell_creature(cflag, damage)
Xint cflag;
Xint damage;
X{
X  int i, m_next;
X  vtype out_val;
X  monster_type *m_ptr;
X  creature_type *r_ptr;
X  struct misc *p_ptr;
X  int dispel;
X
X  i = muptr;
X  dispel = FALSE;
X  while (i > 0)
X    {
X      m_next = m_list[i].nptr;
X      m_ptr = &m_list[i];
X      if (m_ptr->ml) 
X	if (cflag & c_list[m_ptr->mptr].cdefense)
X	  {
X	    m_ptr->hp -= randint(damage);
X	    m_ptr->csleep = 0;
X	    if (m_ptr->hp < 0) 
X	      {
X		(void) sprintf(out_val, "The %s dissolves!",
X			       c_list[m_ptr->mptr].name);
X		msg_print(out_val);
X		monster_death((int)m_ptr->fy, (int)m_ptr->fx,
X			      c_list[m_ptr->mptr].cmove);
X		r_ptr = &c_list[m_ptr->mptr];
X		p_ptr = &py.misc;
X		p_ptr->exp += ((r_ptr->mexp*(r_ptr->level/p_ptr->lev)) + 0.5);
X		delete_monster(i);
X	      }
X	    else
X	      {
X		(void) sprintf(out_val, "The %s shudders.",
X			       c_list[m_ptr->mptr].name);
X		msg_print(out_val);
X	      }
X	    dispel = TRUE;
X	  }
X      i = m_next;
X    }
X  return(dispel);
X}
X
X
X/* Attempt to turn (confuse) undead creatures... 	-RAK-	*/
Xint turn_undead()
X{
X  int i;
X  int turn_und;
X  monster_type *m_ptr;
X  vtype out_val;
X
X  i = muptr;
X  turn_und = FALSE;
X  while (i > 0)
X    {
X      m_ptr = &m_list[i];
X      if (panel_contains((int)m_ptr->fy, (int)m_ptr->fx)) 
X	if (m_ptr->ml) 
X	  if (0x0008 & c_list[m_ptr->mptr].cdefense)
X	    {
X	      if (((py.misc.lev+1) > c_list[m_ptr->mptr].level) ||
X		  (randint(5) == 1)) 
X		{
X		  (void) sprintf(out_val, "The %s runs frantically!",
X			  c_list[m_ptr->mptr].name);
X		  msg_print(out_val);
X		  m_ptr->confused = TRUE;
X		}
X	      else
X		{
X		  (void) sprintf(out_val, "The %s is unaffected.",
X			  c_list[m_ptr->mptr].name);
X		  msg_print(out_val);
X		}
X	      turn_und = TRUE;
X	    }
X      i = m_list[i].nptr;
X    }
X  return(turn_und);
X}
X
X
X/* Leave a glyph of warding... Creatures will not pass over! -RAK-*/
Xint warding_glyph()
X{
X  int i;
X  cave_type *c_ptr;
X
X  c_ptr = &cave[char_row][char_col];
X  if (c_ptr->tptr == 0) 
X    {
X      popt(&i);
X      c_ptr->tptr = i;
X      t_list[i] = scare_monster;
X    }
X  return(TRUE);
X}
X
X
X/* Lose a strength point.				-RAK-	*/
Xint lose_str()
X{
X  if (!py.flags.sustain_str) 
X    {
X      py.stats.cstr = de_statp(py.stats.cstr);
X      msg_print("You feel very sick.");
X      prt_strength();
X    }
X  else
X    msg_print("You feel sick for a moment,  it passes.");
X  return(TRUE);
X}
X
X
X/* Lose an intelligence point.				-RAK-	*/
Xint lose_int()
X{
X  if (!py.flags.sustain_int) 
X    {
X      py.stats.cint = de_statp(py.stats.cint);
X      msg_print("You become very dizzy.");
X      prt_intelligence();
X    }
X  else
X    msg_print("You become dizzy for a moment,  it passes.");
X  return(TRUE);
X}
X
X
X/* Lose a wisdom point.					-RAK-	*/
Xint lose_wis()
X{
X  if (!py.flags.sustain_wis) 
X    {
X      py.stats.cwis = de_statp(py.stats.cwis);
X      msg_print("You feel very naive.");
X      prt_wisdom();
X    }
X  else
X    msg_print("You feel naive for a moment,  it passes.");
X  return(TRUE);
X}
X
X
X/* Lose a dexterity point.				-RAK-	*/
Xint lose_dex()
X{
X  if (!py.flags.sustain_dex) 
X    {
X      py.stats.cdex = de_statp(py.stats.cdex);
X      msg_print("You feel very sore.");
X      prt_dexterity();
X    }
X  else
X    msg_print("You feel sore for a moment,  it passes.");
X  return(TRUE);
X}
X
X
X/* Lose a constitution point.				-RAK-	*/
Xint lose_con()
X{
X  if (!py.flags.sustain_con) 
X    {
X      py.stats.ccon = de_statp(py.stats.ccon);
X      msg_print("You feel very sick.");
X      prt_constitution();
X    }
X  else
X    msg_print("You feel sick for a moment,  it passes.");
X  return(TRUE);
X}
X
X
X/* Lose a charisma point.				-RAK-	*/
Xint lose_chr()
X{
X  if (!py.flags.sustain_chr) 
X    {
X      py.stats.cchr = de_statp(py.stats.cchr);
X      msg_print("Your skin starts to itch.");
X      prt_charisma();
X    }
X  else
X    msg_print("Your skin starts to itch, but feels better now.");
X  return(TRUE);
X}
X
X
X/* Lose experience					-RAK-	*/
Xlose_exp(amount)
Xint amount;
X{
X  int i, j;
X  int av_hp, lose_hp;
X  int av_mn, lose_mn;
X  int flag;
X  struct misc *m_ptr;
X  class_type *c_ptr;
X
X  m_ptr = &py.misc;
X  if (amount > m_ptr->exp) 
X    m_ptr->exp = 0;
X  else
X    m_ptr->exp -= amount;
X  i = 1;
X  while ((player_exp[i]*m_ptr->expfact) <= m_ptr->exp)
X    i++;
X  j = m_ptr->lev - i;
X  while (j > 0)
X    {
X      av_hp = (m_ptr->mhp/m_ptr->lev) + 1;
X      av_mn = (m_ptr->mana/m_ptr->lev) + 1;
X      m_ptr->lev--;
X      j--;
X      lose_hp = randint(av_hp*2-1);
X      lose_mn = randint(av_mn*2-1);
X      m_ptr->mhp  -= lose_hp;
X      m_ptr->mana -= lose_mn;
X      if (m_ptr->mhp  < 1)  m_ptr->mhp  = 1;
X      if (m_ptr->mana < 0)  m_ptr->mana = 0;
X      c_ptr = &class[m_ptr->pclass];
X      if ((c_ptr->mspell) || (c_ptr->pspell)) 
X	{
X	  i = 32;
X	  flag = FALSE;
X	  do
X	    {
X	      i--;
X	      if (magic_spell[m_ptr->pclass][i].learned) 
X		flag = TRUE;
X	    }
X	  while ((!flag) && (i >= 2));
X	  if (flag) 
X	    {
X	      magic_spell[m_ptr->pclass][i].learned = FALSE;
X	      if (c_ptr->mspell) 
X		msg_print("You have forgotten a magic spell!");
X	      else
X		msg_print("You have forgotten a prayer!");
X	    }
X	}
X    }
X  if (m_ptr->chp > m_ptr->mhp)
X    m_ptr->chp = (double)m_ptr->mhp;
X  if (m_ptr->cmana > m_ptr->mana)
X    m_ptr->cmana = (double)m_ptr->mana;
X  (void) strcpy(m_ptr->title, player_title[m_ptr->pclass][m_ptr->lev-1]);
X  prt_experience();
X  prt_mhp();
X  prt_chp();
X  prt_cmana();
X  prt_level();
X  prt_title();
X}
X
X
X/* Slow Poison						-RAK-	*/
Xint slow_poison()
X{
X  int slow;
X  struct flags *f_ptr;
X
X  slow = FALSE;
X  f_ptr = &py.flags;
X  if (f_ptr->poisoned > 0) 
X    {
X      f_ptr->poisoned /= 2.0;
X      if (f_ptr->poisoned < 1)  f_ptr->poisoned = 1;
X      slow = TRUE;
X      msg_print("The effects of the poison has been reduced.");
X    }
X  return(slow);
X}
X
X
X/* Bless 						-RAK-	*/
Xint bless(amount)
Xint amount;
X{
X  py.flags.blessed += amount;
X  return(TRUE);
X}
X
X
X/* Detect Invisible for period of time			-RAK-	*/
Xdetect_inv2(amount)
Xint amount;
X{
X  py.flags.detect_inv += amount;
X}
X
X
Xreplace_spot(y, x, typ)
Xint y, x, typ;
X{
X  cave_type *c_ptr;
X
X  c_ptr = &cave[y][x];
X  switch(typ)
X    {
X    case 1: case 2: case 3:
X      c_ptr->fval  = corr_floor1.ftval;
X      c_ptr->fopen = corr_floor1.ftopen;
X      break;
X    case 4: case 7: case 10:
X      c_ptr->fval  = rock_wall1.ftval;
X      c_ptr->fopen = rock_wall1.ftopen;
X      break;
X    case 5: case 8: case 11:
X      c_ptr->fval  = rock_wall2.ftval;
X      c_ptr->fopen = rock_wall2.ftopen;
X      break;
X    case 6: case 9: case 12:
X      c_ptr->fval  = rock_wall3.ftval;
X      c_ptr->fopen = rock_wall3.ftopen;
X      break;
X    }
X  c_ptr->pl = FALSE;
X  c_ptr->fm = FALSE;
X  if (c_ptr->tptr != 0) 
X    (void) delete_object(y, x);
X  if (c_ptr->cptr > 1) 
X    delete_monster((int)c_ptr->cptr);
X}
X
X
X/* The spell of destruction...				-RAK-	*/
X/* NOTE : Winning creatures that are deleted will be considered  */
X/*        as teleporting to another level.  This will NOT win the*/
X/*        game...                                                */
Xint destroy_area(y, x)
Xint y, x;
X{
X  int i, j, k;
X
X  if (dun_level > 0) 
X    {
X      for (i = (y-15); i <= (y+15); i++)
X	for (j = (x-15); j <= (x+15); j++)
X	  if (in_bounds(i, j)) 
X	    if (cave[i][j].fval != 15) 
X	      {
X		k = distance(i, j, y, x);
X		if (k < 13) 
X		  replace_spot(i, j, randint(6));
X		else if (k < 16) 
X		  replace_spot(i, j, randint(9));
X	      }
X    }
X  msg_print("There is a searing blast of light!");
X  py.flags.blind += 10 + randint(10);
X  return(TRUE);
X}
X
X
X/* Enchants a plus onto an item...			-RAK-	*/
Xint enchant(plusses)
Xworlint *plusses;
X{
X  int chance;
X  int res;
X
X  chance = 0;
X  res = FALSE;
X  if (*plusses > 0) 
X    switch(*plusses)
X      {
X      case 1:  chance = 040; break;
X      case 2:  chance = 100; break;
X      case 3:  chance = 200; break;
X      case 4:  chance = 400; break;
X      case 5:  chance = 600; break;
X      case 6:  chance = 700; break;
X      case 7:  chance = 800; break;
X      case 8:  chance = 900; break;
X      case 9:  chance = 950; break;
X      default: chance = 995; break;
X      }
X  if (randint(1000) > chance) 
X    {
X      *plusses += 1;
X      res = TRUE;
X    }
X  return(res);
X}
X
X
X/* Removes curses from items in inventory		-RAK-	*/
Xint remove_curse()
X{
X  int i;
X  int remove;
X  treasure_type *i_ptr;
X
X  remove = FALSE;
X  for (i = 22; i <= 31; i++)
X    {
X      i_ptr = &inventory[i];
X      if (0x80000000 & i_ptr->flags)
X	{
X	  i_ptr->flags &= 0x7FFFFFFF;
X	  py_bonuses(blank_treasure, 0);
X	  remove = TRUE;
X	}
X    }
X  return(remove);
X}
X
X
X/* Restores any drained experience			-RAK-	*/
Xint restore_level()
X{
X  int restore;
X  struct misc *m_ptr;
X  
X  restore = FALSE;
X  m_ptr = &py.misc;
X  if (m_ptr->max_exp > m_ptr->exp) 
X    {
X      restore = TRUE;
X      msg_print("You feel your life energies returning...");
X      while (m_ptr->exp < m_ptr->max_exp)
X	{
X	  m_ptr->exp = m_ptr->max_exp;
X	  prt_experience();
X	}
X    }
X  return(restore);
X}
END_OF_spells.c
if test 50992 -ne `wc -c <spells.c`; then
    echo shar: \"spells.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 3 \(of 16\).
cp /dev/null ark3isdone
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