-+-+-+-+-+-+-+-+ START OF PART 45 -+-+-+-+-+-+-+-+
X/* The cycle lists the directions in anticlockwise order, for`09-CJS-
X   over two complete cycles. The chome array maps a direction on
X   to its position in the cycle.
X*/
Xstatic int cycle`5B`5D = `7B 1, 2, 3, 6, 9, 8, 7, 4, 1, 2, 3, 6, 9, 8, 7, 4,
V 1 `7D;
Xstatic int chome`5B`5D = `7B -1, 8, 9, 10, 7, -1, 11, 6, 5, 4 `7D;
Xstatic int find_openarea, find_breakright, find_breakleft, find_prevdir;
Xstatic int find_direction; /* Keep a record of which way we are going. */
X
Xvoid find_init(dir)
Xint dir;
X`7B
X  int row, col, deepleft, deepright;
X  register int i, shortleft, shortright;
X
X  row = char_row;
X  col = char_col;
X  if (!mmove(dir, &row, &col))
X    find_flag = FALSE;
X  else
X    `7B
X      find_direction = dir;
X      find_flag = 1;
X      find_breakright = find_breakleft = FALSE;
X      find_prevdir = dir;
X      if (py.flags.blind < 1)
X`09`7B
X`09  i = chome`5Bdir`5D;
X`09  deepleft = deepright = FALSE;
X`09  shortright = shortleft = FALSE;
X`09  if (see_wall(cycle`5Bi+1`5D, char_row, char_col))
X`09    `7B
X`09      find_breakleft = TRUE;
X`09      shortleft = TRUE;
X`09    `7D
X`09  else if (see_wall(cycle`5Bi+1`5D, row, col))
X`09    `7B
X`09      find_breakleft = TRUE;
X`09      deepleft = TRUE;
X`09    `7D
X`09  if (see_wall(cycle`5Bi-1`5D, char_row, char_col))
X`09    `7B
X`09      find_breakright = TRUE;
X`09      shortright = TRUE;
X`09    `7D
X`09  else if (see_wall(cycle`5Bi-1`5D, row, col))
X`09    `7B
X`09      find_breakright = TRUE;
X`09      deepright = TRUE;
X`09    `7D
X`09  if (find_breakleft && find_breakright)
X`09    `7B
X`09      find_openarea = FALSE;
X`09      if (dir & 1)
X`09`09`7B`09`09/* a hack to allow angled corridor entry */
X`09`09  if (deepleft && !deepright)
X`09`09    find_prevdir = cycle`5Bi-1`5D;
X`09`09  else if (deepright && !deepleft)
X`09`09    find_prevdir = cycle`5Bi+1`5D;
X`09`09`7D
X`09      /* else if there is a wall two spaces ahead and seem to be in a
X`09`09 corridor, then force a turn into the side corridor, must
X`09`09 be moving straight into a corridor here */
X`09      else if (see_wall(cycle`5Bi`5D, row, col))
X`09`09`7B
X`09`09  if (shortleft && !shortright)
X`09`09    find_prevdir = cycle`5Bi-2`5D;
X`09`09  else if (shortright && !shortleft)
X`09`09    find_prevdir = cycle`5Bi+2`5D;
X`09`09`7D
X`09    `7D
X`09  else
X`09    find_openarea = TRUE;
X`09`7D
X    `7D
X
X  /* We must erase the player symbol '@' here, because sub3_move_light()
X     does not erase the previous location of the player when in find mode
X     and when find_prself is FALSE.  The player symbol is not draw at all
X     in this case while moving, so the only problem is on the first turn
X     of find mode, when the initial position of the character must be erased
V.
X     Hence we must do the erasure here.  */
X  if (! light_flag && ! find_prself)
X    print(loc_symbol(char_row, char_col), char_row, char_col);
X
X  move_char(dir, TRUE);
X  if (find_flag == FALSE)
X    command_count = 0;
X`7D
X
Xvoid find_run()
X`7B
X  /* prevent infinite loops in find mode, will stop after moving 100 times *
V/
X  if (find_flag++ > 100)
X    `7B
X      msg_print("You stop running to catch your breath.");
X      end_find();
X    `7D
X  else
X    move_char(find_direction, TRUE);
X`7D
X
X/* Switch off the run flag - and get the light correct. -CJS- */
Xvoid end_find()
X`7B
X  if (find_flag)
X    `7B
X      find_flag = FALSE;
X      move_light(char_row, char_col, char_row, char_col);
X    `7D
X`7D
X
X/* Do we see a wall? Used in running.`09`09-CJS- */
Xstatic int see_wall(dir, y, x)
Xint dir, y, x;
X`7B
X  char c;
X
X  if (!mmove(dir, &y, &x))`09/* check to see if movement there possible */
X    return TRUE;
X#ifdef MSDOS
X  else if ((c = loc_symbol(y, x)) == wallsym `7C`7C c == '%')
X#else
X#ifdef ATARI_ST
X  else if ((c = loc_symbol(y, x)) == (unsigned char)240 `7C`7C c == '%')
X#else
X  else if ((c = loc_symbol(y, x)) == '#' `7C`7C c == '%')
X#endif
X#endif
X    return TRUE;
X  else
X    return FALSE;
X`7D
X
X/* Do we see anything? Used in running.`09`09-CJS- */
Xstatic int see_nothing(dir, y, x)
Xint dir, y, x;
X`7B
X  if (!mmove(dir, &y, &x))`09/* check to see if movement there possible */
X    return FALSE;
X  else if (loc_symbol(y, x) == ' ')
X    return TRUE;
X  else
X    return FALSE;
X`7D
X
X
X/* Determine the next direction for a run, or if we should stop.  -CJS- */
Xvoid area_affect(dir, y, x)
Xint dir, y, x;
X`7B
X  int newdir, t, inv, check_dir, row, col;
X  register int i, max, option, option2;
X  register cave_type *c_ptr;
X
X  if (py.flags.blind < 1)
X    `7B
X      option = 0;
X      option2 = 0;
X      dir = find_prevdir;
X      max = (dir & 1) + 1;
X      /* Look at every newly adjacent square. */
X      for(i = -max; i <= max; i++)
X`09`7B
X`09  newdir = cycle`5Bchome`5Bdir`5D+i`5D;
X`09  row = y;
X`09  col = x;
X`09  if (mmove(newdir, &row, &col))
X`09    `7B
X`09      /* Objects player can see (Including doors?) cause a stop. */
X`09      c_ptr = &cave`5Brow`5D`5Bcol`5D;
X`09      if (player_light `7C`7C c_ptr->tl `7C`7C c_ptr->pl `7C`7C c_ptr->fm
V)
X`09`09`7B
X`09`09  if (c_ptr->tptr != 0)
X`09`09    `7B
X`09`09      t = t_list`5Bc_ptr->tptr`5D.tval;
X`09`09      if (t != TV_INVIS_TRAP && t != TV_SECRET_DOOR
X`09`09`09  && (t != TV_OPEN_DOOR `7C`7C !find_ignore_doors))
X`09`09`09`7B
X`09`09`09  end_find();
X`09`09`09  return;
X`09`09`09`7D
X`09`09    `7D
X`09`09  /* Also Creatures`09`09*/
X`09`09  /* the monster should be visible since update_mon() checks
X`09`09     for the special case of being in find mode */
X`09`09  if (c_ptr->cptr > 1 && m_list`5Bc_ptr->cptr`5D.ml)
X`09`09    `7B
X`09`09      end_find();
X`09`09      return;
X`09`09    `7D
X`09`09  inv = FALSE;
X`09`09`7D
X`09      else
X`09`09inv = TRUE;`09/* Square unseen. Treat as open. */
X
X`09      if (c_ptr->fval <= MAX_OPEN_SPACE `7C`7C inv)
X`09`09`7B
X`09`09  if (find_openarea)
X`09`09    `7B
X`09`09      /* Have we found a break? */
X`09`09      if (i < 0)
X`09`09`09`7B
X`09`09`09  if (find_breakright)
X`09`09`09    `7B
X`09`09`09      end_find();
X`09`09`09      return;
X`09`09`09    `7D
X`09`09`09`7D
X`09`09      else if (i > 0)
X`09`09`09`7B
X`09`09`09  if (find_breakleft)
X`09`09`09    `7B
X`09`09`09      end_find();
X`09`09`09      return;
X`09`09`09    `7D
X`09`09`09`7D
X`09`09    `7D
X`09`09  else if (option == 0)
X`09`09    option = newdir;`09/* The first new direction. */
X`09`09  else if (option2 != 0)
X`09`09    `7B
X`09`09      end_find();`09/* Three new directions. STOP. */
X`09`09      return;
X`09`09    `7D
X`09`09  else if (option != cycle`5Bchome`5Bdir`5D+i-1`5D)
X`09`09    `7B
X`09`09      end_find();`09/* If not adjacent to prev, STOP */
X`09`09      return;
X`09`09    `7D
X`09`09  else
X`09`09    `7B
X`09`09      /* Two adjacent choices. Make option2 the diagonal,
X`09`09`09 and remember the other diagonal adjacent to the first
X`09`09`09 option. */
X`09`09      if ((newdir & 1) == 1)
X`09`09`09`7B
X`09`09`09  check_dir = cycle`5Bchome`5Bdir`5D+i-2`5D;
X`09`09`09  option2 = newdir;
X`09`09`09`7D
X`09`09      else
X`09`09`09`7B
X`09`09`09  check_dir = cycle`5Bchome`5Bdir`5D+i+1`5D;
X`09`09`09  option2 = option;
X`09`09`09  option = newdir;
X`09`09`09`7D
X`09`09    `7D
X`09`09`7D
X`09      else if (find_openarea)
X`09`09`7B
X`09`09  /* We see an obstacle. In open area, STOP if on a side
X`09`09     previously open. */
X`09`09  if (i < 0)
X`09`09    `7B
X`09`09      if (find_breakleft)
X`09`09`09`7B
X`09`09`09  end_find();
X`09`09`09  return;
X`09`09`09`7D
X`09`09      find_breakright = TRUE;
X`09`09    `7D
X`09`09  else if (i > 0)
X`09`09    `7B
X`09`09      if (find_breakright)
X`09`09`09`7B
X`09`09`09  end_find();
X`09`09`09  return;
X`09`09`09`7D
X`09`09      find_breakleft = TRUE;
X`09`09    `7D
X`09`09`7D
X`09    `7D
X`09`7D
X
X      if (find_openarea == FALSE)
X`09`7B`09/* choose a direction. */
X`09  if (option2 == 0 `7C`7C (find_examine && !find_cut))
X`09    `7B
X`09      /* There is only one option, or if two, then we always examine
X`09`09 potential corners and never cur known corners, so you step
X`09`09 into the straight option. */
X`09      if (option != 0)
X`09`09find_direction = option;
X`09      if (option2 == 0)
X`09`09find_prevdir = option;
X`09      else
X`09`09find_prevdir = option2;
X`09    `7D
X`09  else
X`09    `7B
X`09      /* Two options! */
X`09      row = y;
X`09      col = x;
X`09      (void) mmove(option, &row, &col);
X`09      if (!see_wall(option, row, col)
X`09`09  `7C`7C !see_wall(check_dir, row, col))
X`09`09`7B
X`09`09  /* Don't see that it is closed off.  This could be a
X`09`09     potential corner or an intersection. */
X`09`09  if (find_examine && see_nothing(option, row, col)
X`09`09      && see_nothing(option2, row, col))
X`09`09    /* Can not see anything ahead and in the direction we are
X`09`09       turning, assume that it is a potential corner. */
X`09`09    `7B
X`09`09      find_direction = option;
X`09`09      find_prevdir = option2;
X`09`09    `7D
X`09`09  else
X`09`09    /* STOP: we are next to an intersection or a room */
X`09`09    end_find();
X`09`09`7D
X`09      else if (find_cut)
X`09`09`7B
X`09`09  /* This corner is seen to be enclosed; we cut the corner. */
X`09`09  find_direction = option2;
X`09`09  find_prevdir = option2;
X`09`09`7D
X`09      else
X`09`09`7B
X`09`09  /* This corner is seen to be enclosed, and we deliberately
X`09`09     go the long way. */
X`09`09  find_direction = option;
X`09`09  find_prevdir = option2;
X`09`09`7D
X`09    `7D
X`09`7D
X    `7D
X`7D
X
X
X/* AC gets worse`09`09`09`09`09-RAK-`09*/
X/* Note: This routine affects magical AC bonuses so that stores`09  */
X/*`09 can detect the damage.`09`09`09`09`09 */
Xint minus_ac(typ_dam)
Xint32u typ_dam;
X`7B
X  register int i, j;
X  int tmp`5B6`5D, minus;
X  register inven_type *i_ptr;
X  bigvtype out_val, tmp_str;
X
X  i = 0;
X  if (inventory`5BINVEN_BODY`5D.tval != TV_NOTHING)
X    `7B
X      tmp`5Bi`5D = INVEN_BODY;
X      i++;
X    `7D
X  if (inventory`5BINVEN_ARM`5D.tval != TV_NOTHING)
X    `7B
X      tmp`5Bi`5D = INVEN_ARM;
X      i++;
X    `7D
X  if (inventory`5BINVEN_OUTER`5D.tval != TV_NOTHING)
X    `7B
X      tmp`5Bi`5D = INVEN_OUTER;
X      i++;
X    `7D
X  if (inventory`5BINVEN_HANDS`5D.tval != TV_NOTHING)
X    `7B
X      tmp`5Bi`5D = INVEN_HANDS;
X      i++;
X    `7D
X  if (inventory`5BINVEN_HEAD`5D.tval != TV_NOTHING)
X    `7B
X      tmp`5Bi`5D = INVEN_HEAD;
X      i++;
X    `7D
X  /* also affect boots */
X  if (inventory`5BINVEN_FEET`5D.tval != TV_NOTHING)
X    `7B
X      tmp`5Bi`5D = INVEN_FEET;
X      i++;
X    `7D
X  minus = FALSE;
X  if (i > 0)
X    `7B
X      j = tmp`5Brandint(i) - 1`5D;
X      i_ptr = &inventory`5Bj`5D;
X      if (i_ptr->flags & typ_dam)
X`09`7B
X`09  objdes(tmp_str, &inventory`5Bj`5D, FALSE);
X`09  (void) sprintf(out_val, "Your %s resists damage!", tmp_str);
X`09  msg_print(out_val);
X`09  minus = TRUE;
X`09`7D
X      else if ((i_ptr->ac+i_ptr->toac) > 0)
X`09`7B
X`09  objdes(tmp_str, &inventory`5Bj`5D, FALSE);
X`09  (void) sprintf(out_val, "Your %s is damaged!", tmp_str);
X`09  msg_print(out_val);
X`09  i_ptr->toac--;
X`09  calc_bonuses();
X`09  minus = TRUE;
X`09`7D
X    `7D
X  return(minus);
X`7D
X
X
X/* Corrode the unsuspecting person's armor`09`09 -RAK-`09 */
Xvoid corrode_gas(kb_str)
Xchar *kb_str;
X`7B
X#ifdef ATARIST_MWC
X  int32u holder;
X#endif
X
X#ifdef ATARIST_MWC
X  if (!minus_ac((int32u) (holder = TR_RES_ACID)))
X#else
X  if (!minus_ac((int32u) TR_RES_ACID))
X#endif
X    take_hit(randint(8), kb_str);
X  if (inven_damage(set_corrodes, 5) > 0)
X    msg_print("There is an acrid smell coming from your pack.");
X`7D
X
X
X/* Poison gas the idiot.`09`09`09`09-RAK-`09*/
Xvoid poison_gas(dam, kb_str)
Xint dam;
Xchar *kb_str;
X`7B
X  take_hit(dam, kb_str);
X  py.flags.poisoned += 12 + randint(dam);
X`7D
X
X
X/* Burn the fool up.`09`09`09`09`09-RAK-`09*/
Xvoid fire_dam(dam, kb_str)
Xint dam;
Xchar *kb_str;
X`7B
X  if (py.flags.fire_resist)
X    dam = dam / 3;
X  if (py.flags.resist_heat > 0)
X    dam = dam / 3;
X  take_hit(dam, kb_str);
X  if (inven_damage(set_flammable, 3) > 0)
X    msg_print("There is smoke coming from your pack!");
X`7D
X
X
X/* Freeze him to death.`09`09`09`09-RAK-`09*/
Xvoid cold_dam(dam, kb_str)
Xint dam;
Xchar *kb_str;
X`7B
X  if (py.flags.cold_resist)
X    dam = dam / 3;
X  if (py.flags.resist_cold > 0)
X    dam = dam / 3;
X  take_hit(dam, kb_str);
X  if (inven_damage(set_frost_destroy, 5) > 0)
X    msg_print("Something shatters inside your pack!");
X`7D
X
X
X/* Lightning bolt the sucker away.`09`09`09-RAK-`09*/
Xvoid light_dam(dam, kb_str)
Xint dam;
Xchar *kb_str;
X`7B
X  if (py.flags.lght_resist)
X    take_hit((dam / 3), kb_str);
X  else
X    take_hit(dam, kb_str);
X  if (inven_damage(set_lightning_destroy, 3) > 0)
X    msg_print("There are sparks coming from your pack!");
X`7D
X
X
X/* Throw acid on the hapless victim`09`09`09-RAK-`09*/
Xvoid acid_dam(dam, kb_str)
Xint dam;
Xchar *kb_str;
X`7B
X  register int flag;
X#ifdef ATARIST_MWC
X  int32u holder;
X#endif
X
X  flag = 0;
X#ifdef ATARIST_MWC
X  if (minus_ac((int32u) (holder = TR_RES_ACID)))
X#else
X  if (minus_ac((int32u) TR_RES_ACID))
X#endif
X    flag = 1;
X  if (py.flags.acid_resist)
X    flag += 2;
X  take_hit (dam / (flag + 1), kb_str);
X  if (inven_damage(set_acid_affect, 3) > 0)
X    msg_print("There is an acrid smell coming from your pack!");
X`7D
$ CALL UNPACK MORIA2.C;1 773170235
$ create 'f'
X/* source/moria3.c: misc code, mainly to handle player commands
X
X   Copyright (c) 1989-92 James E. Wilson, Robert A. Koeneke
X
X   This software may be copied and distributed for educational, research, an
Vd
X   not for profit purposes provided that this copyright and statement are
X   included in all such copies. */
X
X#ifdef __TURBOC__
X#include`09<stdio.h>
X#endif
X
X#include "config.h"
X#include "constant.h"
X#include "types.h"
X#include "externs.h"
X
X#ifdef USG
X#ifndef ATARIST_MWC
X#include <string.h>
X#endif
X#else
X#include <strings.h>
X#endif
X
X#if defined(LINT_ARGS)
Xstatic void hit_trap(int, int);
Xstatic void carry(int, int, int);
+-+-+-+-+-+-+-+-  END  OF PART 45 +-+-+-+-+-+-+-+-
