From decwrl!wyse!mips!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!aplcen!uunet!zephyr.ens.tek.com!tekred!saab!billr Sat May 19 10:38:40 PDT 1990
Article 878 of comp.sources.games:
Path: decwrl!wyse!mips!zaphod.mps.ohio-state.edu!uakari.primate.wisc.edu!aplcen!uunet!zephyr.ens.tek.com!tekred!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v09i059:  umoria3 - single player dungeon simulation (ver. 5.2), Part05/31
Message-ID: <5590@tekred.CNA.TEK.COM>
Date: 16 May 90 19:11:51 GMT
Sender: news@tekred.CNA.TEK.COM
Lines: 2515
Approved: billr@saab.CNA.TEK.COM

Submitted-by: wilson@ernie.Berkeley.EDU (Jim Wilson)
Posting-number: Volume 9, Issue 59
Archive-name: umoria3/Part05
Supersedes: umoria2: Volume 5, Issue 32-37,41-52,87



#! /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 5 (of 31)."
# Contents:  misc2.c
# Wrapped by billr@saab on Wed May 16 11:58:33 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'misc2.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'misc2.c'\"
else
echo shar: Extracting \"'misc2.c'\" \(57629 characters\)
sed "s/^X//" >'misc2.c' <<'END_OF_FILE'
X/* misc2.c: misc code for maintaining the dungeon, printing player info
X
X   Copyright (c) 1989 James E. Wilson, Robert A. Koeneke
X
X   This software may be copied and distributed for educational, research, and
X   not for profit purposes provided that this copyright and statement are
X   included in all such copies. */
X
X#include "config.h"
X
X/* include before constant.h because param.h defines NULL incorrectly */
X#ifndef USG
X#include <sys/types.h>
X#include <sys/param.h>
X#endif
X
X#include "constant.h"
X#include "types.h"
X#include "externs.h"
X
X#include <ctype.h>
X
X#ifdef USG
X#ifndef ATARIST_MWC
X#include <string.h>
X#else
Xchar *index();
X#endif
X#else
X#include <strings.h>
X#endif
X
X#if defined(LINT_ARGS)
Xstatic void prt_lnum(char *, int32, int, int);
Xstatic void prt_num(char *, int, int, int);
Xstatic void prt_long(int32, int, int);
Xstatic void prt_int(int, int, int);
Xstatic void gain_level(void);
X#endif
X
Xstatic char *stat_names[] = { "STR : ", "INT : ", "WIS : ",
X				 "DEX : ", "CON : ", "CHR : " };
X#define BLANK_LENGTH	24
Xstatic char blank_string[] = "                        ";
X
Xchar *malloc();
X
X/* Places a particular trap at location y, x		-RAK-	*/
Xvoid place_trap(y, x, subval)
Xint y, x, subval;
X{
X  register int cur_pos;
X
X  cur_pos = popt();
X  cave[y][x].tptr  = cur_pos;
X  invcopy(&t_list[cur_pos], OBJ_TRAP_LIST + subval);
X}
X
X
X/* Places rubble at location y, x			-RAK-	*/
Xvoid place_rubble(y, x)
Xint y, x;
X{
X  register int cur_pos;
X  register cave_type *cave_ptr;
X
X  cur_pos = popt();
X  cave_ptr = &cave[y][x];
X  cave_ptr->tptr = cur_pos;
X  cave_ptr->fval = BLOCKED_FLOOR;
X  invcopy(&t_list[cur_pos], OBJ_RUBBLE);
X}
X
X
X/* Places a treasure (Gold or Gems) at given row, column -RAK-	*/
Xvoid place_gold(y, x)
Xint y, x;
X{
X  register int i, cur_pos;
X  register inven_type *t_ptr;
X
X  cur_pos = popt();
X  i = ((randint(dun_level+2)+2) / 2) - 1;
X  if (randint(OBJ_GREAT) == 1)
X    i += randint(dun_level+1);
X  if (i >= MAX_GOLD)
X    i = MAX_GOLD - 1;
X  cave[y][x].tptr = cur_pos;
X  invcopy(&t_list[cur_pos], OBJ_GOLD_LIST+i);
X  t_ptr = &t_list[cur_pos];
X  t_ptr->cost += (8L * (long)randint((int)t_ptr->cost)) + randint(8);
X  if (cave[y][x].cptr == 1)
X    msg_print ("You feel something roll beneath your feet.");
X}
X
X
X/* Returns the array number of a random object		-RAK-	*/
Xint get_obj_num(level)
Xint level;
X{
X  register int i, j;
X
X  if (level == 0)
X    i = randint(t_level[0]) - 1;
X  else
X    {
X      if (level >= MAX_OBJ_LEVEL)
X	level = MAX_OBJ_LEVEL;
X      else if (randint(OBJ_GREAT) == 1)
X	{
X	  level = level * MAX_OBJ_LEVEL / randint (MAX_OBJ_LEVEL) + 1;
X	  if (level > MAX_OBJ_LEVEL)
X	    level = MAX_OBJ_LEVEL;
X	}
X
X      /* This code has been added to make it slightly more likely to get the
X	 higher level objects.	Originally a uniform distribution over all
X	 objects less than or equal to the dungeon level.  This distribution
X	 makes a level n objects occur approx 2/n% of the time on level n,
X	 and 1/2n are 0th level. */
X
X      if (randint(2) == 1)
X	i = randint(t_level[level]) - 1;
X      else /* Choose three objects, pick the highest level. */
X	{
X	  i = randint(t_level[level]) - 1;
X	  j = randint(t_level[level]) - 1;
X	  if (i < j)
X	    i = j;
X	  j = randint(t_level[level]) - 1;
X	  if (i < j)
X	    i = j;
X	  j = object_list[sorted_objects[i]].level;
X	  if (j == 0)
X	    i = randint(t_level[0]) - 1;
X	  else
X	    i = randint(t_level[j]-t_level[j-1]) - 1 + t_level[j-1];
X	}
X    }
X  return(i);
X}
X
X
X/* Places an object at given row, column co-ordinate	-RAK-	*/
Xvoid place_object(y, x)
Xint y, x;
X{
X  register int cur_pos, tmp;
X
X  cur_pos = popt();
X  cave[y][x].tptr = cur_pos;
X  /* split this line up to avoid a reported compiler bug */
X  tmp = get_obj_num(dun_level);
X  invcopy(&t_list[cur_pos], sorted_objects[tmp]);
X  magic_treasure(cur_pos, dun_level);
X  if (cave[y][x].cptr == 1)
X    msg_print ("You feel something roll beneath your feet.");	/* -CJS- */
X}
X
X
X/* Allocates an object for tunnels and rooms		-RAK-	*/
Xvoid alloc_object(alloc_set, typ, num)
Xint (*alloc_set)();
Xint typ, num;
X{
X  register int i, j, k;
X
X  for (k = 0; k < num; k++)
X    {
X      do
X	{
X	  i = randint(cur_height) - 1;
X	  j = randint(cur_width) - 1;
X	}
X      /* don't put an object beneath the player, this could cause problems
X	 if player is standing under rubble, or on a trap */
X      while ((!(*alloc_set)(cave[i][j].fval)) ||
X	     (cave[i][j].tptr != 0) || (i == char_row && j == char_col));
X      if (typ < 4) {	/* typ == 2 not used, used to be visible traps */
X	if (typ == 1) place_trap(i, j, randint(MAX_TRAP)-1); /* typ == 1 */
X	else	      place_rubble(i, j); /* typ == 3 */
X      } else {
X	if (typ == 4) place_gold(i, j); /* typ == 4 */
X	else	      place_object(i, j); /* typ == 5 */
X      }
X    }
X}
X
X
X/* Creates objects nearby the coordinates given		-RAK-	*/
Xvoid random_object(y, x, num)
Xint y, x, num;
X{
X  register int i, j, k;
X  register cave_type *cave_ptr;
X
X  do
X    {
X      i = 0;
X      do
X	{
X	  j = y - 3 + randint(5);
X	  k = x - 4 + randint(7);
X	  cave_ptr = &cave[j][k];
X	  if ((cave_ptr->fval <= MAX_CAVE_FLOOR) && (cave_ptr->tptr == 0))
X	    {
X	      if (randint(100) < 75)
X		place_object(j, k);
X	      else
X		place_gold(j, k);
X	      i = 9;
X	    }
X	  i++;
X	}
X      while(i <= 10);
X      num--;
X    }
X  while (num != 0);
X}
X
X
X/* Converts stat num into string			-RAK-	*/
Xvoid cnv_stat(stat, out_val)
Xint8u stat;
Xchar *out_val;
X{
X  register int part1, part2;
X
X  if (stat > 18)
X    {
X      part1 = 18;
X      part2 = stat - 18;
X      if (part2 == 100)
X	(void) strcpy(out_val, "18/100");
X      else
X	(void) sprintf(out_val, " %2d/%02d", part1, part2);
X    }
X  else
X    (void) sprintf(out_val, "%6d", stat);
X}
X
X
X/* Print character stat in given row, column		-RAK-	*/
Xvoid prt_stat(stat)
Xint stat;
X{
X  stat_type out_val1;
X
X  cnv_stat(py.stats.use_stat[stat], out_val1);
X  put_buffer(stat_names[stat], 6+stat, STAT_COLUMN);
X  put_buffer (out_val1, 6+stat, STAT_COLUMN+6);
X}
X
X
X/* Print character info in given row, column		-RAK-	*/
X/* the longest title is 13 characters, so only pad to 13 */
Xvoid prt_field(info, row, column)
Xchar *info;
Xint row, column;
X{
X  put_buffer (&blank_string[BLANK_LENGTH-13], row, column);
X  put_buffer (info, row, column);
X}
X
X/* Print long number with header at given row, column */
Xstatic void prt_lnum(header, num, row, column)
Xchar *header;
Xint32 num;
Xint row, column;
X{
X  vtype out_val;
X
X  (void) sprintf(out_val, "%s: %6ld", header, num);
X  put_buffer(out_val, row, column);
X}
X
X/* Print number with header at given row, column	-RAK-	*/
Xstatic void prt_num(header, num, row, column)
Xchar *header;
Xint num, row, column;
X{
X  vtype out_val;
X
X  (void) sprintf(out_val, "%s: %6d", header, num);
X  put_buffer(out_val, row, column);
X}
X
X/* Print long number at given row, column */
Xstatic void prt_long(num, row, column)
Xint32 num;
Xint row, column;
X{
X  vtype out_val;
X
X  (void) sprintf(out_val, "%6ld", num);
X  put_buffer(out_val, row, column);
X}
X
X/* Print number at given row, column	-RAK-	*/
Xstatic void prt_int(num, row, column)
Xint num, row, column;
X{
X  vtype out_val;
X
X  (void) sprintf(out_val, "%6d", num);
X  put_buffer(out_val, row, column);
X}
X
X
X/* Adjustment for wisdom/intelligence				-JWT-	*/
Xint stat_adj(stat)
Xint stat;
X{
X  register int value;
X
X  value = py.stats.use_stat[stat];
X  if (value > 117)
X    return(7);
X  else if (value > 107)
X    return(6);
X  else if (value > 87)
X    return(5);
X  else if (value > 67)
X    return(4);
X  else if (value > 17)
X    return(3);
X  else if (value > 14)
X    return(2);
X  else if (value > 7)
X    return(1);
X  else
X    return(0);
X}
X
X
X/* Adjustment for charisma				-RAK-	*/
X/* Percent decrease or increase in price of goods		 */
Xint chr_adj()
X{
X  register int charisma;
X
X  charisma = py.stats.use_stat[A_CHR];
X  if (charisma > 117)
X    return(90);
X  else if (charisma > 107)
X    return(92);
X  else if (charisma > 87)
X    return(94);
X  else if (charisma > 67)
X    return(96);
X  else if (charisma > 18)
X    return(98);
X  else
X    switch(charisma)
X      {
X      case 18:	return(100);
X      case 17:	return(101);
X      case 16:	return(102);
X      case 15:	return(103);
X      case 14:	return(104);
X      case 13:	return(106);
X      case 12:	return(108);
X      case 11:	return(110);
X      case 10:	return(112);
X      case 9:  return(114);
X      case 8:  return(116);
X      case 7:  return(118);
X      case 6:  return(120);
X      case 5:  return(122);
X      case 4:  return(125);
X      case 3:  return(130);
X      default: return(100);
X      }
X}
X
X
X/* Returns a character's adjustment to hit points	 -JWT-	 */
Xint con_adj()
X{
X  register int con;
X
X  con = py.stats.use_stat[A_CON];
X  if (con < 7)
X    return(con - 7);
X  else if (con < 17)
X    return(0);
X  else if (con ==  17)
X    return(1);
X  else if (con <  94)
X    return(2);
X  else if (con < 117)
X    return(3);
X  else
X    return(4);
X}
X
X
Xchar *title_string()
X{
X  register char *p;
X
X  if (py.misc.lev < 1)
X    p = "Babe in arms";
X  else if (py.misc.lev <= MAX_PLAYER_LEVEL)
X    p = player_title[py.misc.pclass][py.misc.lev-1];
X  else if (py.misc.male)
X    p = "**KING**";
X  else
X    p = "**QUEEN**";
X  return p;
X}
X
X
X/* Prints title of character				-RAK-	*/
Xvoid prt_title()
X{
X  prt_field(title_string(), 4, STAT_COLUMN);
X}
X
X
X/* Prints level						-RAK-	*/
Xvoid prt_level()
X{
X  prt_int((int)py.misc.lev, 13, STAT_COLUMN+6);
X}
X
X
X/* Prints players current mana points.		 -RAK-	*/
Xvoid prt_cmana()
X{
X  prt_int(py.misc.cmana, 15, STAT_COLUMN+6);
X}
X
X
X/* Prints Max hit points				-RAK-	*/
Xvoid prt_mhp()
X{
X  prt_int(py.misc.mhp, 16, STAT_COLUMN+6);
X}
X
X
X/* Prints players current hit points			-RAK-	*/
Xvoid prt_chp()
X{
X  prt_int(py.misc.chp, 17, STAT_COLUMN+6);
X}
X
X
X/* prints current AC					-RAK-	*/
Xvoid prt_pac()
X{
X  prt_int(py.misc.dis_ac, 19, STAT_COLUMN+6);
X}
X
X
X/* Prints current gold					-RAK-	*/
Xvoid prt_gold()
X{
X  prt_long(py.misc.au, 20, STAT_COLUMN+6);
X}
X
X
X/* Prints depth in stat area				-RAK-	*/
Xvoid prt_depth()
X{
X  vtype depths;
X  register int depth;
X
X  depth = dun_level*50;
X  if (depth == 0)
X    (void) strcpy(depths, "Town level");
X  else
X    (void) sprintf(depths, "%d feet", depth);
X  prt(depths, 23, 65);
X}
X
X
X/* Prints status of hunger				-RAK-	*/
Xvoid prt_hunger()
X{
X  if (PY_WEAK & py.flags.status)
X    put_buffer("Weak  ", 23, 0);
X  else if (PY_HUNGRY & py.flags.status)
X    put_buffer("Hungry", 23, 0);
X  else
X    put_buffer(&blank_string[BLANK_LENGTH-6], 23, 0);
X}
X
X
X/* Prints Blind status					-RAK-	*/
Xvoid prt_blind()
X{
X  if (PY_BLIND & py.flags.status)
X    put_buffer("Blind", 23, 7);
X  else
X    put_buffer(&blank_string[BLANK_LENGTH-5], 23, 7);
X}
X
X
X/* Prints Confusion status				-RAK-	*/
Xvoid prt_confused()
X{
X  if (PY_CONFUSED & py.flags.status)
X    put_buffer("Confused", 23, 13);
X  else
X    put_buffer(&blank_string[BLANK_LENGTH-8], 23, 13);
X}
X
X
X/* Prints Fear status					-RAK-	*/
Xvoid prt_afraid()
X{
X  if (PY_FEAR & py.flags.status)
X    put_buffer("Afraid", 23, 22);
X  else
X    put_buffer(&blank_string[BLANK_LENGTH-6], 23, 22);
X}
X
X
X/* Prints Poisoned status				-RAK-	*/
Xvoid prt_poisoned()
X{
X  if (PY_POISONED & py.flags.status)
X    put_buffer("Poisoned", 23, 29);
X  else
X    put_buffer(&blank_string[BLANK_LENGTH-8], 23, 29);
X}
X
X
X/* Prints Searching, Resting, Paralysis, or 'count' status	-RAK-	*/
Xvoid prt_state()
X{
X  char tmp[16];
X
X  py.flags.status &= ~PY_REPEAT;
X  if (py.flags.paralysis > 1)
X    put_buffer ("Paralysed", 23, 38);
X  else if (PY_REST & py.flags.status)
X    {
X      (void) sprintf (tmp, "Rest %-5d", py.flags.rest);
X      put_buffer (tmp, 23, 38);
X    }
X  else if (command_count > 0)
X    {
X      (void) sprintf (tmp, "Repeat %-3d", command_count);
X      py.flags.status |= PY_REPEAT;
X      put_buffer (tmp, 23, 38);
X      if (PY_SEARCH & py.flags.status)
X	put_buffer ("Search", 23, 38);
X    }
X  else if (PY_SEARCH & py.flags.status)
X    put_buffer("Searching", 23, 38);
X  else		/* "repeat 999" is 10 characters */
X    put_buffer(&blank_string[BLANK_LENGTH-10], 23, 38);
X}
X
X
X/* Prints the speed of a character.			-CJS- */
Xvoid prt_speed ()
X{
X  register int i;
X
X  i = py.flags.speed;
X  if (PY_SEARCH & py.flags.status)   /* Search mode. */
X    i--;
X  if (i > 1)
X    put_buffer ("Very Slow", 23, 49);
X  else if (i == 1)
X    put_buffer ("Slow     ", 23, 49);
X  else if (i == 0)
X    put_buffer (&blank_string[BLANK_LENGTH-9], 23, 49);
X  else if (i == -1)
X    put_buffer ("Fast     ", 23, 49);
X  else
X    put_buffer ("Very Fast", 23, 49);
X}
X
X
Xvoid prt_study()
X{
X  py.flags.status &= ~PY_STUDY;
X  if (py.flags.new_spells == 0)
X    put_buffer (&blank_string[BLANK_LENGTH-5], 23, 59);
X  else
X    put_buffer ("Study", 23, 59);
X}
X
X
X/* Prints winner status on display			-RAK-	*/
Xvoid prt_winner()
X{
X  if (noscore & 0x2)
X    {
X      if (wizard)
X	put_buffer("Is wizard  ", 22, 0);
X      else
X	put_buffer("Was wizard ", 22, 0);
X    }
X  else if (noscore & 0x1)
X    put_buffer("Resurrected", 22, 0);
X  else if (total_winner)
X    put_buffer("*Winner*   ", 22, 0);
X}
X
X
Xint8u modify_stat (stat, amount)
Xint stat;
Xint16 amount;
X{
X  register int loop, i;
X  register int8u tmp_stat;
X
X  tmp_stat = py.stats.cur_stat[stat];
X  loop = (amount < 0 ? -amount : amount);
X  for (i = 0; i < loop; i++)
X    {
X      if (amount > 0)
X	{
X	  if (tmp_stat < 18)
X	    tmp_stat++;
X	  else if (tmp_stat < 108)
X	    tmp_stat += 10;
X	  else
X	    tmp_stat = 118;
X	}
X      else
X	{
X	  if (tmp_stat > 27)
X	    tmp_stat -= 10;
X	  else if (tmp_stat > 18)
X	    tmp_stat = 18;
X	  else if (tmp_stat > 3)
X	    tmp_stat--;
X	}
X    }
X  return tmp_stat;
X}
X
X
X/* Set the value of the stat which is actually used.	 -CJS- */
Xvoid set_use_stat(stat)
Xint stat;
X{
X  py.stats.use_stat[stat] = modify_stat (stat, py.stats.mod_stat[stat]);
X
X  if (stat == A_STR)
X    {
X      py.flags.status |= PY_STR_WGT;
X      calc_bonuses();
X    }
X  else if (stat == A_DEX)
X    calc_bonuses();
X  else if (stat == A_INT && class[py.misc.pclass].spell == MAGE)
X    {
X      calc_spells(A_INT);
X      calc_mana(A_INT);
X    }
X  else if (stat == A_WIS && class[py.misc.pclass].spell == PRIEST)
X    {
X      calc_spells(A_WIS);
X      calc_mana(A_WIS);
X    }
X  else if (stat == A_CON)
X    calc_hitpoints();
X}
X
X
X/* Increases a stat by one randomized level		-RAK-	*/
Xint inc_stat(stat)
Xregister int stat;
X{
X  register int tmp_stat, gain;
X
X  tmp_stat = py.stats.cur_stat[stat];
X  if (tmp_stat < 118)
X    {
X      if (tmp_stat < 18)
X	tmp_stat++;
X      else if (tmp_stat < 116)
X	{
X	  /* stat increases by 1/6 to 1/3 of difference from max */
X	  gain = ((118 - tmp_stat)/3 + 1) >> 1;
X	  tmp_stat += randint(gain) + gain;
X	}
X      else
X	tmp_stat++;
X
X      py.stats.cur_stat[stat] = tmp_stat;
X      if (tmp_stat > py.stats.max_stat[stat])
X	py.stats.max_stat[stat] = tmp_stat;
X      set_use_stat (stat);
X      prt_stat (stat);
X      return TRUE;
X    }
X  else
X    return FALSE;
X}
X
X
X/* Decreases a stat by one randomized level		-RAK-	*/
Xint dec_stat(stat)
Xregister int stat;
X{
X  register int tmp_stat, loss;
X
X  tmp_stat = py.stats.cur_stat[stat];
X  if (tmp_stat > 3)
X    {
X      if (tmp_stat < 19)
X	tmp_stat--;
X      else if (tmp_stat < 117)
X	{
X	  loss = (((118 - tmp_stat) >> 1) + 1) >> 1;
X	  tmp_stat += -randint(loss) - loss;
X	  if (tmp_stat < 18)
X	    tmp_stat = 18;
X	}
X      else
X	tmp_stat--;
X
X      py.stats.cur_stat[stat] = tmp_stat;
X      set_use_stat (stat);
X      prt_stat (stat);
X      return TRUE;
X    }
X  else
X    return FALSE;
X}
X
X
X/* Restore a stat.  Return TRUE only if this actually makes a difference. */
Xint res_stat (stat)
Xint stat;
X{
X  register int i;
X
X  i = py.stats.max_stat[stat] - py.stats.cur_stat[stat];
X  if (i)
X    {
X      py.stats.cur_stat[stat] += i;
X      set_use_stat (stat);
X      prt_stat (stat);
X      return TRUE;
X    }
X  return FALSE;
X}
X
X/* Boost a stat artificially (by wearing something). If the display argument
X   is TRUE, then increase is shown on the screen. */
Xvoid bst_stat (stat, amount)
Xint stat, amount;
X{
X  py.stats.mod_stat[stat] += amount;
X
X  set_use_stat (stat);
X  /* can not call prt_stat() here, may be in store, may be in inven_command */
X  py.flags.status |= (PY_STR << stat);
X}
X
X
X/* Returns a character's adjustment to hit.		 -JWT-	 */
Xint tohit_adj()
X{
X  register int total, stat;
X
X  stat = py.stats.use_stat[A_DEX];
X  if	  (stat <   4)	total = -3;
X  else if (stat <   6)	total = -2;
X  else if (stat <   8)	total = -1;
X  else if (stat <  16)	total =	 0;
X  else if (stat <  17)	total =	 1;
X  else if (stat <  18)	total =	 2;
X  else if (stat <  69)	total =	 3;
X  else if (stat < 118)	total =	 4;
X  else			total =	 5;
X  stat = py.stats.use_stat[A_STR];
X  if	  (stat <   4)	total -= 3;
X  else if (stat <   5)	total -= 2;
X  else if (stat <   7)	total -= 1;
X  else if (stat <  18)	total -= 0;
X  else if (stat <  94)	total += 1;
X  else if (stat < 109)	total += 2;
X  else if (stat < 117)	total += 3;
X  else			total += 4;
X  return(total);
X}
X
X
X/* Returns a character's adjustment to armor class	 -JWT-	 */
Xint toac_adj()
X{
X  register int stat;
X
X  stat = py.stats.use_stat[A_DEX];
X  if	  (stat <   4)	return(-4);
X  else if (stat ==  4)	return(-3);
X  else if (stat ==  5)	return(-2);
X  else if (stat ==  6)	return(-1);
X  else if (stat <  15)	return( 0);
X  else if (stat <  18)	return( 1);
X  else if (stat <  59)	return( 2);
X  else if (stat <  94)	return( 3);
X  else if (stat < 117)	return( 4);
X  else			return( 5);
X}
X
X
X/* Returns a character's adjustment to disarm		 -RAK-	 */
Xint todis_adj()
X{
X  register int stat;
X
X  stat = py.stats.use_stat[A_DEX];
X  if	  (stat <   3)	return(-8);
X  else if (stat ==  4)	return(-6);
X  else if (stat ==  5)	return(-4);
X  else if (stat ==  6)	return(-2);
X  else if (stat ==  7)	return(-1);
X  else if (stat <  13)	return( 0);
X  else if (stat <  16)	return( 1);
X  else if (stat <  18)	return( 2);
X  else if (stat <  59)	return( 4);
X  else if (stat <  94)	return( 5);
X  else if (stat < 117)	return( 6);
X  else			return( 8);
X}
X
X
X/* Returns a character's adjustment to damage		 -JWT-	 */
Xint todam_adj()
X{
X  register int stat;
X
X  stat = py.stats.use_stat[A_STR];
X  if	  (stat <   4)	return(-2);
X  else if (stat <   5)	return(-1);
X  else if (stat <  16)	return( 0);
X  else if (stat <  17)	return( 1);
X  else if (stat <  18)	return( 2);
X  else if (stat <  94)	return( 3);
X  else if (stat < 109)	return( 4);
X  else if (stat < 117)	return( 5);
X  else			return( 6);
X}
X
X
X/* Prints character-screen info				-RAK-	*/
Xvoid prt_stat_block()
X{
X  register int32u status;
X  register struct misc *m_ptr;
X  register int i;
X
X  m_ptr = &py.misc;
X  prt_field(race[py.misc.prace].trace,	  2, STAT_COLUMN);
X  prt_field(class[py.misc.pclass].title,  3, STAT_COLUMN);
X  prt_field(title_string(),		  4, STAT_COLUMN);
X  for (i = 0; i < 6; i++)
X    prt_stat (i);
X  prt_num ("LEV ", (int)m_ptr->lev,    13, STAT_COLUMN);
X  prt_lnum("EXP ", m_ptr->exp,	       14, STAT_COLUMN);
X  prt_num ("MANA", m_ptr->cmana,	 15, STAT_COLUMN);
X  prt_num ("MHP ", m_ptr->mhp,	       16, STAT_COLUMN);
X  prt_num ("CHP ", m_ptr->chp,	 17, STAT_COLUMN);
X  prt_num ("AC  ", m_ptr->dis_ac,      19, STAT_COLUMN);
X  prt_lnum("GOLD", m_ptr->au,	       20, STAT_COLUMN);
X  prt_winner();
X  status = py.flags.status;
X  if ((PY_HUNGRY|PY_WEAK) & status)
X    prt_hunger();
X  if (PY_BLIND & status)
X    prt_blind();
X  if (PY_CONFUSED & status)
X    prt_confused();
X  if (PY_FEAR & status)
X    prt_afraid();
X  if (PY_POISONED & status)
X    prt_poisoned();
X  if ((PY_SEARCH|PY_REST) & status)
X    prt_state ();
X  /* if speed non zero, print it, modify speed if Searching */
X  if (py.flags.speed - ((PY_SEARCH & status) >> 8) != 0)
X    prt_speed ();
X}
X
X
X/* Draws entire screen					-RAK-	*/
Xvoid draw_cave()
X{
X  clear_screen ();
X  prt_stat_block();
X  prt_map();
X  prt_depth();
X}
X
X
X/* Prints the following information on the screen.	-JWT-	*/
Xvoid put_character()
X{
X  register struct misc *m_ptr;
X
X  m_ptr = &py.misc;
X  clear_screen ();
X  put_buffer ("Name        :", 2, 1);
X  put_buffer ("Race        :", 3, 1);
X  put_buffer ("Sex         :", 4, 1);
X  put_buffer ("Class       :", 5, 1);
X  if (character_generated)
X    {
X      put_buffer (m_ptr->name, 2, 15);
X      put_buffer (race[m_ptr->prace].trace, 3, 15);
X      put_buffer ((m_ptr->male ? "Male" : "Female"), 4, 15);
X      put_buffer (class[m_ptr->pclass].title, 5, 15);
X    }
X}
X
X
X/* Prints the following information on the screen.	-JWT-	*/
Xvoid put_stats()
X{
X  register struct misc *m_ptr;
X  register int i;
X  vtype buf;
X
X  m_ptr = &py.misc;
X  for (i = 0; i < 6; i++)
X    {
X      cnv_stat (py.stats.use_stat[i], buf);
X      put_buffer (stat_names[i], 2+i, 61);
X      put_buffer (buf, 2+i, 66);
X      if (py.stats.max_stat[i] > py.stats.cur_stat[i])
X	{
X	  cnv_stat (py.stats.max_stat[i], buf);
X	  put_buffer (buf, 2+i, 73);
X	}
X    }
X  prt_num("+ To Hit    ", m_ptr->dis_th,  9, 1);
X  prt_num("+ To Damage ", m_ptr->dis_td, 10, 1);
X  prt_num("+ To AC     ", m_ptr->dis_tac, 11, 1);
X  prt_num("  Total AC  ", m_ptr->dis_ac, 12, 1);
X}
X
X
X/* Returns a rating of x depending on y			-JWT-	*/
Xchar *likert(x, y)
Xint x, y;
X{
X  switch((x/y))
X    {
X      case -3: case -2: case -1: return("Very Bad");
X      case 0: case 1:		 return("Bad");
X      case 2:			 return("Poor");
X      case 3: case 4:		 return("Fair");
X      case  5:			 return("Good");
X      case 6:			 return("Very Good");
X      case 7: case 8:		 return("Excellent");
X      default:			 return("Superb");
X      }
X}
X
X
X/* Prints age, height, weight, and SC			-JWT-	*/
Xvoid put_misc1()
X{
X  register struct misc *m_ptr;
X
X  m_ptr = &py.misc;
X  prt_num("Age          ", (int)m_ptr->age, 2, 38);
X  prt_num("Height       ", (int)m_ptr->ht, 3, 38);
X  prt_num("Weight       ", (int)m_ptr->wt, 4, 38);
X  prt_num("Social Class ", (int)m_ptr->sc, 5, 38);
X}
X
X
X/* Prints the following information on the screen.	-JWT-	*/
Xvoid put_misc2()
X{
X  register struct misc *m_ptr;
X
X  m_ptr = &py.misc;
X  prt_num("Level      ", (int)m_ptr->lev, 9, 29);
X  prt_lnum("Experience ", m_ptr->exp, 10, 29);
X  prt_lnum("Max Exp    ", m_ptr->max_exp, 11, 29);
X  prt_lnum("Exp to Adv.", (int32)(player_exp[m_ptr->lev-1] *
X				  m_ptr->expfact/100), 12, 29);
X  prt_lnum("Gold       ", m_ptr->au, 13, 29);
X  prt_num("Max Hit Points ", m_ptr->mhp, 9, 52);
X  prt_num("Cur Hit Points ", m_ptr->chp, 10, 52);
X  prt_num("Max Mana       ", m_ptr->mana, 11, 52);
X  prt_num("Cur Mana       ", m_ptr->cmana, 12, 52);
X}
X
X
X/* Prints ratings on certain abilities			-RAK-	*/
Xvoid put_misc3()
X{
X  int xbth, xbthb, xfos, xsrh, xstl, xdis, xsave, xdev;
X  vtype xinfra;
X  register struct misc *p_ptr;
X
X  clear_from(13);
X  p_ptr = &py.misc;
X  xbth	= p_ptr->bth + p_ptr->ptohit*BTH_PLUS_ADJ
X    + (class_level_adj[p_ptr->pclass][CLA_BTH] * p_ptr->lev);
X  xbthb = p_ptr->bthb + p_ptr->ptohit*BTH_PLUS_ADJ
X    + (class_level_adj[p_ptr->pclass][CLA_BTHB] * p_ptr->lev);
X  /* this results in a range from 0 to 29 */
X  xfos	= 40 - p_ptr->fos;
X  if (xfos < 0)	 xfos = 0;
X  xsrh	= p_ptr->srh;
X  /* this results in a range from 0 to 9 */
X  xstl	= p_ptr->stl + 1;
X  xdis	= p_ptr->disarm + 2*todis_adj() + stat_adj(A_INT)
X    + (class_level_adj[p_ptr->pclass][CLA_DISARM] * p_ptr->lev / 3);
X  xsave = p_ptr->save + stat_adj(A_WIS)
X    + (class_level_adj[p_ptr->pclass][CLA_SAVE] * p_ptr->lev / 3);
X  xdev	= p_ptr->save + stat_adj(A_INT)
X    + (class_level_adj[p_ptr->pclass][CLA_DEVICE] * p_ptr->lev / 3);
X    
X  (void) sprintf(xinfra, "%d feet", py.flags.see_infra*10);
X
X  put_buffer ("(Miscellaneous Abilities)", 15, 25);
X  put_buffer ("Fighting    :", 16, 1);
X  put_buffer (likert (xbth, 12), 16, 15);
X  put_buffer ("Bows/Throw  :", 17, 1);
X  put_buffer (likert (xbthb, 12), 17, 15);
X  put_buffer ("Saving Throw:", 18, 1);
X  put_buffer (likert (xsave, 6), 18, 15);
X
X  put_buffer ("Stealth     :", 16, 28);
X  put_buffer (likert (xstl, 1), 16, 42);
X  put_buffer ("Disarming   :", 17, 28);
X  put_buffer (likert (xdis, 8), 17, 42);
X  put_buffer ("Magic Device:", 18, 28);
X  put_buffer (likert (xdev, 6), 18, 42);
X
X  put_buffer ("Perception  :", 16, 55);
X  put_buffer (likert (xfos, 3), 16, 69);
X  put_buffer ("Searching   :", 17, 55);
X  put_buffer (likert (xsrh, 6), 17, 69);
X  put_buffer ("Infra-Vision:", 18, 55);
X  put_buffer (xinfra, 18, 69);
X}
X
X
X/* Used to display the character on the screen.		-RAK-	*/
Xvoid display_char()
X{
X  put_character();
X  put_misc1();
X  put_stats();
X  put_misc2();
X  put_misc3();
X}
X
X
X/* Gets a name for the character			-JWT-	*/
Xvoid get_name()
X{
X  prt("Enter your player's name  [press <RETURN> when finished]", 21, 2);
X  put_buffer (&blank_string[BLANK_LENGTH-23], 2, 15);
X#ifdef MAC
X  /* Force player to give a name, would be nice to get name from chooser
X     (STR -16096), but that name might be too long */
X  while (!get_string(py.misc.name, 2, 15, 23) || py.misc.name[0] == 0);
X#else
X  if (!get_string(py.misc.name, 2, 15, 23) || py.misc.name[0] == 0)
X    {
X      user_name (py.misc.name);
X      put_buffer (py.misc.name, 2, 15);
X    }
X#endif
X  clear_from (20);
X#ifdef MAC
X  /* Use the new name to set save file default name. */
X  initsavedefaults();
X#endif
X}
X
X
X/* Changes the name of the character			-JWT-	*/
Xvoid change_name()
X{
X  register char c;
X  register int flag;
X#ifndef MAC
X  vtype temp;
X#endif
X
X  flag = FALSE;
X  display_char();
X  do
X    {
X      prt( "<f>ile character description. <c>hange character name.", 21, 2);
X      c = inkey();
X      switch(c)
X	{
X	case 'c':
X	  get_name();
X	  flag = TRUE;
X	  break;
X	case 'f':
X#ifdef MAC
X	  /* On mac, file_character() gets filename with std file dialog. */
X	  if (file_character ())
X	    flag = TRUE;
X#else
X	  prt ("File name:", 0, 0);
X	  if (get_string (temp, 0, 10, 60) && temp[0])
X	    if (file_character (temp))
X	      flag = TRUE;
X#endif
X	  break;
X	case ESCAPE: case ' ':
X	case '\n': case '\r':
X	  flag = TRUE;
X	  break;
X	default:
X	  bell ();
X	  break;
X	}
X    }
X  while (!flag);
X}
X
X
X/* Destroy an item in the inventory			-RAK-	*/
Xvoid inven_destroy(item_val)
Xint item_val;
X{
X  register int j;
X  register inven_type *i_ptr;
X
X  i_ptr = &inventory[item_val];
X  if ((i_ptr->number > 1) && (i_ptr->subval <= ITEM_SINGLE_STACK_MAX))
X    {
X      i_ptr->number--;
X      inven_weight -= i_ptr->weight;
X    }
X  else
X    {
X      inven_weight -= i_ptr->weight*i_ptr->number;
X      for (j = item_val; j < inven_ctr-1; j++)
X	inventory[j] = inventory[j+1];
X      invcopy(&inventory[inven_ctr-1], OBJ_NOTHING);
X      inven_ctr--;
X    }
X  py.flags.status |= PY_STR_WGT;
X}
X
X
X/* Copies the object in the second argument over the first argument.
X   However, the second always gets a number of one except for ammo etc. */
Xvoid take_one_item (s_ptr, i_ptr)
Xregister inven_type *s_ptr, *i_ptr;
X{
X  *s_ptr = *i_ptr;
X  if ((s_ptr->number > 1) && (s_ptr->subval >= ITEM_SINGLE_STACK_MIN)
X      && (s_ptr->subval <= ITEM_SINGLE_STACK_MAX))
X    s_ptr->number = 1;
X}
X
X
X/* Drops an item from inventory to given location	-RAK-	*/
Xvoid inven_drop(item_val, drop_all)
Xregister int item_val, drop_all;
X{
X  int i;
X  register inven_type *i_ptr;
X  vtype prt2;
X  bigvtype prt1;
X
X  if (cave[char_row][char_col].tptr != 0)
X    (void) delete_object(char_row, char_col);
X  i = popt ();
X  i_ptr = &inventory[item_val];
X  t_list[i] = *i_ptr;
X  cave[char_row][char_col].tptr = i;
X
X  if (item_val >= INVEN_WIELD)
X    takeoff (item_val, -1);
X  else
X    {
X      if (drop_all || i_ptr->number == 1)
X	{
X	  inven_weight -= i_ptr->weight*i_ptr->number;
X	  inven_ctr--;
X	  while (item_val < inven_ctr)
X	    {
X	      inventory[item_val] = inventory[item_val+1];
X	      item_val++;
X	    }
X	  invcopy(&inventory[inven_ctr], OBJ_NOTHING);
X	}
X      else
X	{
X	  t_list[i].number = 1;
X	  inven_weight -= i_ptr->weight;
X	  i_ptr->number--;
X	}
X      objdes (prt1, &t_list[i], TRUE);
X      (void) sprintf (prt2, "Dropped %s", prt1);
X      msg_print (prt2);
X    }
X  py.flags.status |= PY_STR_WGT;
X}
X
X
X/* Destroys a type of item on a given percent chance	-RAK-	*/
Xint inven_damage(typ, perc)
Xint (*typ)();
Xregister int perc;
X{
X  register int i, j;
X
X  j = 0;
X  for (i = 0; i < inven_ctr; i++)
X    if ((*typ)(inventory[i].tval) && (randint(100) < perc))
X      {
X	inven_destroy(i);
X	j++;
X      }
X  return(j);
X}
X
X
X/* Computes current weight limit			-RAK-	*/
Xint weight_limit()
X{
X  register int weight_cap;
X
X  weight_cap = py.stats.use_stat[A_STR] * PLAYER_WEIGHT_CAP + py.misc.wt;
X  if (weight_cap > 3000)  weight_cap = 3000;
X  return(weight_cap);
X}
X
X
X/* this code must be identical to the inven_carry() code below */
Xint inven_check_num (t_ptr)
Xregister inven_type *t_ptr;
X{
X  register int i;
X
X  if (inven_ctr < INVEN_WIELD)
X    return TRUE;
X  else if (t_ptr->subval >= ITEM_SINGLE_STACK_MIN)
X    for (i = 0; i < inven_ctr; i++)
X      if (inventory[i].tval == t_ptr->tval &&
X	  inventory[i].subval == t_ptr->subval &&
X	  /* make sure the number field doesn't overflow */
X	  ((int)inventory[i].number + (int)t_ptr->number < 256) &&
X	  /* they always stack (subval < 192), or else they have same p1 */
X	  ((t_ptr->subval < ITEM_GROUP_MIN) || (inventory[i].p1 == t_ptr->p1))
X	  /* only stack if both or neither are identified */
X	  && (known1_p(&inventory[i]) == known1_p(t_ptr)))
X	return TRUE;
X  return FALSE;
X}
X
X/* return FALSE if picking up an object would change the players speed */ 
Xint inven_check_weight(i_ptr)
Xregister inven_type *i_ptr;
X{
X  register int i, new_inven_weight;
X
X  i = weight_limit();
X  new_inven_weight = i_ptr->number*i_ptr->weight + inven_weight;
X  if (i < new_inven_weight)
X    i = new_inven_weight / (i + 1);
X  else
X    i = 0;
X
X  if (pack_heavy != i)
X    return FALSE;
X  else
X    return TRUE;
X}
X
X
X/* Are we strong enough for the current pack and weapon?  -CJS-	 */
Xvoid check_strength()
X{
X  register int i;
X  register inven_type *i_ptr;
X
X  i_ptr = &inventory[INVEN_WIELD];
X  if (i_ptr->tval != TV_NOTHING
X      && (py.stats.use_stat[A_STR]*15 < i_ptr->weight))
X    {
X      if (weapon_heavy == FALSE)
X	{
X	  msg_print("You have trouble wielding such a heavy weapon.");
X	  weapon_heavy = TRUE;
X	  calc_bonuses();
X	}
X    }
X  else if (weapon_heavy == TRUE)
X    {
X      weapon_heavy = FALSE;
X      if (i_ptr->tval != TV_NOTHING)
X	msg_print("You are strong enough to wield your weapon.");
X      calc_bonuses();
X    }
X  i = weight_limit();
X  if (i < inven_weight)
X    i = inven_weight / (i+1);
X  else
X    i = 0;
X  if (pack_heavy != i)
X    {
X      if (pack_heavy < i)
X	msg_print("Your pack is so heavy that it slows you down.");
X      else
X	msg_print("You move more easily under the weight of your pack.");
X      change_speed(i - pack_heavy);
X      pack_heavy = i;
X    }
X  py.flags.status &= ~PY_STR_WGT;
X}
X
X
X/* Add an item to players inventory.  Return the	*/
X/* item position for a description if needed.	       -RAK-   */
X/* this code must be identical to the inven_check_num() code above */
Xint inven_carry(i_ptr)
Xregister inven_type *i_ptr;
X{
X  register int locn, i;
X  register int typ, subt;
X  register inven_type *t_ptr;
X
X  typ = i_ptr->tval;
X  subt = i_ptr->subval;
X  /* Now, check to see if player can carry object  */
X  for (locn = 0; ; locn++)
X    {
X      t_ptr = &inventory[locn];
X      if ((typ == t_ptr->tval) && (subt == t_ptr->subval)
X	  && (subt >= ITEM_SINGLE_STACK_MIN) &&
X	  ((int)t_ptr->number + (int)i_ptr->number < 256) &&
X	  ((subt < ITEM_GROUP_MIN) || (t_ptr->p1 == i_ptr->p1)) &&	
X	  /* only stack if both or neither are identified */
X	  (known1_p(i_ptr) == known1_p(t_ptr)))
X	{
X	  t_ptr->number += i_ptr->number;
X	  break;
X	}
X      else if (typ > t_ptr->tval)
X	{
X	  for (i = inven_ctr - 1; i >= locn; i--)
X	    inventory[i+1] = inventory[i];
X	  inventory[locn] = *i_ptr;
X	  inven_ctr++;
X	  break;
X	}
X    }
X
X  inven_weight += i_ptr->number*i_ptr->weight;
X  py.flags.status |= PY_STR_WGT;
X  return locn;
X}
X
X
X/* Returns spell chance of failure for spell		-RAK-	*/
Xint spell_chance(spell)
Xint spell;
X{
X  register spell_type *s_ptr;
X  register int chance;
X  register int stat;
X
X  s_ptr = &magic_spell[py.misc.pclass-1][spell];
X  chance = s_ptr->sfail - 3*(py.misc.lev-s_ptr->slevel);
X  if (class[py.misc.pclass].spell == MAGE)
X    stat = A_INT;
X  else
X    stat = A_WIS;
X  chance -= 3 * (stat_adj(stat)-1);
X  if (s_ptr->smana > py.misc.cmana)
X    chance += 5 * (s_ptr->smana-py.misc.cmana);
X  if (chance > 95)
X    chance = 95;
X  else if (chance < 5)
X    chance = 5;
X  return chance;
X}
X
X
X/* Print list of spells					-RAK-	*/
X/* if nonconsec is -1: spells numbered consecutively from 'a' to 'a'+num
X                  >=0: spells numbered by offset from nonconsec */
Xvoid print_spells(spell, num, comment, nonconsec)
Xint *spell;
Xregister int num;
Xint comment, nonconsec;
X{
X  register int i, j;
X  vtype out_val;
X  register spell_type *s_ptr;
X  int col, offset;
X  char *p;
X  char spell_char;
X
X  if (comment)
X    col = 22;
X  else
X    col = 31;
X  offset = (class[py.misc.pclass].spell==MAGE ? SPELL_OFFSET : PRAYER_OFFSET);
X  erase_line(1, col);
X  put_buffer("Name", 1, col+5);
X  put_buffer("Lv Mana Fail", 1, col+35);
X  /* only show the first 22 choices */
X  if (num > 22)
X    num = 22;
X  for (i = 0; i < num; i++)
X    {
X      j = spell[i];
X      s_ptr = &magic_spell[py.misc.pclass-1][j];
X      if (comment == FALSE)
X	p = "";
X      else if ((spell_forgotten & (1L << j)) != 0)
X	p = " forgotten";
X      else if ((spell_learned & (1L << j)) == 0)
X	p = " unknown";
X      else if ((spell_worked & (1L << j)) == 0)
X	p = " untried";
X      else
X	p = "";
X      /* determine whether or not to leave holes in character choices,
X	 nonconsec -1 when learning spells, consec offset>=0 when asking which
X	 spell to cast */
X      if (nonconsec == -1)
X	spell_char = 'a' + i;
X      else
X	spell_char = 'a' + j - nonconsec;
X      (void) sprintf(out_val, "  %c) %-30s%2d %4d %3d%%%s", spell_char,
X		     spell_names[j+offset], s_ptr->slevel, s_ptr->smana,
X		     spell_chance (j), p);
X      prt(out_val, 2+i, col);
X    }
X}
X
X
X/* Returns spell pointer				-RAK-	*/
Xint get_spell(spell, num, sn, sc, prompt, first_spell)
Xint *spell;
Xregister int num;
Xregister int *sn, *sc;
Xchar *prompt;
Xint first_spell;
X{
X  register spell_type *s_ptr;
X  int flag, redraw, offset, i;
X  char choice;
X  vtype out_str, tmp_str;
X
X  *sn = -1;
X  flag = FALSE;
X  (void) sprintf(out_str, "(Spells %c-%c, *=List, <ESCAPE>=exit) %s",
X		 spell[0]+'a'-first_spell, spell[num-1]+'a'-first_spell,
X		 prompt);
X  redraw = FALSE;
X  offset = (class[py.misc.pclass].spell==MAGE ? SPELL_OFFSET : PRAYER_OFFSET);
X  while (flag == FALSE && get_com (out_str, &choice))
X    {
X      if (isupper((int)choice))
X	{
X	  *sn = choice-'A'+first_spell;
X	  /* verify that this is in spell[], at most 22 entries in spell[] */
X	  for (i = 0; i < num; i++)
X	    if (*sn == spell[i])
X	      break;
X	  if (i == num)
X	    *sn = -2;
X	  else
X	    {
X	      s_ptr = &magic_spell[py.misc.pclass-1][*sn];
X	      (void) sprintf (tmp_str, "Cast %s (%d mana, %d%% fail)?",
X			      spell_names[*sn+offset], s_ptr->smana,
X			      spell_chance (*sn));
X	      if (get_check (tmp_str))
X		flag = TRUE;
X	      else
X		*sn = -1;
X	    }
X	}
X      else if (islower((int)choice))
X	{
X	  *sn = choice-'a'+first_spell;
X	  /* verify that this is in spell[], at most 22 entries in spell[] */
X	  for (i = 0; i < num; i++)
X	    if (*sn == spell[i])
X	      break;
X	  if (i == num)
X	    *sn = -2;
X	  else
X	    flag = TRUE;
X	}
X      else if (choice == '*')
X	{
X	  /* only do this drawing once */
X	  if (!redraw)
X	    {
X	      save_screen ();
X	      redraw = TRUE;
X	      print_spells (spell, num, FALSE, first_spell);
X	    }
X	}
X      else if (isalpha((int)choice))
X	*sn = -2;
X      else
X	{
X	  *sn = -1;
X	  bell();
X	}
X      if (*sn == -2)
X	msg_print("You don't know that spell.");
X    }
X  if (redraw)
X    restore_screen ();
X
X  erase_line(MSG_LINE, 0);
X  if (flag)
X    *sc = spell_chance (*sn);
X
X  return(flag);
X}
X
X
X/* calculate number of spells player should have, and learn forget spells
X   until that number is met -JEW- */
Xvoid calc_spells(stat)
Xint stat;
X{
X  register int i;
X  register int32u mask;
X  int32u spell_flag;
X  int j, offset;
X  int num_allowed, new_spells, num_known, levels;
X  vtype tmp_str;
X  char *p;
X  register struct misc *p_ptr;
X  register spell_type *msp_ptr;
X
X  p_ptr = &py.misc;
X  msp_ptr = &magic_spell[p_ptr->pclass-1][0];
X  if (stat == A_INT)
X    {
X      p = "spell";
X      offset = SPELL_OFFSET;
X    }
X  else
X    {
X      p = "prayer";
X      offset = PRAYER_OFFSET;
X    }
X
X  /* check to see if know any spells greater than level, eliminate them */
X  for (i = 31, mask = 0x80000000; mask; mask >>= 1, i--)
X    if (mask & spell_learned)
X      {
X	if (msp_ptr[i].slevel > p_ptr->lev)
X	  {
X	    spell_learned &= ~mask;
X	    spell_forgotten |= mask;
X	    (void) sprintf(tmp_str, "You have forgotten the %s of %s.", p,
X			   spell_names[i+offset]);
X	    msg_print(tmp_str);
X	  }
X	else
X	  break;
X      }
X
X  /* calc number of spells allowed */
X  levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1;
X  switch(stat_adj(stat))
X    {
X    case 0:		    num_allowed = 0; break;
X    case 1: case 2: case 3: num_allowed = 1 * levels; break;
X    case 4: case 5:	    num_allowed = 3 * levels / 2; break;
X    case 6:		    num_allowed = 2 * levels; break;
X    case 7:		    num_allowed = 5 * levels / 2; break;
X    }
X
X  num_known = 0;
X  for (mask = 0x1; mask; mask <<= 1)
X    if (mask & spell_learned)
X      num_known++;
X  new_spells = num_allowed - num_known;
X
X  if (new_spells > 0)
X    {
X      /* remember forgotten spells while forgotten spells exist of new_spells
X	 positive, remember the spells in the order that they were learned */
X      for (i = 0; (spell_forgotten && new_spells
X		   && (i < num_allowed) && (i < 32)); i++)
X	{
X	  /* j is (i+1)th spell learned */
X	  j = spell_order[i];
X	  /* shifting by amounts greater than number of bits in long gives
X	     an undefined result, so don't shift for unknown spells */
X	  if (j == 99)
X	    mask = 0x0;
X	  else
X	    mask = 1L << j;
X	  if (mask & spell_forgotten)
X	    {
X	      if (msp_ptr[j].slevel <= p_ptr->lev)
X		{
X		  new_spells--;
X		  spell_forgotten &= ~mask;
X		  spell_learned |= mask;
X		  (void) sprintf(tmp_str, "You have remembered the %s of %s.",
X				 p, spell_names[j+offset]);
X		  msg_print(tmp_str);
X		}
X	      else
X		num_allowed++;
X	    }
X	}
X
X      if (new_spells > 0)
X	{
X	  /* determine which spells player can learn */
X	  /* must check all spells here, in gain_spell() we actually check
X	     if the books are present */
X	  spell_flag = 0x7FFFFFFFL & ~spell_learned;
X
X	  mask = 0x1;
X	  i = 0;
X	  for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++)
X	    if (spell_flag & mask)
X	      {
X		spell_flag &= ~mask;
X		if (msp_ptr[j].slevel <= p_ptr->lev)
X		  i++;
X	      }
X
X	  if (new_spells > i)
X	    new_spells = i;
X	}
X    }
X  else if (new_spells < 0)
X    {
X      /* forget spells until new_spells zero or no more spells know, spells
X	 are forgotten in the opposite order that they were learned */
X      for (i = 31; new_spells && spell_learned; i--)
X	{
X	  /* j is the (i+1)th spell learned */
X	  j = spell_order[i];
X	  /* shifting by amounts greater than number of bits in long gives
X	     an undefined result, so don't shift for unknown spells */
X	  if (j == 99)
X	    mask = 0x0;
X	  else
X	    mask = 1L << j;
X	  if (mask & spell_learned)
X	    {
X	      spell_learned &= ~mask;
X	      spell_forgotten |= mask;
X	      new_spells++;
X	      (void) sprintf(tmp_str, "You have forgotten the %s of %s.", p,
X			     spell_names[j+offset]);
X	      msg_print(tmp_str);
X	    }
X	}
X
X      new_spells = 0;
X    }
X
X  if (new_spells != py.flags.new_spells)
X    {
X      if (new_spells > 0 && py.flags.new_spells == 0)
X	{
X	  (void) sprintf(tmp_str, "You can learn some new %ss now.", p);
X	  msg_print(tmp_str);
X	}
X
X      py.flags.new_spells = new_spells;
X      py.flags.status |= PY_STUDY;
X    }
X}
X
X
X/* gain spells when player wants to		- jw */
Xvoid gain_spells()
X{
X  char query;
X  int stat, diff_spells, new_spells;
X  int spells[31], offset, last_known;
X  register int i, j;
X  register int32u spell_flag, mask;
X  vtype tmp_str;
X  struct misc *p_ptr;
X  register spell_type *msp_ptr;
X
X  i = 0;
X  if (py.flags.blind > 0)
X    msg_print("You can't see to read your spell book!");
X  else if (no_light())
X    msg_print("You have no light to read by.");
X  else if (py.flags.confused > 0)
X    msg_print("You are too confused.");
X  else
X    i = 1;
X  if (i == 0)
X    return;
X
X  new_spells = py.flags.new_spells;
X  diff_spells = 0;
X  p_ptr = &py.misc;
X  msp_ptr = &magic_spell[p_ptr->pclass-1][0];
X  if (class[p_ptr->pclass].spell == MAGE)
X    {
X      stat = A_INT;
X      offset = SPELL_OFFSET;
X    }
X  else
X    {
X      stat = A_WIS;
X      offset = PRAYER_OFFSET;
X    }
X
X  for (last_known = 0; last_known < 32; last_known++)
X    if (spell_order[last_known] == 99)
X      break;
X
X  if (!new_spells)
X    {
X      (void) sprintf(tmp_str, "You can't learn any new %ss!",
X		     (stat == A_INT ? "spell" : "prayer"));
X      msg_print(tmp_str);
X      free_turn_flag = TRUE;
X    }
X  else
X    {
X      /* determine which spells player can learn */
X      /* mages need the book to learn a spell, priests do not need the book */
X      if (stat == A_INT)
X	{
X	  spell_flag = 0;
X	  for (i = 0; i < inven_ctr; i++)
X	    if (((stat == A_INT) && (inventory[i].tval == TV_MAGIC_BOOK))
X		|| ((stat == A_WIS) && (inventory[i].tval == TV_PRAYER_BOOK)))
X	      spell_flag |= inventory[i].flags;
X	}
X      else
X	spell_flag = 0x7FFFFFFF;
X
X      /* clear bits for spells already learned */
X      spell_flag &= ~spell_learned;
X      
X      mask = 0x1;
X      i = 0;
X      for (j = 0, mask = 0x1; spell_flag; mask <<= 1, j++)
X	if (spell_flag & mask)
X	  {
X	    spell_flag &= ~mask;
X	    if (msp_ptr[j].slevel <= p_ptr->lev)
X	      {
X		spells[i] = j;
X		i++;
X	      }
X	  }
X      
X      if (new_spells > i)
X	{
X	  msg_print("You seem to be missing a book.");
X	  diff_spells = new_spells - i;
X	  new_spells = i;
X	}
X      if (new_spells == 0)
X	;
X      else if (stat == A_INT)
X	{
X	  /* get to choose which mage spells will be learned */
X	  save_screen();
X	  print_spells (spells, i, FALSE, -1);
X	  while (new_spells && get_com ("Learn which spell?", &query))
X	    {
X	      j = query - 'a';
X	      /* test j < 23 in case i is greater than 22, only 22 spells
X		 are actually shown on the screen, so limit choice to those */
X	      if (j >= 0 && j < i && j < 22)
X		{
X		  new_spells--;
X		  spell_learned |= 1L << spells[j];
X		  spell_order[last_known++] = spells[j];
X		  for (; j <= i-1; j++)
X		    spells[j] = spells[j+1];
X		  i--;
X		  erase_line (j+1, 31);
X		  print_spells (spells, i, FALSE, -1);
X		}
X	      else
X		bell();
X	    }
X	  restore_screen();
X	}
X      else
X	{
X	  /* pick a prayer at random */
X	  while (new_spells)
X	    {
X	      j = randint(i) - 1;
X	      spell_learned |= 1L << spells[j];
X	      spell_order[last_known++] = spells[j];
X	      (void) sprintf (tmp_str,
X			      "You have learned the prayer of %s.",
X			      spell_names[spells[j]+offset]);
X	      msg_print(tmp_str);
X	      for (; j <= i-1; j++)
X		spells[j] = spells[j+1];
X	      i--;
X	      new_spells--;
X	    }
X	}
X      py.flags.new_spells = new_spells + diff_spells;
X      if (py.flags.new_spells == 0)
X	py.flags.status |= PY_STUDY;
X      /* set the mana for first level characters when they learn first spell */
X      if (py.misc.mana == 0)
X	calc_mana(stat);
X    }
X}
X
X
X/* Gain some mana if you know at least one spell	-RAK-	*/
Xvoid calc_mana(stat)
Xint stat;
X{
X  register int new_mana, levels;
X  register struct misc *p_ptr;
X  register int32 value;
X
X  p_ptr = &py.misc;
X  if (spell_learned != 0)
X    {
X      levels = p_ptr->lev - class[p_ptr->pclass].first_spell_lev + 1;
X      switch(stat_adj(stat))
X	{
X	case 0: new_mana = 0; break;
X	case 1: case 2: new_mana = 1 * levels; break;
X	case 3: new_mana = 3 * levels / 2; break;
X	case 4: new_mana = 2 * levels; break;
X	case 5: new_mana = 5 * levels / 2; break;
X	case 6: new_mana = 3 * levels; break;
X	case 7: new_mana = 4 * levels; break;
X	}
X      /* increment mana by one, so that first level chars have 2 mana */
X      if (new_mana > 0)
X	new_mana++;
X
X      /* mana can be zero when creating character */
X      if (p_ptr->mana != new_mana)
X	{
X	  if (p_ptr->mana != 0)
X	    {
X	      /* change current mana proportionately to change of max mana,
X		 divide first to avoid overflow, little loss of accuracy */
X	      value = (((long)p_ptr->cmana << 16) + p_ptr->cmana_frac)
X		/ p_ptr->mana * new_mana;
X	      p_ptr->cmana = value >> 16;
X	      p_ptr->cmana_frac = value & 0xFFFF;
X	    }
X	  else
X	    {
X	      p_ptr->cmana = new_mana;
X	      p_ptr->cmana_frac = 0;
X	    }
X	  p_ptr->mana = new_mana;
X	  /* can't print mana here, may be in store or inventory mode */
X	  py.flags.status |= PY_MANA;
X	}
X    }
X  else if (p_ptr->mana != 0)
X    {
X      p_ptr->mana = 0;
X      p_ptr->cmana = 0;
X      /* can't print mana here, may be in store or inventory mode */
X      py.flags.status |= PY_MANA;
X    }
X}
X
X
X/* Increases hit points and level			-RAK-	*/
Xstatic void gain_level()
X{
X  register int32 dif_exp, need_exp;
X  vtype out_val;
X  register struct misc *p_ptr;
X  register class_type *c_ptr;
X
X  p_ptr = &py.misc;
X  p_ptr->lev++;
X  (void) sprintf(out_val, "Welcome to level %d.", (int)p_ptr->lev);
X  msg_print(out_val);
X  calc_hitpoints();
X
X  need_exp = player_exp[p_ptr->lev-1] * p_ptr->expfact / 100;
X  if (p_ptr->exp > need_exp)
X    {
X      /* lose some of the 'extra' exp when gain a level */
X      dif_exp = p_ptr->exp - need_exp;
X      p_ptr->exp = need_exp + (dif_exp / 2);
X    }
X  prt_level();
X  prt_title();
X  c_ptr = &class[p_ptr->pclass];
X  if (c_ptr->spell == MAGE)
X    {
X      calc_spells(A_INT);
X      calc_mana(A_INT);
X    }
X  else if (c_ptr->spell == PRIEST)
X    {
X      calc_spells(A_WIS);
X      calc_mana(A_WIS);
X    }
X}
X
X/* Prints experience					-RAK-	*/
Xvoid prt_experience()
X{
X  register struct misc *p_ptr;
X
X  p_ptr = &py.misc;
X  if (p_ptr->exp > MAX_EXP)
X    p_ptr->exp = MAX_EXP;
X  if (p_ptr->lev < MAX_PLAYER_LEVEL)
X    {
X      while ((player_exp[p_ptr->lev-1] * p_ptr->expfact / 100) <= p_ptr->exp)
X	gain_level();
X      if (p_ptr->exp > p_ptr->max_exp)
X	p_ptr->max_exp = p_ptr->exp;
X    }
X  prt_long(p_ptr->exp, 14, STAT_COLUMN+6);
X}
X
X
X/* Calculate the players hit points */
Xvoid calc_hitpoints()
X{
X  register int hitpoints;
X  register struct misc *p_ptr;
X  register int32 value;
X
X  p_ptr = &py.misc;
X  hitpoints = player_hp[p_ptr->lev-1] + (con_adj() * p_ptr->lev);
X  /* always give at least one point per level + 1 */
X  if (hitpoints < (p_ptr->lev + 1))
X    hitpoints = p_ptr->lev + 1;
X
X  if (py.flags.status & PY_HERO)
X    hitpoints += 10;
X  if (py.flags.status & PY_SHERO)
X    hitpoints += 20;
X
X  /* mhp can equal zero while character is being created */
X  if ((hitpoints != p_ptr->mhp) && (p_ptr->mhp != 0))
X    {
X      /* change current hit points proportionately to change of mhp,
X	 divide first to avoid overflow, little loss of accuracy */
X      value = (((long)p_ptr->chp << 16) + p_ptr->chp_frac) / p_ptr->mhp
X	* hitpoints;
X      p_ptr->chp = value >> 16;
X      p_ptr->chp_frac = value & 0xFFFF;
X      p_ptr->mhp = hitpoints;
X
X      /* can't print hit points here, may be in store or inventory mode */
X      py.flags.status |= PY_HP;
X    }
X}
X
X
X/* Inserts a string into a string				*/
Xvoid insert_str(object_str, mtc_str, insert)
Xchar *object_str, *mtc_str, *insert;
X{
X  int obj_len;
X  char *bound, *pc;
X  register int i, mtc_len;
X  register char *temp_obj, *temp_mtc;
X  char out_val[80];
X
X  mtc_len = strlen(mtc_str);
X  obj_len = strlen(object_str);
X  bound = object_str + obj_len - mtc_len;
X  for (pc = object_str; pc <= bound; pc++)
X    {
X      temp_obj = pc;
X      temp_mtc = mtc_str;
X      for (i = 0; i < mtc_len; i++)
X	if (*temp_obj++ != *temp_mtc++)
X	  break;
X      if (i == mtc_len)
X	break;
X    }
X
X  if (pc <= bound)
X    {
X      (void) strncpy(out_val, object_str, (pc-object_str));
X      out_val[(pc-object_str)] = '\0';
X      if (insert)
X	(void) strcat(out_val, insert);
X      (void) strcat(out_val, (char *)(pc+mtc_len));
X      (void) strcpy(object_str, out_val);
X    }
X}
X
X
X#if 0
X/* this is no longer used anywhere */
X/* Inserts a number into a string				*/
Xvoid insert_num(object_str, mtc_str, number, show_sign)
Xchar *object_str;
Xregister char *mtc_str;
Xint number;
Xint show_sign;
X{
X  int mlen;
X  vtype str1, str2;
X  register char *string, *tmp_str;
X  int flag;
X
X  flag = 1;
X  mlen = strlen(mtc_str);
X  tmp_str = object_str;
X  do
X    {
X      string = index(tmp_str, mtc_str[0]);
X      if (string == NULL)
X	flag = 0;
X      else
X	{
X	  flag = strncmp(string, mtc_str, mlen);
X	  if (flag)
X	    tmp_str = string+1;
X	}
X    }
X  while (flag);
X  if (string)
X    {
X      (void) strncpy(str1, object_str, string - object_str);
X      str1[string - object_str] = '\0';
X      (void) strcpy(str2, string + mlen);
X      if ((number >= 0) && (show_sign))
X	(void) sprintf(object_str, "%s+%d%s", str1, number, str2);
X      else
X	(void) sprintf(object_str, "%s%d%s", str1, number, str2);
X    }
X}
X#endif
X
Xvoid insert_lnum(object_str, mtc_str, number, show_sign)
Xchar *object_str;
Xregister char *mtc_str;
Xint32 number;
Xint show_sign;
X{
X  int mlen;
X  vtype str1, str2;
X  register char *string, *tmp_str;
X  int flag;
X
X  flag = 1;
X  mlen = strlen(mtc_str);
X  tmp_str = object_str;
X  do
X    {
X      string = index(tmp_str, mtc_str[0]);
X      if (string == 0)
X	flag = 0;
X      else
X	{
X	  flag = strncmp(string, mtc_str, mlen);
X	  if (flag)
X	    tmp_str = string+1;
X	}
X    }
X  while (flag);
X  if (string)
X    {
X      (void) strncpy(str1, object_str, string - object_str);
X      str1[string - object_str] = '\0';
X      (void) strcpy(str2, string + mlen);
X      if ((number >= 0) && (show_sign))
X	(void) sprintf(object_str, "%s+%ld%s", str1, number, str2);
X      else
X	(void) sprintf(object_str, "%s%ld%s", str1, number, str2);
X    }
X}
X
X
X/* lets anyone enter wizard mode after a disclaimer...		- JEW - */
Xint enter_wiz_mode()
X{
X  register int answer;
X
X  if (!noscore)
X    {
X      msg_print("Wizard mode is for debugging and experimenting.");
X      answer = get_check(
X	"The game will not be scored if you enter wizard mode. Are you sure?");
X    }
X  if (noscore || answer)
X    {
X      noscore |= 0x2;
X      wizard = TRUE;
X      return(TRUE);
X    }
X  return(FALSE);
X}
X
X
X/* Weapon weight VS strength and dexterity		-RAK-	*/
Xint attack_blows(weight, wtohit)
Xint weight;
Xint *wtohit;
X{
X  register int adj_weight;
X  register int str_index, dex_index, s, d;
X
X  s = py.stats.use_stat[A_STR];
X  d = py.stats.use_stat[A_DEX];
X  if (s * 15 < weight)
X    {
X      *wtohit = s * 15 - weight;
X      return 1;
X    }
X  else
X    {
X      *wtohit = 0;
X      if      (d <  10)	 dex_index = 0;
X      else if (d <  19)	 dex_index = 1;
X      else if (d <  68)	 dex_index = 2;
X      else if (d < 108)	 dex_index = 3;
X      else if (d < 118)	 dex_index = 4;
X      else		 dex_index = 5;
X      adj_weight = (s * 10 / weight);
X      if      (adj_weight < 2)	str_index = 0;
X      else if (adj_weight < 3)	str_index = 1;
X      else if (adj_weight < 4)	str_index = 2;
X      else if (adj_weight < 5)	str_index = 3;
X      else if (adj_weight < 7)	str_index = 4;
X      else if (adj_weight < 9)	str_index = 5;
X      else			str_index = 6;
X      return (int)blows_table[str_index][dex_index];
X    }
X}
X
X
X/* Special damage due to magical abilities of object	-RAK-	*/
Xint tot_dam(i_ptr, tdam, monster)
Xregister inven_type *i_ptr;
Xregister int tdam;
Xint monster;
X{
X  register creature_type *m_ptr;
X  register recall_type *r_ptr;
X
X  if ((i_ptr->flags & TR_EGO_WEAPON) &&
X      (((i_ptr->tval >= TV_SLING_AMMO) && (i_ptr->tval <= TV_ARROW)) ||
X       ((i_ptr->tval >= TV_HAFTED) && (i_ptr->tval <= TV_SWORD)) ||
X       (i_ptr->tval == TV_FLASK)))
X    {
X      m_ptr = &c_list[monster];
X      r_ptr = &c_recall[monster];
X      /* Slay Dragon  */
X      if ((m_ptr->cdefense & CD_DRAGON) && (i_ptr->flags & TR_SLAY_DRAGON))
X	{
X	  tdam = tdam * 4;
X	  r_ptr->r_cdefense |= CD_DRAGON;
X	}
X      /* Slay Undead  */
X      else if ((m_ptr->cdefense & CD_UNDEAD) &&(i_ptr->flags & TR_SLAY_UNDEAD))
X	{
X	  tdam = tdam * 3;
X	  r_ptr->r_cdefense |= CD_UNDEAD;
X	}
X      /* Slay Animal  */
X      else if ((m_ptr->cdefense & CD_ANIMAL) &&(i_ptr->flags & TR_SLAY_ANIMAL))
X	{
X	  tdam = tdam * 2;
X	  r_ptr->r_cdefense |= CD_ANIMAL;
X	}
X      /* Slay Evil     */
X      else if ((m_ptr->cdefense & CD_EVIL) && (i_ptr->flags & TR_SLAY_EVIL))
X	{
X	  tdam = tdam * 2;
X	  r_ptr->r_cdefense |= CD_EVIL;
X	}
X      /* Frost	       */
X      else if ((m_ptr->cdefense & CD_FROST) && (i_ptr->flags & TR_FROST_BRAND))
X	{
X	  tdam = tdam * 3 / 2;
X	  r_ptr->r_cdefense |= CD_FROST;
X	}
X      /* Fire	      */
X      else if ((m_ptr->cdefense & CD_FIRE) && (i_ptr->flags & TR_FLAME_TONGUE))
X	{
X	  tdam = tdam * 3 / 2;
X	  r_ptr->r_cdefense |= CD_FIRE;
X	}
X    }
X  return(tdam);
X}
X
X
X/* Critical hits, Nasty way to die.			-RAK-	*/
Xint critical_blow(weight, plus, dam, attack_type)
Xregister int weight, plus, dam;
Xint attack_type;
X{
X  register int critical;
X
X  critical = dam;
X  /* Weight of weapon, plusses to hit, and character level all	    */
X  /* contribute to the chance of a critical			   */
X  if (randint(5000) <= (int)(weight + 5 * plus
X			     + (class_level_adj[py.misc.pclass][attack_type]
X				* py.misc.lev)))
X    {
X      weight += randint(650);
X      if (weight < 400)
X	{
X	  critical = 2*dam + 5;
X	  msg_print("It was a good hit! (x2 damage)");
X	}
X      else if (weight < 700)
X	{
X	  critical = 3*dam + 10;
X	  msg_print("It was an excellent hit! (x3 damage)");
X	}
X      else if (weight < 900)
X	{
X	  critical = 4*dam + 15;
X	  msg_print("It was a superb hit! (x4 damage)");
X	}
X      else
X	{
X	  critical = 5*dam + 20;
X	  msg_print("It was a *GREAT* hit! (x5 damage)");
X	}
X    }
X  return(critical);
X}
X
X
X/* Given direction "dir", returns new row, column location -RAK- */
Xint mmove(dir, y, x)
Xint dir;
Xregister int *y, *x;
X{
X  register int new_row, new_col;
X  int bool;
X
X  switch(dir)
X    {
X    case 1:
X      new_row = *y + 1;
X      new_col = *x - 1;
X      break;
X    case 2:
X      new_row = *y + 1;
X      new_col = *x;
X      break;
X    case 3:
X      new_row = *y + 1;
X      new_col = *x + 1;
X      break;
X    case 4:
X      new_row = *y;
X      new_col = *x - 1;
X      break;
X    case 5:
X      new_row = *y;
X      new_col = *x;
X      break;
X    case 6:
X      new_row = *y;
X      new_col = *x + 1;
X      break;
X    case 7:
X      new_row = *y - 1;
X      new_col = *x - 1;
X      break;
X    case 8:
X      new_row = *y - 1;
X      new_col = *x;
X      break;
X    case 9:
X      new_row = *y - 1;
X      new_col = *x + 1;
X      break;
X    }
X  bool = FALSE;
X  if ((new_row >= 0) && (new_row < cur_height)
X      && (new_col >= 0) && (new_col < cur_width))
X    {
X      *y = new_row;
X      *x = new_col;
X      bool = TRUE;
X    }
X  return(bool);
X}
X
X/* Saving throws for player character.		-RAK-	*/
Xint player_saves()
X{
X  if (randint(100) <= (py.misc.save + stat_adj(A_WIS)
X		       + (class_level_adj[py.misc.pclass][CLA_SAVE]
X			  * py.misc.lev / 3)))
X    return(TRUE);
X  else
X    return(FALSE);
X}
X
X
X/* Finds range of item in inventory list		-RAK-	*/
Xint find_range(item1, item2, j, k)
Xint item1, item2;
Xregister int *j, *k;
X{
X  register int i;
X  register inven_type *i_ptr;
X  int flag;
X
X  i = 0;
X  *j = -1;
X  *k = -1;
X  flag = FALSE;
X  i_ptr = &inventory[0];
X  while (i < inven_ctr)
X    {
X      if (!flag)
X	{
X	  if ((i_ptr->tval == item1) || (i_ptr->tval == item2))
X	    {
X	      flag = TRUE;
X	      *j = i;
X	    }
X	}
X      else
X	{
X	  if ((i_ptr->tval != item1) && (i_ptr->tval != item2))
X	    {
X	      *k = i - 1;
X	      break;
X	    }
X	}
X      i++;
X      i_ptr++;
X    }
X  if (flag && (*k == -1))
X    *k = inven_ctr - 1;
X  return(flag);
X}
X
X
X/* Teleport the player to a new location		-RAK-	*/
Xvoid teleport(dis)
Xint dis;
X{
X  register int y, x, i, j;
X
X  do
X    {
X      y = randint(cur_height) - 1;
X      x = randint(cur_width) - 1;
X      while (distance(y, x, char_row, char_col) > dis)
X	{
X	  y += ((char_row-y)/2);
X	  x += ((char_col-x)/2);
X	}
X    }
X  while ((cave[y][x].fval >= MIN_CLOSED_SPACE) || (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	cave[i][j].tl = FALSE;
X	lite_spot(i, j);
X      }
X  lite_spot(char_row, char_col);
X  char_row = y;
X  char_col = x;
X  check_view();
X  creatures(FALSE);
X  teleport_flag = FALSE;
X}
X
X
X/* Add a comment to an object description.		-CJS- */
Xvoid scribe_object()
X{
X  int item_val, j;
X  vtype out_val, tmp_str;
X
X  if (inven_ctr > 0 || equip_ctr > 0)
X    {
X      if (get_item(&item_val, "Which one? ", 0, INVEN_ARRAY_SIZE))
X	{
X	  objdes(tmp_str, &inventory[item_val], TRUE);
X	  (void) sprintf(out_val, "Inscribing %s", tmp_str);
X	  msg_print(out_val);
X	  if (inventory[item_val].inscrip[0] != '\0')
X	    (void) sprintf(out_val, "Replace %s New inscription:",
X			   inventory[item_val].inscrip);
X	  else
X	    (void) strcpy(out_val, "Inscription: ");
X	  j = 78 - strlen(tmp_str);
X	  if (j > 24)
X	    j = 12;
X	  prt(out_val, 0, 0);
X	  if (get_string(out_val, 0, strlen(out_val), j))
X	    inscribe(&inventory[item_val], out_val);
X	}
X    }
X  else
X    msg_print("You are not carrying anything to inscribe.");
X}
X
X/* Append an additional comment to an object description.	-CJS- */
Xvoid add_inscribe(i_ptr, type)
Xinven_type *i_ptr;
Xint8u type;
X{
X  i_ptr->ident |= type;
X}
X
X/* Replace any existing comment in an object description with a new one. CJS*/
Xvoid inscribe(i_ptr, str)
Xinven_type *i_ptr;
Xchar *str;
X{
X  (void) strcpy(i_ptr->inscrip, str);
X}
X
X
X/* We need to reset the view of things.			-CJS- */
Xvoid check_view()
X{
X  register int i, j;
X  register cave_type *c_ptr, *d_ptr;
X
X  c_ptr = &cave[char_row][char_col];
X  /* Check for new panel		   */
X  if (get_panel(char_row, char_col, FALSE))
X    prt_map();
X  /* Move the light source		   */
X  move_light(char_row, char_col, char_row, char_col);
X  /* A room of light should be lit.	 */
X  if (c_ptr->fval == LIGHT_FLOOR)
X    {
X      if ((py.flags.blind < 1) && !c_ptr->pl)
X	light_room(char_row, char_col);
X    }
X  /* In doorway of light-room?		   */
X  else if (c_ptr->lr && (py.flags.blind < 1))
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	    d_ptr = &cave[i][j];
X	    if ((d_ptr->fval == LIGHT_FLOOR) && !d_ptr->pl)
X	      light_room(i, j);
X	  }
X    }
X}
END_OF_FILE
if test 57629 -ne `wc -c <'misc2.c'`; then
    echo shar: \"'misc2.c'\" unpacked with wrong size!
fi
# end of 'misc2.c'
fi
echo shar: End of archive 5 \(of 31\).
cp /dev/null ark5isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 31 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


