-+-+-+-+-+-+-+-+ START OF PART 7 -+-+-+-+-+-+-+-+
X  if (randint(chance) != 1)
X    *took_turn`09= FALSE;
X  /* Must be within certain range`09`09   */
X  else if (m_ptr->cdis > MAX_SPELL_DIS)
X    *took_turn`09= FALSE;
X  /* Must have unobstructed Line-Of-Sight`09   */
X  else if (!los(char_row, char_col, (int)m_ptr->fy, (int)m_ptr->fx))
X    *took_turn`09= FALSE;
X  else`09/* Creature is going to cast a spell`09 */
X    `7B
X      *took_turn  = TRUE;
X      /* Check to see if monster should be lit. */
X      update_mon (monptr);
X      /* Describe the attack`09`09`09       */
X      if (m_ptr->ml)
X`09(void) sprintf(cdesc, "The %s ", r_ptr->name);
X      else
X`09(void) strcpy(cdesc, "It ");
X      /* For "DIED_FROM" string`09 */
X#ifdef ATARIST_MWC
X      holder = CM_WIN;
X      if (holder & r_ptr->cmove)
X#else
X      if (CM_WIN & r_ptr->cmove)
X#endif
X`09(void) sprintf(ddesc, "The %s", r_ptr->name);
X      else if (is_a_vowel (r_ptr->name`5B0`5D))
X`09(void) sprintf (ddesc, "an %s", r_ptr->name);
X      else
X`09(void) sprintf(ddesc, "a %s", r_ptr->name);
X      /* End DIED_FROM`09`09       */
X
X      /* Extract all possible spells into spell_choice */
X#ifdef ATARIST_MWC
X      holder = `7ECS_FREQ;
X      i = (r_ptr->spells & holder);
X#else
X      i = (r_ptr->spells & `7ECS_FREQ);
X#endif
X      k = 0;
X      while (i != 0)
X`09`7B
X`09  spell_choice`5Bk`5D = bit_pos(&i);
X`09  k++;
X`09`7D
X      /* Choose a spell to cast`09`09`09       */
X      thrown_spell = spell_choice`5Brandint(k) - 1`5D;
X      thrown_spell++;
X      /* all except teleport_away() and drain mana spells always disturb */
X      if (thrown_spell > 6 && thrown_spell != 17)
X`09disturb (1, 0);
X      /* save some code/data space here, with a small time penalty */
X      if ((thrown_spell < 14 && thrown_spell > 6) `7C`7C (thrown_spell == 16
V))
X`09`7B
X`09  (void) strcat(cdesc, "casts a spell.");
X`09  msg_print(cdesc);
X`09`7D
X      /* Cast the spell.`09`09`09     */
X      switch(thrown_spell)
X`09`7B
X`09case 5:`09 /*Teleport Short*/
X`09  teleport_away(monptr, 5);
X`09  break;
X`09case 6:`09 /*Teleport Long */
X`09  teleport_away(monptr, MAX_SIGHT);
X`09  break;
X`09case 7:`09 /*Teleport To`09 */
X`09  teleport_to((int)m_ptr->fy, (int)m_ptr->fx);
X`09  break;
X`09case 8:`09 /*Light Wound`09 */
X`09  if (player_saves())
X`09    msg_print("You resist the effects of the spell.");
X`09  else
X`09    take_hit(damroll(3, 8), ddesc);
X`09  break;
X`09case 9:`09 /*Serious Wound */
X`09  if (player_saves())
X`09    msg_print("You resist the effects of the spell.");
X`09  else
X`09    take_hit(damroll(8, 8), ddesc);
X`09  break;
X`09case 10:  /*Hold Person`09  */
X`09  if (py.flags.free_act)
X`09    msg_print("You are unaffected.");
X`09  else if (player_saves())
X`09    msg_print("You resist the effects of the spell.");
X`09  else if (py.flags.paralysis > 0)
X`09    py.flags.paralysis += 2;
X`09  else
X`09    py.flags.paralysis = randint(5)+4;
X`09  break;
X`09case 11:  /*Cause Blindness*/
X`09  if (player_saves())
X`09    msg_print("You resist the effects of the spell.");
X`09  else if (py.flags.blind > 0)
X`09    py.flags.blind += 6;
X`09  else
X`09    py.flags.blind += 12 + randint(3);
X`09  break;
X`09case 12:  /*Cause Confuse */
X`09  if (player_saves())
X`09    msg_print("You resist the effects of the spell.");
X`09  else if (py.flags.confused > 0)
X`09    py.flags.confused += 2;
X`09  else
X`09    py.flags.confused = randint(5) + 3;
X`09  break;
X`09case 13:  /*Cause Fear`09  */
X`09  if (player_saves())
X`09    msg_print("You resist the effects of the spell.");
X`09  else if (py.flags.afraid > 0)
X`09    py.flags.afraid += 2;
X`09  else
X`09    py.flags.afraid = randint(5) + 3;
X`09  break;
X`09case 14:  /*Summon Monster*/
X`09  (void) strcat(cdesc, "magically summons a monster!");
X`09  msg_print(cdesc);
X`09  y = char_row;
X`09  x = char_col;
X`09  /* in case compact_monster() is called,it needs monptr */
X`09  hack_monptr = monptr;
X`09  (void) summon_monster(&y, &x, FALSE);
X`09  hack_monptr = -1;
X`09  update_mon ((int)cave`5By`5D`5Bx`5D.cptr);
X`09  break;
X`09case 15:  /*Summon Undead*/
X`09  (void) strcat(cdesc, "magically summons an undead!");
X`09  msg_print(cdesc);
X`09  y = char_row;
X`09  x = char_col;
X`09  /* in case compact_monster() is called,it needs monptr */
X`09  hack_monptr = monptr;
X`09  (void) summon_undead(&y, &x);
X`09  hack_monptr = -1;
X`09  update_mon ((int)cave`5By`5D`5Bx`5D.cptr);
X`09  break;
X`09case 16:  /*Slow Person`09 */
X`09  if (py.flags.free_act)
X`09    msg_print("You are unaffected.");
X`09  else if (player_saves())
X`09    msg_print("You resist the effects of the spell.");
X`09  else if (py.flags.slow > 0)
X`09    py.flags.slow += 2;
X`09  else
X`09    py.flags.slow = randint(5) + 3;
X`09  break;
X`09case 17:  /*Drain Mana`09 */
X`09  if (py.misc.cmana > 0)
X`09    `7B
X`09      disturb (1, 0);
X`09      (void) sprintf(outval, "%sdraws psychic energy from you!",cdesc);
X`09      msg_print(outval);
X`09      if (m_ptr->ml)
X`09`09`7B
X`09`09  (void) sprintf(outval, "%sappears healthier.", cdesc);
X`09`09  msg_print(outval);
X`09`09`7D
X`09      r1 = (randint((int)r_ptr->level) >> 1) + 1;
X`09      if (r1 > py.misc.cmana)
X`09`09`7B
X`09`09  r1 = py.misc.cmana;
X`09`09  py.misc.cmana = 0;
X`09`09  py.misc.cmana_frac = 0;
X`09`09`7D
X`09      else
X`09`09py.misc.cmana -= r1;
X`09      prt_cmana();
X`09      m_ptr->hp += 6*(r1);
X`09    `7D
X`09  break;
X`09case 20:  /*Breath Light */
X`09  (void) strcat(cdesc, "breathes lightning.");
X`09  msg_print(cdesc);
X`09  breath(GF_LIGHTNING, char_row, char_col, (m_ptr->hp / 4), ddesc,
X`09`09 monptr);
X`09  break;
X`09case 21:  /*Breath Gas`09 */
X`09  (void) strcat(cdesc, "breathes gas.");
X`09  msg_print(cdesc);
X`09  breath(GF_POISON_GAS, char_row, char_col, (m_ptr->hp / 3), ddesc,
X`09`09 monptr);
X`09  break;
X`09case 22:  /*Breath Acid`09 */
X`09  (void) strcat(cdesc, "breathes acid.");
X`09  msg_print(cdesc);
X`09  breath(GF_ACID, char_row, char_col, (m_ptr->hp / 3), ddesc, monptr);
X`09  break;
X`09case 23:  /*Breath Frost */
X`09  (void) strcat(cdesc, "breathes frost.");
X`09  msg_print(cdesc);
X`09  breath(GF_FROST, char_row, char_col, (m_ptr->hp / 3), ddesc, monptr);
X`09  break;
X`09case 24:  /*Breath Fire`09 */
X`09  (void) strcat(cdesc, "breathes fire.");
X`09  msg_print(cdesc);
X`09  breath(GF_FIRE, char_row, char_col, (m_ptr->hp / 3), ddesc, monptr);
X`09  break;
X`09default:
X`09  (void) strcat (cdesc, "cast unknown spell.");
X`09  msg_print(cdesc);
X`09`7D
X      /* End of spells`09`09`09`09       */
X      if (m_ptr->ml)
X`09`7B
X`09  c_recall`5Bm_ptr->mptr`5D.r_spells `7C= 1L << (thrown_spell-1);
X`09  if ((c_recall`5Bm_ptr->mptr`5D.r_spells & CS_FREQ) != CS_FREQ)
X`09    c_recall`5Bm_ptr->mptr`5D.r_spells++;
X`09  if (death && c_recall`5Bm_ptr->mptr`5D.r_deaths < MAX_SHORT)
X`09    c_recall`5Bm_ptr->mptr`5D.r_deaths++;
X`09`7D
X    `7D
X`7D
X
X
X/* Places creature adjacent to given location`09`09-RAK-`09*/
X/* Rats and Flys are fun!`09`09`09`09`09 */
Xint multiply_monster(y, x, cr_index, monptr)
Xint y, x, cr_index;
Xint monptr;
X`7B
X  register int i, j, k;
X  register cave_type *c_ptr;
X  int result;
X#ifdef ATARIST_MWC
X  int32u holder;
X#endif
X
X  i = 0;
X  do
X    `7B
X      j = y - 2 + randint(3);
X      k = x - 2 + randint(3);
X      /* don't create a new creature on top of the old one, that causes
X`09 invincible/invisible creatures to appear */
X      if (in_bounds(j, k) && (j != y `7C`7C k != x))
X`09`7B
X`09  c_ptr = &cave`5Bj`5D`5Bk`5D;
X`09  if ((c_ptr->fval <= MAX_OPEN_SPACE) && (c_ptr->tptr == 0) &&
X`09      (c_ptr->cptr != 1))
X`09    `7B
X`09      if (c_ptr->cptr > 1)     /* Creature there already?`09*/
X`09`09`7B
X`09`09  /* Some critters are cannibalistic!`09    */
X#ifdef ATARIST_MWC
X`09`09  holder = CM_EATS_OTHER;
X`09`09  if ((c_list`5Bcr_index`5D.cmove & holder)
X#else
X`09`09  if ((c_list`5Bcr_index`5D.cmove & CM_EATS_OTHER)
X#endif
X`09`09      /* Check the experience level -CJS- */
X`09`09     && c_list`5Bcr_index`5D.mexp >=
X`09`09      c_list`5Bm_list`5Bc_ptr->cptr`5D.mptr`5D.mexp)
X`09`09    `7B
X`09`09      /* It ate an already processed monster.Handle normally.*/
X`09`09      if (monptr < c_ptr->cptr)
X`09`09`09delete_monster((int) c_ptr->cptr);
X`09`09      /* If it eats this monster, an already processed mosnter
X`09`09`09 will take its place, causing all kinds of havoc.
X`09`09`09 Delay the kill a bit. */
X`09`09      else
X`09`09`09fix1_delete_monster((int) c_ptr->cptr);
X
X`09`09      /* in case compact_monster() is called,it needs monptr */
X`09`09      hack_monptr = monptr;
X`09`09      /* Place_monster() may fail if monster list full.  */
X`09`09      result = place_monster(j, k, cr_index, FALSE);
X`09`09      hack_monptr = -1;
X`09`09      if (! result)
X`09`09`09return FALSE;
X`09`09      mon_tot_mult++;
X`09`09      return check_mon_lite(j, k);
X`09`09    `7D
X`09`09`7D
X`09      else
X`09`09/* All clear,  place a monster`09  */
X`09`09`7B
X`09`09  /* in case compact_monster() is called,it needs monptr */
X`09`09  hack_monptr = monptr;
X`09`09  /* Place_monster() may fail if monster list full.  */
X`09`09  result = place_monster(j, k, cr_index, FALSE);
X`09`09  hack_monptr = -1;
X`09`09  if (! result)
X`09`09    return FALSE;
X`09`09  mon_tot_mult++;
X`09`09  return check_mon_lite(j, k);
X`09`09`7D
X`09    `7D
X`09`7D
X      i++;
X    `7D
X  while (i <= 18);
X  return FALSE;
X`7D
X
X
X/* Move the critters about the dungeon`09`09`09-RAK-`09*/
Xstatic void mon_move(monptr, rcmove)
Xint monptr;
Xint32u *rcmove;
X`7B
X  register int i, j;
X  int k, move_test, dir;
X#ifdef M_XENIX
X  /* Avoid 'register' bug.  */
X  creature_type *r_ptr;
X#else
X  register creature_type *r_ptr;
X#endif
X  register monster_type *m_ptr;
X  int mm`5B9`5D;
X#ifdef ATARIST_MWC
X  int32u holder;
X#endif
X  int rest_val;
X
X  m_ptr = &m_list`5Bmonptr`5D;
X  r_ptr = &c_list`5Bm_ptr->mptr`5D;
X  /* Does the critter multiply?`09`09`09`09   */
X  /* rest could be negative, to be safe, only use mod with positive values.
V */
X  rest_val = abs (py.flags.rest);
X#ifdef ATARIST_MWC
X  holder = CM_MULTIPLY;
X  if ((r_ptr->cmove & holder) && (MAX_MON_MULT >= mon_tot_mult) &&
X#else
X  if ((r_ptr->cmove & CM_MULTIPLY) && (MAX_MON_MULT >= mon_tot_mult) &&
X#endif
X      ((rest_val % MON_MULT_ADJ) == 0))
X    `7B
X      k = 0;
X      for (i = m_ptr->fy-1; i <= m_ptr->fy+1; i++)
X`09for (j = m_ptr->fx-1; j <= m_ptr->fx+1; j++)
X`09  if (in_bounds(i, j) && (cave`5Bi`5D`5Bj`5D.cptr > 1))
X`09    k++;
X      /* can't call randint with a value of zero, increment counter
X`09 to allow creature multiplication */
X      if (k == 0)
X`09k++;
X      if ((k < 4) && (randint(k*MON_MULT_ADJ) == 1))
X`09if (multiply_monster((int)m_ptr->fy, (int)m_ptr->fx,
X`09`09`09 (int)m_ptr->mptr, monptr))
X#ifdef ATARIST_MWC
X`09  *rcmove `7C= holder;
X#else
X`09  *rcmove `7C= CM_MULTIPLY;
X#endif
X    `7D
X  move_test = FALSE;
X
X  /* if in wall, must immediately escape to a clear area */
X#ifdef ATARIST_MWC
X  holder = CM_PHASE;
X  if (!(r_ptr->cmove & holder) &&
X#else
X  if (!(r_ptr->cmove & CM_PHASE) &&
X#endif
X      (cave`5Bm_ptr->fy`5D`5Bm_ptr->fx`5D.fval >= MIN_CAVE_WALL))
X    `7B
X      /* If the monster is already dead, don't kill it again!
X`09 This can happen for monsters moving faster than the player.  They
X`09 will get multiple moves, but should not if they die on the first
X`09 move.  This is only a problem for monsters stuck in rock.  */
X      if (m_ptr->hp < 0)
X`09return;
X
X      k = 0;
X      dir = 1;
X      /* note direction of for loops matches direction of keypad from 1 to 9
V*/
X      /* do not allow attack against the player */
X      /* Must cast fy-1 to signed int, so that a nagative value of i will
X`09 fail the comparison.  */
X      for (i = m_ptr->fy+1; i >= (int)(m_ptr->fy-1); i--)
X`09for (j = m_ptr->fx-1; j <= m_ptr->fx+1; j++)
X`09  `7B
X`09    if ((dir != 5) && (cave`5Bi`5D`5Bj`5D.fval <= MAX_OPEN_SPACE)
X`09`09&& (cave`5Bi`5D`5Bj`5D.cptr != 1))
X`09      mm`5Bk++`5D = dir;
X`09    dir++;
X`09  `7D
X      if (k != 0)
X`09`7B
X`09  /* put a random direction first */
X`09  dir = randint (k) - 1;
X`09  i = mm`5B0`5D;
X`09  mm`5B0`5D = mm`5Bdir`5D;
X`09  mm`5Bdir`5D = i;
X`09  make_move (monptr, mm, rcmove);
X`09  /* this can only fail if mm`5B0`5D has a rune of protection */
X`09`7D
X      /* if still in a wall, let it dig itself out, but also apply some
X`09 more damage */
X      if (cave`5Bm_ptr->fy`5D`5Bm_ptr->fx`5D.fval >= MIN_CAVE_WALL)
X`09`7B
X`09  /* in case the monster dies, may need to call fix1_delete_monster()
X`09     instead of delete_monsters() */
X`09  hack_monptr = monptr;
X`09  i = mon_take_hit(monptr, damroll (8, 8));
X`09  hack_monptr = -1;
X`09  if (i >= 0)
X`09    `7B
X`09      msg_print("You hear a scream muffled by rock!");
X`09      prt_experience();
X`09    `7D
X`09  else
X`09    `7B
X`09      msg_print ("A creature digs itself out from the rock!");
X`09      (void) twall ((int)m_ptr->fy, (int)m_ptr->fx, 1, 0);
X`09    `7D
X`09`7D
X      return;  /* monster movement finished */
X    `7D
X  /* Creature is confused?  Chance it becomes un-confused  */
X  else if (m_ptr->confused)
X    `7B
X      mm`5B0`5D = randint(9);
X      mm`5B1`5D = randint(9);
X      mm`5B2`5D = randint(9);
X      mm`5B3`5D = randint(9);
X      mm`5B4`5D = randint(9);
X      /* don't move him if he is not supposed to move! */
X      if (!(r_ptr->cmove & CM_ATTACK_ONLY))
X`09make_move(monptr, mm, rcmove);
X      if (randint(8) == 1)
X`09m_ptr->confused = FALSE;
X      move_test = TRUE;
X    `7D
X  /* Creature may cast a spell */
X  else if (r_ptr->spells != 0)
X    mon_cast_spell(monptr, &move_test);
X  if (!move_test)
X    `7B
X      /* 75% random movement */
X      if ((r_ptr->cmove & CM_75_RANDOM) && (randint(100) < 75))
X`09`7B
X`09  mm`5B0`5D = randint(9);
X`09  mm`5B1`5D = randint(9);
X`09  mm`5B2`5D = randint(9);
X`09  mm`5B3`5D = randint(9);
X`09  mm`5B4`5D = randint(9);
X`09  *rcmove `7C= CM_75_RANDOM;
X`09  make_move(monptr, mm, rcmove);
X`09`7D
X      /* 40% random movement */
X      else if ((r_ptr->cmove & CM_40_RANDOM) && (randint(100) < 40))
X`09`7B
X`09  mm`5B0`5D = randint(9);
X`09  mm`5B1`5D = randint(9);
X`09  mm`5B2`5D = randint(9);
+-+-+-+-+-+-+-+-  END  OF PART 7 +-+-+-+-+-+-+-+-
