-+-+-+-+-+-+-+-+ START OF PART 30 -+-+-+-+-+-+-+-+
X  return(summon);
X`7D
X
X
X/* Places undead adjacent to given location`09`09-RAK-`09*/
Xint summon_undead(y, x)
Xint *y, *x;
X`7B
X  register int i, j, k;
X  int l, m, ctr, summon;
X  register cave_type *cave_ptr;
X
X  i = 0;
X  summon = FALSE;
X  l = m_level`5BMAX_MONS_LEVEL`5D;
X  do
X    `7B
X      m = randint(l) - 1;
X      ctr = 0;
X      do
X`09`7B
X`09  if (c_list`5Bm`5D.cdefense & CD_UNDEAD)
X`09    `7B
X`09      ctr = 20;
X`09      l`09 = 0;
X`09    `7D
X`09  else
X`09    `7B
X`09      m++;
X`09      if (m > l)
X`09`09ctr = 20;
X`09      else
X`09`09ctr++;
X`09    `7D
X`09`7D
X      while (ctr <= 19);
X    `7D
X  while(l != 0);
X  do
X    `7B
X      j = *y - 2 + randint(3);
X      k = *x - 2 + randint(3);
X      if (in_bounds(j, k))
X`09`7B
X`09  cave_ptr = &cave`5Bj`5D`5Bk`5D;
X`09  if (cave_ptr->fval <= MAX_OPEN_SPACE && (cave_ptr->cptr == 0))
X`09    `7B
X`09      /* Place_monster() should always return TRUE here.  */
X`09      if (! place_monster(j, k, m, FALSE))
X`09`09return FALSE;
X`09      summon = TRUE;
X`09      i = 9;
X`09      *y = j;
X`09      *x = k;
X`09    `7D
X`09`7D
X      i++;
X    `7D
X  while(i <= 9);
X  return(summon);
X`7D
X
X
X/* If too many objects on floor level, delete some of them-RAK-`09*/
Xstatic void compact_objects()
X`7B
X  register int i, j;
X  int ctr, cur_dis, chance;
X  register cave_type *cave_ptr;
X
X  msg_print("Compacting objects...");
X
X  ctr = 0;
X  cur_dis = 66;
X  do
X    `7B
X      for (i = 0; i < cur_height; i++)
X`09for (j = 0; j < cur_width; j++)
X`09  `7B
X`09    cave_ptr = &cave`5Bi`5D`5Bj`5D;
X`09    if ((cave_ptr->tptr != 0)
X`09`09&& (distance(i, j, char_row, char_col) > cur_dis))
X`09      `7B
X`09`09switch(t_list`5Bcave_ptr->tptr`5D.tval)
X`09`09  `7B
X`09`09  case TV_VIS_TRAP:
X`09`09    chance = 15;
X`09`09    break;
X`09`09  case TV_INVIS_TRAP:
X`09`09  case TV_RUBBLE:
X`09`09  case TV_OPEN_DOOR: case TV_CLOSED_DOOR:
X`09`09    chance = 5;
X`09`09    break;
X`09`09  case TV_UP_STAIR: case TV_DOWN_STAIR:
X`09`09  case TV_STORE_DOOR:
X`09`09    /* stairs, don't delete them */
X`09`09    /* shop doors, don't delete them */
X`09`09    chance = 0;
X`09`09    break;
X`09`09  case TV_SECRET_DOOR: /* secret doors */
X`09`09    chance = 3;
X`09`09    break;
X`09`09  default:
X`09`09    chance = 10;
X`09`09  `7D
X`09`09if (randint (100) <= chance)
X`09`09  `7B
X`09`09    (void) delete_object(i, j);
X`09`09    ctr++;
X`09`09  `7D
X`09      `7D
X`09  `7D
X      if (ctr == 0)  cur_dis -= 6;
X    `7D
X  while (ctr <= 0);
X  if (cur_dis < 66)  prt_map();
X`7D
X
X/* Gives pointer to next free space`09`09`09-RAK-`09*/
Xint popt()
X`7B
X  if (tcptr == MAX_TALLOC)
X    compact_objects();
X  return (tcptr++);
X`7D
X
X
X/* Pushs a record back onto free space list`09`09-RAK-`09*/
X/* Delete_object() should always be called instead, unless the object in
X   question is not in the dungeon, e.g. in store1.c and files.c */
Xvoid pusht(x)
Xregister int8u x;
X`7B
X  register int i, j;
X
X  if (x != tcptr - 1)
X    `7B
X      t_list`5Bx`5D = t_list`5Btcptr - 1`5D;
X
X      /* must change the tptr in the cave of the object just moved */
X      for (i = 0; i < cur_height; i++)
X`09for (j = 0; j < cur_width; j++)
X`09  if (cave`5Bi`5D`5Bj`5D.tptr == tcptr - 1)
X`09    cave`5Bi`5D`5Bj`5D.tptr = x;
X    `7D
X  tcptr--;
X  invcopy(&t_list`5Btcptr`5D, OBJ_NOTHING);
X`7D
X
X
X/* Boolean : is object enchanted`09  -RAK- */
Xint magik(chance)
Xint chance;
X`7B
X  if (randint(100) <= chance)
X    return(TRUE);
X  else
X    return(FALSE);
X`7D
X
X
X/* Enchant a bonus based on degree desired -RAK- */
Xint m_bonus(base, max_std, level)
Xint base, max_std, level;
X`7B
X  register int x, stand_dev, tmp;
X
X  stand_dev = (OBJ_STD_ADJ * level / 100) + OBJ_STD_MIN;
X  /* Check for level > max_std since that may have generated an overflow.  *
V/
X  if (stand_dev > max_std `7C`7C level > max_std)
X    stand_dev = max_std;
X  /* abs may be a macro, don't call it with randnor as a parameter */
X  tmp = randnor(0, stand_dev);
X  x = (abs(tmp) / 10) + base;
X  if (x < base)
X    return(base);
X  else
X    return(x);
X`7D
$ CALL UNPACK MISC1.C;1 1708161202
$ create 'f'
X/* source/misc2.c: misc utility and initialization code, magic objects code
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 /* __TURBOC__ */
X
X#include "config.h"
X#include "constant.h"
X#include "types.h"
X#include "externs.h"
X
X
X/* Chance of treasure having magic abilities`09`09-RAK-`09*/
X/* Chance increases with each dungeon level`09`09`09 */
Xvoid magic_treasure(x, level)
Xint x, level;
X`7B
X  register inven_type *t_ptr;
X  register int chance, special, cursed, i;
X  int tmp;
X#ifdef ATARIST_MWC
X  int32u holder;
X#endif
X
X  chance = OBJ_BASE_MAGIC + level;
X  if (chance > OBJ_BASE_MAX)
X    chance = OBJ_BASE_MAX;
X  special = chance / OBJ_DIV_SPECIAL;
X  cursed  = (10 * chance) / OBJ_DIV_CURSED;
X  t_ptr = &t_list`5Bx`5D;
X
X  /* some objects appear multiple times in the object_list with different
X     levels, this is to make the object occur more often, however, for
X     consistency, must set the level of these duplicates to be the same
X     as the object with the lowest level */
X
X  /* Depending on treasure type, it can have certain magical properties*/
X  switch (t_ptr->tval)
X    `7B
X    case TV_SHIELD: case TV_HARD_ARMOR: case TV_SOFT_ARMOR:
X      if (magik(chance))
X`09`7B
X`09  t_ptr->toac += m_bonus(1, 30, level);
X`09  if (magik(special))
X`09    switch(randint(9))
X`09      `7B
X`09      case 1:
X#ifdef ATARIST_MWC
X`09`09t_ptr->flags `7C= (holder = TR_RES_LIGHT`7CTR_RES_COLD`7CTR_RES_ACID`7
VC
X`09`09`09`09 TR_RES_FIRE);
X#else
X`09`09t_ptr->flags `7C= (TR_RES_LIGHT`7CTR_RES_COLD`7CTR_RES_ACID`7C
X`09`09`09`09 TR_RES_FIRE);
X#endif
X`09`09t_ptr->name2 = SN_R;
X`09`09t_ptr->toac += 5;
X`09`09t_ptr->cost += 2500;
X`09`09break;
X`09      case 2:`09 /* Resist Acid`09  */
X#ifdef ATARIST_MWC
X`09`09t_ptr->flags `7C= (holder = TR_RES_ACID);
X#else
X`09`09t_ptr->flags `7C= TR_RES_ACID;
X#endif
X`09`09t_ptr->name2 = SN_RA;
X`09`09t_ptr->cost += 1000;
X`09`09break;
X`09      case 3: case 4:`09 /* Resist Fire`09  */
X#ifdef ATARIST_MWC
X`09`09t_ptr->flags `7C= (holder = TR_RES_FIRE);
X#else
X`09`09t_ptr->flags `7C= TR_RES_FIRE;
X#endif
X`09`09t_ptr->name2 = SN_RF;
X`09`09t_ptr->cost += 600;
X`09`09break;
X`09      case 5: case 6:`09/* Resist Cold`09 */
X#ifdef ATARIST_MWC
X`09`09t_ptr->flags `7C= (holder = TR_RES_COLD);
X#else
X`09`09t_ptr->flags `7C= TR_RES_COLD;
X#endif
X`09`09t_ptr->name2 = SN_RC;
X`09`09t_ptr->cost += 600;
X`09`09break;
X`09      case 7: case 8: case 9:  /* Resist Lightning*/
X#ifdef ATARIST_MWC
X`09`09t_ptr->flags `7C= (holder = TR_RES_LIGHT);
X#else
X`09`09t_ptr->flags `7C= TR_RES_LIGHT;
X#endif
X`09`09t_ptr->name2 = SN_RL;
X`09`09t_ptr->cost += 500;
X`09`09break;
X`09      `7D
X`09`7D
X      else if (magik(cursed))
X`09`7B
X`09  t_ptr->toac -= m_bonus(1, 40, level);
X`09  t_ptr->cost = 0;
X#ifdef ATARIST_MWC
X`09  t_ptr->flags `7C= (holder = TR_CURSED);
X#else
X`09  t_ptr->flags `7C= TR_CURSED;
X#endif
X`09`7D
X      break;
X
X    case TV_HAFTED: case TV_POLEARM: case TV_SWORD:
X      /* always show tohit/todam values if identified */
X      t_ptr->ident `7C= ID_SHOW_HITDAM;
X      if (magik(chance))
X`09`7B
X`09  t_ptr->tohit += m_bonus(0, 40, level);
X`09  /* Magical damage bonus now proportional to weapon base damage */
X`09  tmp = t_ptr->damage`5B0`5D * t_ptr->damage`5B1`5D;
X`09  t_ptr->todam += m_bonus(0, 4*tmp, tmp*level/10);
X`09  /* the 3*special/2 is needed because weapons are not as common as
X`09     before change to treasure distribution, this helps keep same
X`09     number of ego weapons same as before, see also missiles */
X`09  if (magik(3*special/2))
X`09    switch(randint(16))
X`09      `7B
X`09      case 1:`09/* Holy Avenger`09 */
X#ifdef ATARIST_MWC
X`09`09t_ptr->flags `7C= (holder = TR_SEE_INVIS`7CTR_SUST_STAT`7C
X`09`09`09`09 TR_SLAY_UNDEAD`7CTR_SLAY_EVIL`7CTR_STR);
X#else
X`09`09t_ptr->flags `7C= (TR_SEE_INVIS`7CTR_SUST_STAT`7CTR_SLAY_UNDEAD`7C
X`09`09`09`09 TR_SLAY_EVIL`7CTR_STR);
X#endif
X`09`09t_ptr->tohit += 5;
X`09`09t_ptr->todam += 5;
X`09`09t_ptr->toac  += randint(4);
X`09`09/* the value in p1 is used for strength increase */
X`09`09/* p1 is also used for sustain stat */
X`09`09t_ptr->p1    = randint(4);
X`09`09t_ptr->name2 = SN_HA;
X`09`09t_ptr->cost += t_ptr->p1*500;
X`09`09t_ptr->cost += 10000;
X`09`09break;
X`09      case 2:`09/* Defender`09 */
X#ifdef ATARIST_MWC
X`09`09t_ptr->flags `7C= (holder = TR_FFALL`7CTR_RES_LIGHT`7CTR_SEE_INVIS`7C
X`09`09`09`09 TR_FREE_ACT`7CTR_RES_COLD`7CTR_RES_ACID`7C
X`09`09`09`09 TR_RES_FIRE`7CTR_REGEN`7CTR_STEALTH);
X#else
X`09`09t_ptr->flags `7C= (TR_FFALL`7CTR_RES_LIGHT`7CTR_SEE_INVIS`7CTR_FREE_AC
VT
X`09`09`09`09 `7CTR_RES_COLD`7CTR_RES_ACID`7CTR_RES_FIRE`7C
X`09`09`09`09 TR_REGEN`7CTR_STEALTH);
X#endif
X`09`09t_ptr->tohit += 3;
X`09`09t_ptr->todam += 3;
X`09`09t_ptr->toac  += 5 + randint(5);
X`09`09t_ptr->name2 = SN_DF;
X`09`09/* the value in p1 is used for stealth */
X`09`09t_ptr->p1    = randint(3);
X`09`09t_ptr->cost += t_ptr->p1*500;
X`09`09t_ptr->cost += 7500;
X`09`09break;
X`09      case 3: case 4:`09 /* Slay Animal  */
X`09`09t_ptr->flags `7C= TR_SLAY_ANIMAL;
X`09`09t_ptr->tohit += 3;
X`09`09t_ptr->todam += 3;
X`09`09t_ptr->name2 = SN_SA;
X`09`09t_ptr->cost += 5000;
X`09`09break;
X`09      case 5: case 6:`09/* Slay Dragon`09 */
X`09`09t_ptr->flags `7C= TR_SLAY_DRAGON;
X`09`09t_ptr->tohit += 3;
X`09`09t_ptr->todam += 3;
X`09`09t_ptr->name2 = SN_SD;
X`09`09t_ptr->cost += 4000;
X`09`09break;
X`09      case 7: case 8:`09  /* Slay Evil`09   */
X`09`09t_ptr->flags `7C= TR_SLAY_EVIL;
X`09`09t_ptr->tohit += 3;
X`09`09t_ptr->todam += 3;
X`09`09t_ptr->name2 = SN_SE;
X`09`09t_ptr->cost += 4000;
X`09`09break;
X`09      case 9: case 10:`09 /* Slay Undead`09  */
X#ifdef ATARIST_MWC
X`09`09t_ptr->flags `7C= (holder = TR_SEE_INVIS`7CTR_SLAY_UNDEAD);
X#else
X`09`09t_ptr->flags `7C= (TR_SEE_INVIS`7CTR_SLAY_UNDEAD);
X#endif
X`09`09t_ptr->tohit += 2;
X`09`09t_ptr->todam += 2;
X`09`09t_ptr->name2 = SN_SU;
X`09`09t_ptr->cost += 3000;
X`09`09break;
X`09      case 11: case 12: case 13:   /* Flame Tongue  */
X#ifdef ATARIST_MWC
X`09`09t_ptr->flags `7C= (holder = TR_FLAME_TONGUE);
X#else
X`09`09t_ptr->flags `7C= TR_FLAME_TONGUE;
X#endif
X`09`09t_ptr->tohit++;
X`09`09t_ptr->todam += 3;
X`09`09t_ptr->name2 = SN_FT;
X`09`09t_ptr->cost += 2000;
X`09`09break;
X`09      case 14: case 15: case 16:   /* Frost Brand   */
X#ifdef ATARIST_MWC
X`09`09t_ptr->flags `7C= (holder = TR_FROST_BRAND);
X#else
X`09`09t_ptr->flags `7C= TR_FROST_BRAND;
X#endif
X`09`09t_ptr->tohit++;
X`09`09t_ptr->todam++;
X`09`09t_ptr->name2 = SN_FB;
X`09`09t_ptr->cost += 1200;
X`09`09break;
X`09      `7D
X`09`7D
X      else if (magik(cursed))
X`09`7B
X`09  t_ptr->tohit -= m_bonus(1, 55, level);
X`09  /* Magical damage bonus now proportional to weapon base damage */
X`09  tmp = t_ptr->damage`5B0`5D * t_ptr->damage`5B1`5D;
X`09  t_ptr->todam -= m_bonus(1, 11*tmp/2, tmp*level/10);
X#ifdef ATARIST_MWC
X`09  t_ptr->flags `7C= (holder = TR_CURSED);
X#else
X`09  t_ptr->flags `7C= TR_CURSED;
X#endif
X`09  t_ptr->cost = 0;
X`09`7D
X      break;
X
X    case TV_BOW:
X      /* always show tohit/todam values if identified */
X      t_ptr->ident `7C= ID_SHOW_HITDAM;
X      if (magik(chance))
X`09`7B
X`09  t_ptr->tohit += m_bonus(1, 30, level);
X`09  t_ptr->todam += m_bonus(1, 20, level); /* add damage. -CJS- */
X`09`7D
X      else if (magik(cursed))
X`09`7B
X`09  t_ptr->tohit -= m_bonus(1, 50, level);
X`09  t_ptr->todam -= m_bonus(1, 30, level); /* add damage. -CJS- */
X#ifdef ATARIST_MWC
X`09  t_ptr->flags `7C= (holder = TR_CURSED);
X#else
X`09  t_ptr->flags `7C= TR_CURSED;
X#endif
X`09  t_ptr->cost = 0;
X`09`7D
X      break;
X
X    case TV_DIGGING:
X      /* always show tohit/todam values if identified */
X      t_ptr->ident `7C= ID_SHOW_HITDAM;
X      if (magik(chance))
X`09`7B
X`09  tmp = randint(3);
X`09  if (tmp < 3)
X`09    t_ptr->p1 += m_bonus(0, 25, level);
X`09  else
X`09    `7B
X`09      /* a cursed digging tool */
X`09      t_ptr->p1 = -m_bonus(1, 30, level);
X`09      t_ptr->cost = 0;
X#ifdef ATARIST_MWC
X`09      t_ptr->flags `7C= (holder = TR_CURSED);
X#else
X`09      t_ptr->flags `7C= TR_CURSED;
X#endif
X`09    `7D
X`09`7D
X      break;
X
X    case TV_GLOVES:
X      if (magik(chance))
X`09`7B
X`09  t_ptr->toac += m_bonus(1, 20, level);
X`09  if (magik(special))
X`09    `7B
X`09      if (randint(2) == 1)
X`09`09`7B
X#ifdef ATARIST_MWC
X`09`09  t_ptr->flags `7C= (holder = TR_FREE_ACT);
X#else
X`09`09  t_ptr->flags `7C= TR_FREE_ACT;
X#endif
X`09`09  t_ptr->name2 = SN_FREE_ACTION;
X`09`09  t_ptr->cost += 1000;
X`09`09`7D
X`09      else
X`09`09`7B
X`09`09  t_ptr->ident `7C= ID_SHOW_HITDAM;
X`09`09  t_ptr->tohit += 1 + randint(3);
X`09`09  t_ptr->todam += 1 + randint(3);
X`09`09  t_ptr->name2 = SN_SLAYING;
X`09`09  t_ptr->cost += (t_ptr->tohit+t_ptr->todam)*250;
X`09`09`7D
X`09    `7D
X`09`7D
X      else if (magik(cursed))
X`09`7B
X`09  if (magik(special))
X`09    `7B
X`09      if (randint(2) == 1)
X`09`09`7B
X`09`09  t_ptr->flags `7C= TR_DEX;
X`09`09  t_ptr->name2 = SN_CLUMSINESS;
X`09`09`7D
X`09      else
X`09`09`7B
X`09`09  t_ptr->flags `7C= TR_STR;
X`09`09  t_ptr->name2 = SN_WEAKNESS;
X`09`09`7D
X`09      t_ptr->ident `7C= ID_SHOW_P1;
X`09      t_ptr->p1   = -m_bonus(1, 10, level);
X`09    `7D
X`09  t_ptr->toac -= m_bonus(1, 40, level);
X#ifdef ATARIST_MWC
X`09  t_ptr->flags `7C= (holder = TR_CURSED);
X#else
X`09  t_ptr->flags `7C= TR_CURSED;
X#endif
X`09  t_ptr->cost = 0;
X`09`7D
X      break;
X
X    case TV_BOOTS:
X      if (magik(chance))
X`09`7B
X`09  t_ptr->toac += m_bonus(1, 20, level);
X`09  if (magik(special))
X`09    `7B
X`09      tmp = randint(12);
X`09      if (tmp > 5)
X`09`09`7B
X#ifdef ATARIST_MWC
X`09`09  t_ptr->flags `7C= (holder = TR_FFALL);
X#else
+-+-+-+-+-+-+-+-  END  OF PART 30 +-+-+-+-+-+-+-+-
