Source:NetHack 3.6.0/src/makemon.c

From NetHackWiki
(Redirected from Source:Makemon.c)
Jump to: navigation, search

Below is the full text to makemon.c from the source code of NetHack 3.6.0. To link to a particular line, write [[Source:NetHack 3.6.0/src/makemon.c#line123]], for example.

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

Top of file

  1.  /* NetHack 3.6	makemon.c	$NHDT-Date: 1449269917 2015/12/04 22:58:37 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.105 $ */
  2.  /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5.  #include "hack.h"
  6.  
  7.  #include <ctype.h>
  8.  
  9.  STATIC_VAR NEARDATA struct monst zeromonst;
  10.  
  11.  /* this assumes that a human quest leader or nemesis is an archetype
  12.     of the corresponding role; that isn't so for some roles (tourist
  13.     for instance) but is for the priests and monks we use it for... */
  14.  #define quest_mon_represents_role(mptr, role_pm) \
  15.      (mptr->mlet == S_HUMAN && Role_if(role_pm)   \
  16.       && (mptr->msound == MS_LEADER || mptr->msound == MS_NEMESIS))
  17.  
  18.  STATIC_DCL boolean FDECL(uncommon, (int));
  19.  STATIC_DCL int FDECL(align_shift, (struct permonst *));
  20.  STATIC_DCL boolean FDECL(mk_gen_ok, (int, int, int));
  21.  STATIC_DCL boolean FDECL(wrong_elem_type, (struct permonst *));
  22.  STATIC_DCL void FDECL(m_initgrp, (struct monst *, int, int, int));
  23.  STATIC_DCL void FDECL(m_initthrow, (struct monst *, int, int));
  24.  STATIC_DCL void FDECL(m_initweap, (struct monst *));
  25.  STATIC_DCL void FDECL(m_initinv, (struct monst *));
  26.  STATIC_DCL boolean FDECL(makemon_rnd_goodpos, (struct monst *, unsigned, coord *));
  27.  
  28.  extern const int monstr[];
  29.  
  30.  #define m_initsgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 3)
  31.  #define m_initlgrp(mtmp, x, y) m_initgrp(mtmp, x, y, 10)
  32.  #define toostrong(monindx, lev) (monstr[monindx] > lev)
  33.  #define tooweak(monindx, lev) (monstr[monindx] < lev)
  34.  

is_home_elemental

  1.  boolean
  2.  is_home_elemental(ptr)
  3.  struct permonst *ptr;
  4.  {
  5.      if (ptr->mlet == S_ELEMENTAL)
  6.          switch (monsndx(ptr)) {
  7.          case PM_AIR_ELEMENTAL:
  8.              return Is_airlevel(&u.uz);
  9.          case PM_FIRE_ELEMENTAL:
  10.              return Is_firelevel(&u.uz);
  11.          case PM_EARTH_ELEMENTAL:
  12.              return Is_earthlevel(&u.uz);
  13.          case PM_WATER_ELEMENTAL:
  14.              return Is_waterlevel(&u.uz);
  15.          }
  16.      return FALSE;
  17.  }
  18.  

wrong_elem_type

  1.  /*
  2.   * Return true if the given monster cannot exist on this elemental level.
  3.   */
  4.  STATIC_OVL boolean
  5.  wrong_elem_type(ptr)
  6.  struct permonst *ptr;
  7.  {
  8.      if (ptr->mlet == S_ELEMENTAL) {
  9.          return (boolean) !is_home_elemental(ptr);
  10.      } else if (Is_earthlevel(&u.uz)) {
  11.          /* no restrictions? */
  12.      } else if (Is_waterlevel(&u.uz)) {
  13.          /* just monsters that can swim */
  14.          if (!is_swimmer(ptr))
  15.              return TRUE;
  16.      } else if (Is_firelevel(&u.uz)) {
  17.          if (!pm_resistance(ptr, MR_FIRE))
  18.              return TRUE;
  19.      } else if (Is_airlevel(&u.uz)) {
  20.          if (!(is_flyer(ptr) && ptr->mlet != S_TRAPPER) && !is_floater(ptr)
  21.              && !amorphous(ptr) && !noncorporeal(ptr) && !is_whirly(ptr))
  22.              return TRUE;
  23.      }
  24.      return FALSE;
  25.  }
  26.  

m_initgrp

  1.  /* make a group just like mtmp */
  2.  STATIC_OVL void
  3.  m_initgrp(mtmp, x, y, n)
  4.  register struct monst *mtmp;
  5.  register int x, y, n;
  6.  {
  7.      coord mm;
  8.      register int cnt = rnd(n);
  9.      struct monst *mon;
  10.  #if defined(__GNUC__) && (defined(HPUX) || defined(DGUX))
  11.      /* There is an unresolved problem with several people finding that
  12.       * the game hangs eating CPU; if interrupted and restored, the level
  13.       * will be filled with monsters.  Of those reports giving system type,
  14.       * there were two DG/UX and two HP-UX, all using gcc as the compiler.
  15.       * hcroft@hpopb1.cern.ch, using gcc 2.6.3 on HP-UX, says that the
  16.       * problem went away for him and another reporter-to-newsgroup
  17.       * after adding this debugging code.  This has almost got to be a
  18.       * compiler bug, but until somebody tracks it down and gets it fixed,
  19.       * might as well go with the "but it went away when I tried to find
  20.       * it" code.
  21.       */
  22.      int cnttmp, cntdiv;
  23.  
  24.      cnttmp = cnt;
  25.      debugpline4("init group call <%d,%d>, n=%d, cnt=%d.", x, y, n, cnt);
  26.      cntdiv = ((u.ulevel < 3) ? 4 : (u.ulevel < 5) ? 2 : 1);
  27.  #endif
  28.      /* Tuning: cut down on swarming at low character levels [mrs] */
  29.      cnt /= (u.ulevel < 3) ? 4 : (u.ulevel < 5) ? 2 : 1;
  30.  #if defined(__GNUC__) && (defined(HPUX) || defined(DGUX))
  31.      if (cnt != (cnttmp / cntdiv)) {
  32.          pline("cnt=%d using %d, cnttmp=%d, cntdiv=%d", cnt,
  33.                (u.ulevel < 3) ? 4 : (u.ulevel < 5) ? 2 : 1, cnttmp, cntdiv);
  34.      }
  35.  #endif
  36.      if (!cnt)
  37.          cnt++;
  38.  #if defined(__GNUC__) && (defined(HPUX) || defined(DGUX))
  39.      if (cnt < 0)
  40.          cnt = 1;
  41.      if (cnt > 10)
  42.          cnt = 10;
  43.  #endif
  44.  
  45.      mm.x = x;
  46.      mm.y = y;
  47.      while (cnt--) {
  48.          if (peace_minded(mtmp->data))
  49.              continue;
  50.          /* Don't create groups of peaceful monsters since they'll get
  51.           * in our way.  If the monster has a percentage chance so some
  52.           * are peaceful and some are not, the result will just be a
  53.           * smaller group.
  54.           */
  55.          if (enexto(&mm, mm.x, mm.y, mtmp->data)) {
  56.              mon = makemon(mtmp->data, mm.x, mm.y, NO_MM_FLAGS);
  57.              if (mon) {
  58.                  mon->mpeaceful = FALSE;
  59.                  mon->mavenge = 0;
  60.                  set_malign(mon);
  61.                  /* Undo the second peace_minded() check in makemon(); if the
  62.                   * monster turned out to be peaceful the first time we
  63.                   * didn't create it at all; we don't want a second check.
  64.                   */
  65.              }
  66.          }
  67.      }
  68.  }
  69.  

m_initthrow

  1.  STATIC_OVL
  2.  void
  3.  m_initthrow(mtmp, otyp, oquan)
  4.  struct monst *mtmp;
  5.  int otyp, oquan;
  6.  {
  7.      register struct obj *otmp;
  8.  
  9.      otmp = mksobj(otyp, TRUE, FALSE);
  10.      otmp->quan = (long) rn1(oquan, 3);
  11.      otmp->owt = weight(otmp);
  12.      if (otyp == ORCISH_ARROW)
  13.          otmp->opoisoned = TRUE;
  14.      (void) mpickobj(mtmp, otmp);
  15.  }
  16.  

m_initweap

  1.  STATIC_OVL void
  2.  m_initweap(mtmp)
  3.  register struct monst *mtmp;
  4.  {
  5.      register struct permonst *ptr = mtmp->data;
  6.      register int mm = monsndx(ptr);
  7.      struct obj *otmp;
  8.      int bias, spe2, w1, w2;
  9.  
  10.      if (Is_rogue_level(&u.uz))
  11.          return;
  12.      /*
  13.       *  First a few special cases:
  14.       *          giants get a boulder to throw sometimes
  15.       *          ettins get clubs
  16.       *          kobolds get darts to throw
  17.       *          centaurs get some sort of bow & arrows or bolts
  18.       *          soldiers get all sorts of things
  19.       *          kops get clubs & cream pies.
  20.       */
  21.      switch (ptr->mlet) {
  22.      case S_GIANT:
  23.          if (rn2(2))
  24.              (void) mongets(mtmp, (mm != PM_ETTIN) ? BOULDER : CLUB);
  25.          break;
  26.      case S_HUMAN:
  27.          if (is_mercenary(ptr)) {
  28.              w1 = w2 = 0;
  29.              switch (mm) {
  30.              case PM_WATCHMAN:
  31.              case PM_SOLDIER:
  32.                  if (!rn2(3)) {
  33.                      w1 = rn1(BEC_DE_CORBIN - PARTISAN + 1, PARTISAN);
  34.                      w2 = rn2(2) ? DAGGER : KNIFE;
  35.                  } else
  36.                      w1 = rn2(2) ? SPEAR : SHORT_SWORD;
  37.                  break;
  38.              case PM_SERGEANT:
  39.                  w1 = rn2(2) ? FLAIL : MACE;
  40.                  break;
  41.              case PM_LIEUTENANT:
  42.                  w1 = rn2(2) ? BROADSWORD : LONG_SWORD;
  43.                  break;
  44.              case PM_CAPTAIN:
  45.              case PM_WATCH_CAPTAIN:
  46.                  w1 = rn2(2) ? LONG_SWORD : SILVER_SABER;
  47.                  break;
  48.              default:
  49.                  if (!rn2(4))
  50.                      w1 = DAGGER;
  51.                  if (!rn2(7))
  52.                      w2 = SPEAR;
  53.                  break;
  54.              }
  55.              if (w1)
  56.                  (void) mongets(mtmp, w1);
  57.              if (!w2 && w1 != DAGGER && !rn2(4))
  58.                  w2 = KNIFE;
  59.              if (w2)
  60.                  (void) mongets(mtmp, w2);
  61.          } else if (is_elf(ptr)) {
  62.              if (rn2(2))
  63.                  (void) mongets(mtmp,
  64.                                 rn2(2) ? ELVEN_MITHRIL_COAT : ELVEN_CLOAK);
  65.              if (rn2(2))
  66.                  (void) mongets(mtmp, ELVEN_LEATHER_HELM);
  67.              else if (!rn2(4))
  68.                  (void) mongets(mtmp, ELVEN_BOOTS);
  69.              if (rn2(2))
  70.                  (void) mongets(mtmp, ELVEN_DAGGER);
  71.              switch (rn2(3)) {
  72.              case 0:
  73.                  if (!rn2(4))
  74.                      (void) mongets(mtmp, ELVEN_SHIELD);
  75.                  if (rn2(3))
  76.                      (void) mongets(mtmp, ELVEN_SHORT_SWORD);
  77.                  (void) mongets(mtmp, ELVEN_BOW);
  78.                  m_initthrow(mtmp, ELVEN_ARROW, 12);
  79.                  break;
  80.              case 1:
  81.                  (void) mongets(mtmp, ELVEN_BROADSWORD);
  82.                  if (rn2(2))
  83.                      (void) mongets(mtmp, ELVEN_SHIELD);
  84.                  break;
  85.              case 2:
  86.                  if (rn2(2)) {
  87.                      (void) mongets(mtmp, ELVEN_SPEAR);
  88.                      (void) mongets(mtmp, ELVEN_SHIELD);
  89.                  }
  90.                  break;
  91.              }
  92.              if (mm == PM_ELVENKING) {
  93.                  if (rn2(3) || (in_mklev && Is_earthlevel(&u.uz)))
  94.                      (void) mongets(mtmp, PICK_AXE);
  95.                  if (!rn2(50))
  96.                      (void) mongets(mtmp, CRYSTAL_BALL);
  97.              }
  98.          } else if (ptr->msound == MS_PRIEST
  99.                     || quest_mon_represents_role(ptr, PM_PRIEST)) {
  100.              otmp = mksobj(MACE, FALSE, FALSE);
  101.              if (otmp) {
  102.                  otmp->spe = rnd(3);
  103.                  if (!rn2(2))
  104.                      curse(otmp);
  105.                  (void) mpickobj(mtmp, otmp);
  106.              }
  107.          } else if (mm == PM_NINJA) { /* extra quest villains */
  108.              (void) mongets(mtmp, rn2(4) ? SHURIKEN : DART);
  109.              (void) mongets(mtmp, rn2(4) ? SHORT_SWORD : AXE);
  110.          }
  111.          break;
  112.  
  113.      case S_ANGEL:
  114.          if (humanoid(ptr)) {
  115.              /* create minion stuff; can't use mongets */
  116.              otmp = mksobj(LONG_SWORD, FALSE, FALSE);
  117.  
  118.              /* maybe make it special */
  119.              if (!rn2(20) || is_lord(ptr))
  120.                  otmp = oname(otmp,
  121.                               artiname(rn2(2) ? ART_DEMONBANE : ART_SUNSWORD));
  122.              bless(otmp);
  123.              otmp->oerodeproof = TRUE;
  124.              spe2 = rn2(4);
  125.              otmp->spe = max(otmp->spe, spe2);
  126.              (void) mpickobj(mtmp, otmp);
  127.  
  128.              otmp = mksobj(!rn2(4) || is_lord(ptr) ? SHIELD_OF_REFLECTION
  129.                                                    : LARGE_SHIELD,
  130.                            FALSE, FALSE);
  131.              otmp->cursed = FALSE;
  132.              otmp->oerodeproof = TRUE;
  133.              otmp->spe = 0;
  134.              (void) mpickobj(mtmp, otmp);
  135.          }
  136.          break;
  137.  
  138.      case S_HUMANOID:
  139.          if (mm == PM_HOBBIT) {
  140.              switch (rn2(3)) {
  141.              case 0:
  142.                  (void) mongets(mtmp, DAGGER);
  143.                  break;
  144.              case 1:
  145.                  (void) mongets(mtmp, ELVEN_DAGGER);
  146.                  break;
  147.              case 2:
  148.                  (void) mongets(mtmp, SLING);
  149.                  break;
  150.              }
  151.              if (!rn2(10))
  152.                  (void) mongets(mtmp, ELVEN_MITHRIL_COAT);
  153.              if (!rn2(10))
  154.                  (void) mongets(mtmp, DWARVISH_CLOAK);
  155.          } else if (is_dwarf(ptr)) {
  156.              if (rn2(7))
  157.                  (void) mongets(mtmp, DWARVISH_CLOAK);
  158.              if (rn2(7))
  159.                  (void) mongets(mtmp, IRON_SHOES);
  160.              if (!rn2(4)) {
  161.                  (void) mongets(mtmp, DWARVISH_SHORT_SWORD);
  162.                  /* note: you can't use a mattock with a shield */
  163.                  if (rn2(2))
  164.                      (void) mongets(mtmp, DWARVISH_MATTOCK);
  165.                  else {
  166.                      (void) mongets(mtmp, rn2(2) ? AXE : DWARVISH_SPEAR);
  167.                      (void) mongets(mtmp, DWARVISH_ROUNDSHIELD);
  168.                  }
  169.                  (void) mongets(mtmp, DWARVISH_IRON_HELM);
  170.                  if (!rn2(3))
  171.                      (void) mongets(mtmp, DWARVISH_MITHRIL_COAT);
  172.              } else {
  173.                  (void) mongets(mtmp, !rn2(3) ? PICK_AXE : DAGGER);
  174.              }
  175.          }
  176.          break;
  177.      case S_KOP:
  178.          /* create Keystone Kops with cream pies to
  179.             throw. As suggested by KAA.     [MRS] */
  180.          if (!rn2(4))
  181.              m_initthrow(mtmp, CREAM_PIE, 2);
  182.          if (!rn2(3))
  183.              (void) mongets(mtmp, (rn2(2)) ? CLUB : RUBBER_HOSE);
  184.          break;
  185.      case S_ORC:
  186.          if (rn2(2))
  187.              (void) mongets(mtmp, ORCISH_HELM);
  188.          switch ((mm != PM_ORC_CAPTAIN) ? mm
  189.                  : rn2(2) ? PM_MORDOR_ORC : PM_URUK_HAI) {
  190.          case PM_MORDOR_ORC:
  191.              if (!rn2(3))
  192.                  (void) mongets(mtmp, SCIMITAR);
  193.              if (!rn2(3))
  194.                  (void) mongets(mtmp, ORCISH_SHIELD);
  195.              if (!rn2(3))
  196.                  (void) mongets(mtmp, KNIFE);
  197.              if (!rn2(3))
  198.                  (void) mongets(mtmp, ORCISH_CHAIN_MAIL);
  199.              break;
  200.          case PM_URUK_HAI:
  201.              if (!rn2(3))
  202.                  (void) mongets(mtmp, ORCISH_CLOAK);
  203.              if (!rn2(3))
  204.                  (void) mongets(mtmp, ORCISH_SHORT_SWORD);
  205.              if (!rn2(3))
  206.                  (void) mongets(mtmp, IRON_SHOES);
  207.              if (!rn2(3)) {
  208.                  (void) mongets(mtmp, ORCISH_BOW);
  209.                  m_initthrow(mtmp, ORCISH_ARROW, 12);
  210.              }
  211.              if (!rn2(3))
  212.                  (void) mongets(mtmp, URUK_HAI_SHIELD);
  213.              break;
  214.          default:
  215.              if (mm != PM_ORC_SHAMAN && rn2(2))
  216.                  (void) mongets(mtmp, (mm == PM_GOBLIN || rn2(2) == 0)
  217.                                           ? ORCISH_DAGGER
  218.                                           : SCIMITAR);
  219.          }
  220.          break;
  221.      case S_OGRE:
  222.          if (!rn2(mm == PM_OGRE_KING ? 3 : mm == PM_OGRE_LORD ? 6 : 12))
  223.              (void) mongets(mtmp, BATTLE_AXE);
  224.          else
  225.              (void) mongets(mtmp, CLUB);
  226.          break;
  227.      case S_TROLL:
  228.          if (!rn2(2))
  229.              switch (rn2(4)) {
  230.              case 0:
  231.                  (void) mongets(mtmp, RANSEUR);
  232.                  break;
  233.              case 1:
  234.                  (void) mongets(mtmp, PARTISAN);
  235.                  break;
  236.              case 2:
  237.                  (void) mongets(mtmp, GLAIVE);
  238.                  break;
  239.              case 3:
  240.                  (void) mongets(mtmp, SPETUM);
  241.                  break;
  242.              }
  243.          break;
  244.      case S_KOBOLD:
  245.          if (!rn2(4))
  246.              m_initthrow(mtmp, DART, 12);
  247.          break;
  248.  
  249.      case S_CENTAUR:
  250.          if (rn2(2)) {
  251.              if (ptr == &mons[PM_FOREST_CENTAUR]) {
  252.                  (void) mongets(mtmp, BOW);
  253.                  m_initthrow(mtmp, ARROW, 12);
  254.              } else {
  255.                  (void) mongets(mtmp, CROSSBOW);
  256.                  m_initthrow(mtmp, CROSSBOW_BOLT, 12);
  257.              }
  258.          }
  259.          break;
  260.      case S_WRAITH:
  261.          (void) mongets(mtmp, KNIFE);
  262.          (void) mongets(mtmp, LONG_SWORD);
  263.          break;
  264.      case S_ZOMBIE:
  265.          if (!rn2(4))
  266.              (void) mongets(mtmp, LEATHER_ARMOR);
  267.          if (!rn2(4))
  268.              (void) mongets(mtmp, (rn2(3) ? KNIFE : SHORT_SWORD));
  269.          break;
  270.      case S_LIZARD:
  271.          if (mm == PM_SALAMANDER)
  272.              (void) mongets(mtmp,
  273.                             (rn2(7) ? SPEAR : rn2(3) ? TRIDENT : STILETTO));
  274.          break;
  275.      case S_DEMON:
  276.          switch (mm) {
  277.          case PM_BALROG:
  278.              (void) mongets(mtmp, BULLWHIP);
  279.              (void) mongets(mtmp, BROADSWORD);
  280.              break;
  281.          case PM_ORCUS:
  282.              (void) mongets(mtmp, WAN_DEATH); /* the Wand of Orcus */
  283.              break;
  284.          case PM_HORNED_DEVIL:
  285.              (void) mongets(mtmp, rn2(4) ? TRIDENT : BULLWHIP);
  286.              break;
  287.          case PM_DISPATER:
  288.              (void) mongets(mtmp, WAN_STRIKING);
  289.              break;
  290.          case PM_YEENOGHU:
  291.              (void) mongets(mtmp, FLAIL);
  292.              break;
  293.          }
  294.          /* prevent djinn and mail daemons from leaving objects when
  295.           * they vanish
  296.           */
  297.          if (!is_demon(ptr))
  298.              break;
  299.          /*FALLTHRU*/
  300.      default:
  301.          /*
  302.           * Now the general case, some chance of getting some type
  303.           * of weapon for "normal" monsters.  Certain special types
  304.           * of monsters will get a bonus chance or different selections.
  305.           */
  306.          bias = is_lord(ptr) + is_prince(ptr) * 2 + extra_nasty(ptr);
  307.          switch (rnd(14 - (2 * bias))) {
  308.          case 1:
  309.              if (strongmonst(ptr))
  310.                  (void) mongets(mtmp, BATTLE_AXE);
  311.              else
  312.                  m_initthrow(mtmp, DART, 12);
  313.              break;
  314.          case 2:
  315.              if (strongmonst(ptr))
  316.                  (void) mongets(mtmp, TWO_HANDED_SWORD);
  317.              else {
  318.                  (void) mongets(mtmp, CROSSBOW);
  319.                  m_initthrow(mtmp, CROSSBOW_BOLT, 12);
  320.              }
  321.              break;
  322.          case 3:
  323.              (void) mongets(mtmp, BOW);
  324.              m_initthrow(mtmp, ARROW, 12);
  325.              break;
  326.          case 4:
  327.              if (strongmonst(ptr))
  328.                  (void) mongets(mtmp, LONG_SWORD);
  329.              else
  330.                  m_initthrow(mtmp, DAGGER, 3);
  331.              break;
  332.          case 5:
  333.              if (strongmonst(ptr))
  334.                  (void) mongets(mtmp, LUCERN_HAMMER);
  335.              else
  336.                  (void) mongets(mtmp, AKLYS);
  337.              break;
  338.          default:
  339.              break;
  340.          }
  341.          break;
  342.      }
  343.  
  344.      if ((int) mtmp->m_lev > rn2(75))
  345.          (void) mongets(mtmp, rnd_offensive_item(mtmp));
  346.  }
  347.  

mkmonmoney

  1.  /*
  2.   *   Makes up money for monster's inventory.
  3.   *   This will change with silver & copper coins
  4.   */
  5.  void
  6.  mkmonmoney(mtmp, amount)
  7.  struct monst *mtmp;
  8.  long amount;
  9.  {
  10.      struct obj *gold = mksobj(GOLD_PIECE, FALSE, FALSE);
  11.  
  12.      gold->quan = amount;
  13.      add_to_minv(mtmp, gold);
  14.  }
  15.  

m_initinv

  1.  STATIC_OVL void
  2.  m_initinv(mtmp)
  3.  register struct monst *mtmp;
  4.  {
  5.      register int cnt;
  6.      register struct obj *otmp;
  7.      register struct permonst *ptr = mtmp->data;
  8.  
  9.      if (Is_rogue_level(&u.uz))
  10.          return;
  11.      /*
  12.       *  Soldiers get armour & rations - armour approximates their ac.
  13.       *  Nymphs may get mirror or potion of object detection.
  14.       */
  15.      switch (ptr->mlet) {
  16.      case S_HUMAN:
  17.          if (is_mercenary(ptr)) {
  18.              register int mac;
  19.  
  20.              switch (monsndx(ptr)) {
  21.              case PM_GUARD:
  22.                  mac = -1;
  23.                  break;
  24.              case PM_SOLDIER:
  25.                  mac = 3;
  26.                  break;
  27.              case PM_SERGEANT:
  28.                  mac = 0;
  29.                  break;
  30.              case PM_LIEUTENANT:
  31.                  mac = -2;
  32.                  break;
  33.              case PM_CAPTAIN:
  34.                  mac = -3;
  35.                  break;
  36.              case PM_WATCHMAN:
  37.                  mac = 3;
  38.                  break;
  39.              case PM_WATCH_CAPTAIN:
  40.                  mac = -2;
  41.                  break;
  42.              default:
  43.                  impossible("odd mercenary %d?", monsndx(ptr));
  44.                  mac = 0;
  45.                  break;
  46.              }
  47.  
  48.              if (mac < -1 && rn2(5))
  49.                  mac += 7 + mongets(mtmp, (rn2(5)) ? PLATE_MAIL
  50.                                                    : CRYSTAL_PLATE_MAIL);
  51.              else if (mac < 3 && rn2(5))
  52.                  mac +=
  53.                      6 + mongets(mtmp, (rn2(3)) ? SPLINT_MAIL : BANDED_MAIL);
  54.              else if (rn2(5))
  55.                  mac += 3 + mongets(mtmp, (rn2(3)) ? RING_MAIL
  56.                                                    : STUDDED_LEATHER_ARMOR);
  57.              else
  58.                  mac += 2 + mongets(mtmp, LEATHER_ARMOR);
  59.  
  60.              if (mac < 10 && rn2(3))
  61.                  mac += 1 + mongets(mtmp, HELMET);
  62.              else if (mac < 10 && rn2(2))
  63.                  mac += 1 + mongets(mtmp, DENTED_POT);
  64.              if (mac < 10 && rn2(3))
  65.                  mac += 1 + mongets(mtmp, SMALL_SHIELD);
  66.              else if (mac < 10 && rn2(2))
  67.                  mac += 2 + mongets(mtmp, LARGE_SHIELD);
  68.              if (mac < 10 && rn2(3))
  69.                  mac += 1 + mongets(mtmp, LOW_BOOTS);
  70.              else if (mac < 10 && rn2(2))
  71.                  mac += 2 + mongets(mtmp, HIGH_BOOTS);
  72.              if (mac < 10 && rn2(3))
  73.                  mac += 1 + mongets(mtmp, LEATHER_GLOVES);
  74.              else if (mac < 10 && rn2(2))
  75.                  mac += 1 + mongets(mtmp, LEATHER_CLOAK);
  76.  
  77.              if (ptr != &mons[PM_GUARD] && ptr != &mons[PM_WATCHMAN]
  78.                  && ptr != &mons[PM_WATCH_CAPTAIN]) {
  79.                  if (!rn2(3))
  80.                      (void) mongets(mtmp, K_RATION);
  81.                  if (!rn2(2))
  82.                      (void) mongets(mtmp, C_RATION);
  83.                  if (ptr != &mons[PM_SOLDIER] && !rn2(3))
  84.                      (void) mongets(mtmp, BUGLE);
  85.              } else if (ptr == &mons[PM_WATCHMAN] && rn2(3))
  86.                  (void) mongets(mtmp, TIN_WHISTLE);
  87.          } else if (ptr == &mons[PM_SHOPKEEPER]) {
  88.              (void) mongets(mtmp, SKELETON_KEY);
  89.              switch (rn2(4)) {
  90.              /* MAJOR fall through ... */
  91.              case 0:
  92.                  (void) mongets(mtmp, WAN_MAGIC_MISSILE);
  93.              case 1:
  94.                  (void) mongets(mtmp, POT_EXTRA_HEALING);
  95.              case 2:
  96.                  (void) mongets(mtmp, POT_HEALING);
  97.              case 3:
  98.                  (void) mongets(mtmp, WAN_STRIKING);
  99.              }
  100.          } else if (ptr->msound == MS_PRIEST
  101.                     || quest_mon_represents_role(ptr, PM_PRIEST)) {
  102.              (void) mongets(mtmp, rn2(7) ? ROBE
  103.                                          : rn2(3) ? CLOAK_OF_PROTECTION
  104.                                                   : CLOAK_OF_MAGIC_RESISTANCE);
  105.              (void) mongets(mtmp, SMALL_SHIELD);
  106.              mkmonmoney(mtmp, (long) rn1(10, 20));
  107.          } else if (quest_mon_represents_role(ptr, PM_MONK)) {
  108.              (void) mongets(mtmp, rn2(11) ? ROBE : CLOAK_OF_MAGIC_RESISTANCE);
  109.          }
  110.          break;
  111.      case S_NYMPH:
  112.          if (!rn2(2))
  113.              (void) mongets(mtmp, MIRROR);
  114.          if (!rn2(2))
  115.              (void) mongets(mtmp, POT_OBJECT_DETECTION);
  116.          break;
  117.      case S_GIANT:
  118.          if (ptr == &mons[PM_MINOTAUR]) {
  119.              if (!rn2(3) || (in_mklev && Is_earthlevel(&u.uz)))
  120.                  (void) mongets(mtmp, WAN_DIGGING);
  121.          } else if (is_giant(ptr)) {
  122.              for (cnt = rn2((int) (mtmp->m_lev / 2)); cnt; cnt--) {
  123.                  otmp = mksobj(rnd_class(DILITHIUM_CRYSTAL, LUCKSTONE - 1),
  124.                                FALSE, FALSE);
  125.                  otmp->quan = (long) rn1(2, 3);
  126.                  otmp->owt = weight(otmp);
  127.                  (void) mpickobj(mtmp, otmp);
  128.              }
  129.          }
  130.          break;
  131.      case S_WRAITH:
  132.          if (ptr == &mons[PM_NAZGUL]) {
  133.              otmp = mksobj(RIN_INVISIBILITY, FALSE, FALSE);
  134.              curse(otmp);
  135.              (void) mpickobj(mtmp, otmp);
  136.          }
  137.          break;
  138.      case S_LICH:
  139.          if (ptr == &mons[PM_MASTER_LICH] && !rn2(13))
  140.              (void) mongets(mtmp, (rn2(7) ? ATHAME : WAN_NOTHING));
  141.          else if (ptr == &mons[PM_ARCH_LICH] && !rn2(3)) {
  142.              otmp = mksobj(rn2(3) ? ATHAME : QUARTERSTAFF, TRUE,
  143.                            rn2(13) ? FALSE : TRUE);
  144.              if (otmp->spe < 2)
  145.                  otmp->spe = rnd(3);
  146.              if (!rn2(4))
  147.                  otmp->oerodeproof = 1;
  148.              (void) mpickobj(mtmp, otmp);
  149.          }
  150.          break;
  151.      case S_MUMMY:
  152.          if (rn2(7))
  153.              (void) mongets(mtmp, MUMMY_WRAPPING);
  154.          break;
  155.      case S_QUANTMECH:
  156.          if (!rn2(20)) {
  157.              otmp = mksobj(LARGE_BOX, FALSE, FALSE);
  158.              otmp->spe = 1; /* flag for special box */
  159.              otmp->owt = weight(otmp);
  160.              (void) mpickobj(mtmp, otmp);
  161.          }
  162.          break;
  163.      case S_LEPRECHAUN:
  164.          mkmonmoney(mtmp, (long) d(level_difficulty(), 30));
  165.          break;
  166.      case S_DEMON:
  167.          /* moved here from m_initweap() because these don't
  168.             have AT_WEAP so m_initweap() is not called for them */
  169.          if (ptr == &mons[PM_ICE_DEVIL] && !rn2(4)) {
  170.              (void) mongets(mtmp, SPEAR);
  171.          } else if (ptr == &mons[PM_ASMODEUS]) {
  172.              (void) mongets(mtmp, WAN_COLD);
  173.              (void) mongets(mtmp, WAN_FIRE);
  174.          }
  175.          break;
  176.      case S_GNOME:
  177.          if (!rn2((In_mines(&u.uz) && in_mklev) ? 20 : 60)) {
  178.              otmp = mksobj(rn2(4) ? TALLOW_CANDLE : WAX_CANDLE, TRUE, FALSE);
  179.              otmp->quan = 1;
  180.              otmp->owt = weight(otmp);
  181.              if (!mpickobj(mtmp, otmp) && !levl[mtmp->mx][mtmp->my].lit)
  182.                  begin_burn(otmp, FALSE);
  183.          }
  184.          break;
  185.      default:
  186.          break;
  187.      }
  188.  
  189.      /* ordinary soldiers rarely have access to magic (or gold :-) */
  190.      if (ptr == &mons[PM_SOLDIER] && rn2(13))
  191.          return;
  192.  
  193.      if ((int) mtmp->m_lev > rn2(50))
  194.          (void) mongets(mtmp, rnd_defensive_item(mtmp));
  195.      if ((int) mtmp->m_lev > rn2(100))
  196.          (void) mongets(mtmp, rnd_misc_item(mtmp));
  197.      if (likes_gold(ptr) && !findgold(mtmp->minvent) && !rn2(5))
  198.          mkmonmoney(mtmp,
  199.                     (long) d(level_difficulty(), mtmp->minvent ? 5 : 10));
  200.  }
  201.  

clone_mon

  1.  /* Note: for long worms, always call cutworm (cutworm calls clone_mon) */
  2.  struct monst *
  3.  clone_mon(mon, x, y)
  4.  struct monst *mon;
  5.  xchar x, y; /* clone's preferred location or 0 (near mon) */
  6.  {
  7.      coord mm;
  8.      struct monst *m2;
  9.  
  10.      /* may be too weak or have been extinguished for population control */
  11.      if (mon->mhp <= 1 || (mvitals[monsndx(mon->data)].mvflags & G_EXTINCT))
  12.          return (struct monst *) 0;
  13.  
  14.      if (x == 0) {
  15.          mm.x = mon->mx;
  16.          mm.y = mon->my;
  17.          if (!enexto(&mm, mm.x, mm.y, mon->data) || MON_AT(mm.x, mm.y))
  18.              return (struct monst *) 0;
  19.      } else if (!isok(x, y)) {
  20.          return (struct monst *) 0; /* paranoia */
  21.      } else {
  22.          mm.x = x;
  23.          mm.y = y;
  24.          if (MON_AT(mm.x, mm.y)) {
  25.              if (!enexto(&mm, mm.x, mm.y, mon->data) || MON_AT(mm.x, mm.y))
  26.                  return (struct monst *) 0;
  27.          }
  28.      }
  29.      m2 = newmonst();
  30.      *m2 = *mon; /* copy condition of old monster */
  31.      m2->mextra = (struct mextra *) 0;
  32.      m2->nmon = fmon;
  33.      fmon = m2;
  34.      m2->m_id = context.ident++;
  35.      if (!m2->m_id)
  36.          m2->m_id = context.ident++; /* ident overflowed */
  37.      m2->mx = mm.x;
  38.      m2->my = mm.y;
  39.  
  40.      m2->mcloned = 1;
  41.      m2->minvent = (struct obj *) 0; /* objects don't clone */
  42.      m2->mleashed = FALSE;
  43.      /* Max HP the same, but current HP halved for both.  The caller
  44.       * might want to override this by halving the max HP also.
  45.       * When current HP is odd, the original keeps the extra point.
  46.       */
  47.      m2->mhpmax = mon->mhpmax;
  48.      m2->mhp = mon->mhp / 2;
  49.      mon->mhp -= m2->mhp;
  50.  
  51.      /* since shopkeepers and guards will only be cloned if they've been
  52.       * polymorphed away from their original forms, the clone doesn't have
  53.       * room for the extra information.  we also don't want two shopkeepers
  54.       * around for the same shop.
  55.       */
  56.      if (mon->isshk)
  57.          m2->isshk = FALSE;
  58.      if (mon->isgd)
  59.          m2->isgd = FALSE;
  60.      if (mon->ispriest)
  61.          m2->ispriest = FALSE;
  62.      place_monster(m2, m2->mx, m2->my);
  63.      if (emits_light(m2->data))
  64.          new_light_source(m2->mx, m2->my, emits_light(m2->data), LS_MONSTER,
  65.                           monst_to_any(m2));
  66.      if (has_mname(mon)) {
  67.          m2 = christen_monst(m2, MNAME(mon));
  68.      } else if (mon->isshk) {
  69.          m2 = christen_monst(m2, shkname(mon));
  70.      }
  71.  
  72.      /* not all clones caused by player are tame or peaceful */
  73.      if (!context.mon_moving) {
  74.          if (mon->mtame)
  75.              m2->mtame = rn2(max(2 + u.uluck, 2)) ? mon->mtame : 0;
  76.          else if (mon->mpeaceful)
  77.              m2->mpeaceful = rn2(max(2 + u.uluck, 2)) ? 1 : 0;
  78.      }
  79.  
  80.      newsym(m2->mx, m2->my); /* display the new monster */
  81.      if (m2->mtame) {
  82.          if (mon->isminion) {
  83.              newemin(m2);
  84.              if (EMIN(mon))
  85.                  *(EMIN(m2)) = *(EMIN(mon));
  86.          } else {
  87.              /* because m2 is a copy of mon it is tame but not init'ed.
  88.               * however, tamedog will not re-tame a tame dog, so m2
  89.               * must be made non-tame to get initialized properly.
  90.               */
  91.              m2->mtame = 0;
  92.              if (tamedog(m2, (struct obj *) 0)) {
  93.                  *(EDOG(m2)) = *(EDOG(mon));
  94.              }
  95.          }
  96.      }
  97.      set_malign(m2);
  98.  
  99.      return m2;
  100.  }
  101.  

propagate

  1.  /*
  2.   * Propagate a species
  3.   *
  4.   * Once a certain number of monsters are created, don't create any more
  5.   * at random (i.e. make them extinct).  The previous (3.2) behavior was
  6.   * to do this when a certain number had _died_, which didn't make
  7.   * much sense.
  8.   *
  9.   * Returns FALSE propagation unsuccessful
  10.   *         TRUE  propagation successful
  11.   */
  12.  boolean
  13.  propagate(mndx, tally, ghostly)
  14.  int mndx;
  15.  boolean tally;
  16.  boolean ghostly;
  17.  {
  18.      boolean result;
  19.      uchar lim = mbirth_limit(mndx);
  20.      boolean gone = (mvitals[mndx].mvflags & G_GONE) != 0; /* geno'd|extinct */
  21.  
  22.      result = (((int) mvitals[mndx].born < lim) && !gone) ? TRUE : FALSE;
  23.  
  24.      /* if it's unique, don't ever make it again */
  25.      if (mons[mndx].geno & G_UNIQ)
  26.          mvitals[mndx].mvflags |= G_EXTINCT;
  27.  
  28.      if (mvitals[mndx].born < 255 && tally
  29.          && (!ghostly || (ghostly && result)))
  30.          mvitals[mndx].born++;
  31.      if ((int) mvitals[mndx].born >= lim && !(mons[mndx].geno & G_NOGEN)
  32.          && !(mvitals[mndx].mvflags & G_EXTINCT)) {
  33.          if (wizard) {
  34.              debugpline1("Automatically extinguished %s.",
  35.                          makeplural(mons[mndx].mname));
  36.          }
  37.          mvitals[mndx].mvflags |= G_EXTINCT;
  38.          reset_rndmonst(mndx);
  39.      }
  40.      return result;
  41.  }
  42.  

monhp_per_lvl

  1.  /* amount of HP to lose from level drain (or gain from Stormbringer) */
  2.  int
  3.  monhp_per_lvl(mon)
  4.  struct monst *mon;
  5.  {
  6.      struct permonst *ptr = mon->data;
  7.      int hp = rnd(8); /* default is d8 */
  8.  
  9.      /* like newmonhp, but home elementals are ignored, riders use normal d8 */
  10.      if (is_golem(ptr)) {
  11.          /* draining usually won't be applicable for these critters */
  12.          hp = golemhp(monsndx(ptr)) / (int) ptr->mlevel;
  13.      } else if (ptr->mlevel > 49) {
  14.          /* arbitrary; such monsters won't be involved in draining anyway */
  15.          hp = 4 + rnd(4); /* 5..8 */
  16.      } else if (ptr->mlet == S_DRAGON && monsndx(ptr) >= PM_GRAY_DRAGON) {
  17.          /* adult dragons; newmonhp() uses In_endgame(&u.uz) ? 8 : 4 + rnd(4)
  18.           */
  19.          hp = 4 + rn2(5); /* 4..8 */
  20.      } else if (!mon->m_lev) {
  21.          /* level 0 monsters use 1d4 instead of Nd8 */
  22.          hp = rnd(4);
  23.      }
  24.      return hp;
  25.  }
  26.  

newmonhp

  1.  /* set up a new monster's initial level and hit points;
  2.     used by newcham() as well as by makemon() */
  3.  void
  4.  newmonhp(mon, mndx)
  5.  struct monst *mon;
  6.  int mndx;
  7.  {
  8.      struct permonst *ptr = &mons[mndx];
  9.  
  10.      mon->m_lev = adj_lev(ptr);
  11.      if (is_golem(ptr)) {
  12.          mon->mhpmax = mon->mhp = golemhp(mndx);
  13.      } else if (is_rider(ptr)) {
  14.          /* we want low HP, but a high mlevel so they can attack well */
  15.          mon->mhpmax = mon->mhp = d(10, 8);
  16.      } else if (ptr->mlevel > 49) {
  17.          /* "special" fixed hp monster
  18.           * the hit points are encoded in the mlevel in a somewhat strange
  19.           * way to fit in the 50..127 positive range of a signed character
  20.           * above the 1..49 that indicate "normal" monster levels */
  21.          mon->mhpmax = mon->mhp = 2 * (ptr->mlevel - 6);
  22.          mon->m_lev = mon->mhp / 4; /* approximation */
  23.      } else if (ptr->mlet == S_DRAGON && mndx >= PM_GRAY_DRAGON) {
  24.          /* adult dragons */
  25.          mon->mhpmax = mon->mhp =
  26.              (int) (In_endgame(&u.uz)
  27.                         ? (8 * mon->m_lev)
  28.                         : (4 * mon->m_lev + d((int) mon->m_lev, 4)));
  29.      } else if (!mon->m_lev) {
  30.          mon->mhpmax = mon->mhp = rnd(4);
  31.      } else {
  32.          mon->mhpmax = mon->mhp = d((int) mon->m_lev, 8);
  33.          if (is_home_elemental(ptr))
  34.              mon->mhpmax = (mon->mhp *= 3);
  35.      }
  36.  }
  37.  

newmextra

  1.  struct mextra *
  2.  newmextra()
  3.  {
  4.      struct mextra *mextra;
  5.  
  6.      mextra = (struct mextra *) alloc(sizeof(struct mextra));
  7.      mextra->mname = 0;
  8.      mextra->egd = 0;
  9.      mextra->epri = 0;
  10.      mextra->eshk = 0;
  11.      mextra->emin = 0;
  12.      mextra->edog = 0;
  13.      mextra->mcorpsenm = NON_PM;
  14.      return mextra;
  15.  }
  16.  

makemon_rnd_goodpos

  1.  boolean
  2.  makemon_rnd_goodpos(mon, gpflags, cc)
  3.  struct monst *mon;
  4.  unsigned gpflags;
  5.  coord *cc;
  6.  {
  7.      int tryct = 0;
  8.      int nx,ny;
  9.      boolean good;
  10.  
  11.      do {
  12.          nx = rn1(COLNO - 3, 2);
  13.          ny = rn2(ROWNO);
  14.          good = (!in_mklev && cansee(nx,ny)) ? FALSE
  15.                                              : goodpos(nx, ny, mon, gpflags);
  16.      } while ((++tryct < 50) && !good);
  17.  
  18.      if (!good) {
  19.          /* else go through all map positions, twice, first round
  20.             ignoring positions in sight, and pick first good one.
  21.             skip first round if we're in special level loader or blind */
  22.          int xofs = nx;
  23.          int yofs = ny;
  24.          int dx,dy;
  25.          int bl = (in_mklev || Blind) ? 1 : 0;
  26.  
  27.          for ( ; bl < 2; bl++) {
  28.              for (dx = 0; dx < COLNO; dx++)
  29.                  for (dy = 0; dy < ROWNO; dy++) {
  30.                      nx = ((dx + xofs) % (COLNO - 1)) + 1;
  31.                      ny = ((dy + yofs) % (ROWNO - 1)) + 1;
  32.                      if (bl == 0 && cansee(nx,ny))
  33.                          continue;
  34.                      if (goodpos(nx, ny, mon, gpflags))
  35.                          goto gotgood;
  36.                  }
  37.              if (bl == 0 && (!mon || mon->data->mmove)) {
  38.                  /* all map positions are visible (or not good),
  39.                     try to pick something logical */
  40.                  if (dnstair.sx && !rn2(2)) {
  41.                      nx = dnstair.sx;
  42.                      ny = dnstair.sy;
  43.                  } else if (upstair.sx && !rn2(2)) {
  44.                      nx = upstair.sx;
  45.                      ny = upstair.sy;
  46.                  } else if (dnladder.sx && !rn2(2)) {
  47.                      nx = dnladder.sx;
  48.                      ny = dnladder.sy;
  49.                  } else if (upladder.sx && !rn2(2)) {
  50.                      nx = upladder.sx;
  51.                      ny = upladder.sy;
  52.                  }
  53.                  if (goodpos(nx, ny, mon, gpflags))
  54.                      goto gotgood;
  55.              }
  56.          }
  57.      } else {
  58.      gotgood:
  59.          cc->x = nx;
  60.          cc->y = ny;
  61.          return TRUE;
  62.      }
  63.      return FALSE;
  64.  }
  65.  

makemon

  1.  /*
  2.   * called with [x,y] = coordinates;
  3.   *      [0,0] means anyplace
  4.   *      [u.ux,u.uy] means: near player (if !in_mklev)
  5.   *
  6.   *      In case we make a monster group, only return the one at [x,y].
  7.   */
  8.  struct monst *
  9.  makemon(ptr, x, y, mmflags)
  10.  register struct permonst *ptr;
  11.  register int x, y;
  12.  int mmflags;
  13.  {
  14.      register struct monst *mtmp;
  15.      int mndx, mcham, ct, mitem;
  16.      boolean anymon = (!ptr);
  17.      boolean byyou = (x == u.ux && y == u.uy);
  18.      boolean allow_minvent = ((mmflags & NO_MINVENT) == 0);
  19.      boolean countbirth = ((mmflags & MM_NOCOUNTBIRTH) == 0);
  20.      unsigned gpflags = (mmflags & MM_IGNOREWATER) ? MM_IGNOREWATER : 0;
  21.  
  22.      /* if caller wants random location, do it here */
  23.      if (x == 0 && y == 0) {
  24.          coord cc;
  25.          struct monst fakemon;
  26.  
  27.          cc.x = cc.y = 0; /* lint suppression */
  28.          fakemon.data = ptr; /* set up for goodpos */
  29.          if (!makemon_rnd_goodpos(ptr ? &fakemon : (struct monst *)0,
  30.                                   gpflags, &cc))
  31.              return (struct monst *) 0;
  32.          x = cc.x;
  33.          y = cc.y;
  34.      } else if (byyou && !in_mklev) {
  35.          coord bypos;
  36.  
  37.          if (enexto_core(&bypos, u.ux, u.uy, ptr, gpflags)) {
  38.              x = bypos.x;
  39.              y = bypos.y;
  40.          } else
  41.              return (struct monst *) 0;
  42.      }
  43.  
  44.      /* Does monster already exist at the position? */
  45.      if (MON_AT(x, y)) {
  46.          if ((mmflags & MM_ADJACENTOK) != 0) {
  47.              coord bypos;
  48.              if (enexto_core(&bypos, x, y, ptr, gpflags)) {
  49.                  x = bypos.x;
  50.                  y = bypos.y;
  51.              } else
  52.                  return (struct monst *) 0;
  53.          } else
  54.              return (struct monst *) 0;
  55.      }
  56.  
  57.      if (ptr) {
  58.          mndx = monsndx(ptr);
  59.          /* if you are to make a specific monster and it has
  60.             already been genocided, return */
  61.          if (mvitals[mndx].mvflags & G_GENOD)
  62.              return (struct monst *) 0;
  63.          if (wizard && (mvitals[mndx].mvflags & G_EXTINCT)) {
  64.              debugpline1("Explicitly creating extinct monster %s.",
  65.                          mons[mndx].mname);
  66.          }
  67.      } else {
  68.          /* make a random (common) monster that can survive here.
  69.           * (the special levels ask for random monsters at specific
  70.           * positions, causing mass drowning on the medusa level,
  71.           * for instance.)
  72.           */
  73.          int tryct = 0; /* maybe there are no good choices */
  74.          struct monst fakemon;
  75.  
  76.          do {
  77.              if (!(ptr = rndmonst())) {
  78.                  debugpline0("Warning: no monster.");
  79.                  return (struct monst *) 0; /* no more monsters! */
  80.              }
  81.              fakemon.data = ptr; /* set up for goodpos */
  82.          } while (++tryct <= 50
  83.                   /* in Sokoban, don't accept a giant on first try;
  84.                      after that, boulder carriers are fair game */
  85.                   && ((tryct == 1 && throws_rocks(ptr) && In_sokoban(&u.uz))
  86.                       || !goodpos(x, y, &fakemon, gpflags)));
  87.          mndx = monsndx(ptr);
  88.      }
  89.      (void) propagate(mndx, countbirth, FALSE);
  90.      mtmp = newmonst();
  91.      *mtmp = zeromonst; /* clear all entries in structure */
  92.  
  93.      if (mmflags & MM_EGD)
  94.          newegd(mtmp);
  95.      if (mmflags & MM_EPRI)
  96.          newepri(mtmp);
  97.      if (mmflags & MM_ESHK)
  98.          neweshk(mtmp);
  99.      if (mmflags & MM_EMIN)
  100.          newemin(mtmp);
  101.      if (mmflags & MM_EDOG)
  102.          newedog(mtmp);
  103.  
  104.      mtmp->nmon = fmon;
  105.      fmon = mtmp;
  106.      mtmp->m_id = context.ident++;
  107.      if (!mtmp->m_id)
  108.          mtmp->m_id = context.ident++; /* ident overflowed */
  109.      set_mon_data(mtmp, ptr, 0);
  110.      if (ptr->msound == MS_LEADER && quest_info(MS_LEADER) == mndx)
  111.          quest_status.leader_m_id = mtmp->m_id;
  112.      mtmp->mnum = mndx;
  113.  
  114.      /* set up level and hit points */
  115.      newmonhp(mtmp, mndx);
  116.  
  117.      if (is_female(ptr))
  118.          mtmp->female = TRUE;
  119.      else if (is_male(ptr))
  120.          mtmp->female = FALSE;
  121.      /* leader and nemesis gender is usually hardcoded in mons[],
  122.         but for ones which can be random, it has already been chosen
  123.         (in role_init(), for possible use by the quest pager code) */
  124.      else if (ptr->msound == MS_LEADER && quest_info(MS_LEADER) == mndx)
  125.          mtmp->female = quest_status.ldrgend;
  126.      else if (ptr->msound == MS_NEMESIS && quest_info(MS_NEMESIS) == mndx)
  127.          mtmp->female = quest_status.nemgend;
  128.      else
  129.          mtmp->female = rn2(2); /* ignored for neuters */
  130.  
  131.      if (In_sokoban(&u.uz) && !mindless(ptr)) /* know about traps here */
  132.          mtmp->mtrapseen = (1L << (PIT - 1)) | (1L << (HOLE - 1));
  133.      /* quest leader and nemesis both know about all trap types */
  134.      if (ptr->msound == MS_LEADER || ptr->msound == MS_NEMESIS)
  135.          mtmp->mtrapseen = ~0;
  136.  
  137.      place_monster(mtmp, x, y);
  138.      mtmp->mcansee = mtmp->mcanmove = TRUE;
  139.      mtmp->mpeaceful = (mmflags & MM_ANGRY) ? FALSE : peace_minded(ptr);
  140.  
  141.      switch (ptr->mlet) {
  142.      case S_MIMIC:
  143.          set_mimic_sym(mtmp);
  144.          break;
  145.      case S_SPIDER:
  146.      case S_SNAKE:
  147.          if (in_mklev)
  148.              if (x && y)
  149.                  (void) mkobj_at(0, x, y, TRUE);
  150.          (void) hideunder(mtmp);
  151.          break;
  152.      case S_LIGHT:
  153.      case S_ELEMENTAL:
  154.          if (mndx == PM_STALKER || mndx == PM_BLACK_LIGHT) {
  155.              mtmp->perminvis = TRUE;
  156.              mtmp->minvis = TRUE;
  157.          }
  158.          break;
  159.      case S_EEL:
  160.          (void) hideunder(mtmp);
  161.          break;
  162.      case S_LEPRECHAUN:
  163.          mtmp->msleeping = 1;
  164.          break;
  165.      case S_JABBERWOCK:
  166.      case S_NYMPH:
  167.          if (rn2(5) && !u.uhave.amulet)
  168.              mtmp->msleeping = 1;
  169.          break;
  170.      case S_ORC:
  171.          if (Race_if(PM_ELF))
  172.              mtmp->mpeaceful = FALSE;
  173.          break;
  174.      case S_UNICORN:
  175.          if (is_unicorn(ptr) && sgn(u.ualign.type) == sgn(ptr->maligntyp))
  176.              mtmp->mpeaceful = TRUE;
  177.          break;
  178.      case S_BAT:
  179.          if (Inhell && is_bat(ptr))
  180.              mon_adjust_speed(mtmp, 2, (struct obj *) 0);
  181.          break;
  182.      }
  183.      if ((ct = emits_light(mtmp->data)) > 0)
  184.          new_light_source(mtmp->mx, mtmp->my, ct, LS_MONSTER,
  185.                           monst_to_any(mtmp));
  186.      mitem = 0; /* extra inventory item for this monster */
  187.  
  188.      if (mndx == PM_VLAD_THE_IMPALER)
  189.          mitem = CANDELABRUM_OF_INVOCATION;
  190.      mtmp->cham = NON_PM; /* default is "not a shapechanger" */
  191.      if ((mcham = pm_to_cham(mndx)) != NON_PM) {
  192.          /* this is a shapechanger after all */
  193.          if (Protection_from_shape_changers
  194.              || mndx == PM_VLAD_THE_IMPALER) {
  195.              ; /* stuck in its natural form (NON_PM) */
  196.          } else {
  197.              mtmp->cham = mcham;
  198.              /* Note: shapechanger's initial form used to be
  199.                 chosen here with rndmonst(), yielding a monster
  200.                 which was appropriate to the level's difficulty
  201.                 but ignored the changer's usual type selection
  202.                 so would be inappropriate for vampshifters.
  203.                 Let newcham() pick the shape. */
  204.              if (newcham(mtmp, (struct permonst *) 0, FALSE, FALSE))
  205.                  allow_minvent = FALSE;
  206.          }
  207.      } else if (mndx == PM_WIZARD_OF_YENDOR) {
  208.          mtmp->iswiz = TRUE;
  209.          context.no_of_wizards++;
  210.          if (context.no_of_wizards == 1 && Is_earthlevel(&u.uz))
  211.              mitem = SPE_DIG;
  212.      } else if (mndx == PM_GHOST && !(mmflags & MM_NONAME)) {
  213.          mtmp = christen_monst(mtmp, rndghostname());
  214.      } else if (mndx == PM_CROESUS) {
  215.          mitem = TWO_HANDED_SWORD;
  216.      } else if (ptr->msound == MS_NEMESIS) {
  217.          mitem = BELL_OF_OPENING;
  218.      } else if (mndx == PM_PESTILENCE) {
  219.          mitem = POT_SICKNESS;
  220.      }
  221.      if (mitem && allow_minvent)
  222.          (void) mongets(mtmp, mitem);
  223.  
  224.      if (in_mklev) {
  225.          if ((is_ndemon(ptr) || mndx == PM_WUMPUS
  226.               || mndx == PM_LONG_WORM || mndx == PM_GIANT_EEL)
  227.              && !u.uhave.amulet && rn2(5))
  228.              mtmp->msleeping = TRUE;
  229.      } else {
  230.          if (byyou) {
  231.              newsym(mtmp->mx, mtmp->my);
  232.              set_apparxy(mtmp);
  233.          }
  234.      }
  235.      if (is_dprince(ptr) && ptr->msound == MS_BRIBE) {
  236.          mtmp->mpeaceful = mtmp->minvis = mtmp->perminvis = 1;
  237.          mtmp->mavenge = 0;
  238.          if (uwep && uwep->oartifact == ART_EXCALIBUR)
  239.              mtmp->mpeaceful = mtmp->mtame = FALSE;
  240.      }
  241.  #ifndef DCC30_BUG
  242.      if (mndx == PM_LONG_WORM && (mtmp->wormno = get_wormno()) != 0)
  243.  #else
  244.      /* DICE 3.0 doesn't like assigning and comparing mtmp->wormno in the
  245.         same expression. */
  246.      if (mndx == PM_LONG_WORM
  247.          && (mtmp->wormno = get_wormno(), mtmp->wormno != 0))
  248.  #endif
  249.      {
  250.          /* we can now create worms with tails - 11/91 */
  251.          initworm(mtmp, rn2(5));
  252.          if (count_wsegs(mtmp))
  253.              place_worm_tail_randomly(mtmp, x, y);
  254.      }
  255.      /* it's possible to create an ordinary monster of some special
  256.         types; make sure their extended data is initialized to
  257.         something sensible if caller hasn't specified MM_EPRI|MM_EMIN
  258.         (when they're specified, caller intends to handle this itself) */
  259.      if ((mndx == PM_ALIGNED_PRIEST || mndx == PM_HIGH_PRIEST)
  260.              ? !(mmflags & (MM_EPRI | MM_EMIN))
  261.              : (mndx == PM_ANGEL && !(mmflags & MM_EMIN) && !rn2(3))) {
  262.          struct emin *eminp;
  263.          newemin(mtmp);
  264.          eminp = EMIN(mtmp);
  265.  
  266.          mtmp->isminion = 1;            /* make priest be a roamer */
  267.          eminp->min_align = rn2(3) - 1; /* no A_NONE */
  268.          eminp->renegade = (boolean) ((mmflags & MM_ANGRY) ? 1 : !rn2(3));
  269.          mtmp->mpeaceful = (eminp->min_align == u.ualign.type)
  270.                                ? !eminp->renegade
  271.                                : eminp->renegade;
  272.      }
  273.      set_malign(mtmp); /* having finished peaceful changes */
  274.      if (anymon) {
  275.          if ((ptr->geno & G_SGROUP) && rn2(2)) {
  276.              m_initsgrp(mtmp, mtmp->mx, mtmp->my);
  277.          } else if (ptr->geno & G_LGROUP) {
  278.              if (rn2(3))
  279.                  m_initlgrp(mtmp, mtmp->mx, mtmp->my);
  280.              else
  281.                  m_initsgrp(mtmp, mtmp->mx, mtmp->my);
  282.          }
  283.      }
  284.  
  285.      if (allow_minvent) {
  286.          if (is_armed(ptr))
  287.              m_initweap(mtmp); /* equip with weapons / armor */
  288.          m_initinv(mtmp); /* add on a few special items incl. more armor */
  289.          m_dowear(mtmp, TRUE);
  290.      } else {
  291.          /* no initial inventory is allowed */
  292.          if (mtmp->minvent)
  293.              discard_minvent(mtmp);
  294.          mtmp->minvent = (struct obj *) 0; /* caller expects this */
  295.      }
  296.      if (ptr->mflags3 && !(mmflags & MM_NOWAIT)) {
  297.          if (ptr->mflags3 & M3_WAITFORU)
  298.              mtmp->mstrategy |= STRAT_WAITFORU;
  299.          if (ptr->mflags3 & M3_CLOSE)
  300.              mtmp->mstrategy |= STRAT_CLOSE;
  301.          if (ptr->mflags3 & (M3_WAITMASK | M3_COVETOUS))
  302.              mtmp->mstrategy |= STRAT_APPEARMSG;
  303.      }
  304.  
  305.      if (!in_mklev)
  306.          newsym(mtmp->mx, mtmp->my); /* make sure the mon shows up */
  307.  
  308.      return mtmp;
  309.  }
  310.  

mbirth_limit

  1.  int
  2.  mbirth_limit(mndx)
  3.  int mndx;
  4.  {
  5.      /* assert(MAXMONNO < 255); */
  6.      return (mndx == PM_NAZGUL ? 9 : mndx == PM_ERINYS ? 3 : MAXMONNO);
  7.  }
  8.  

create_critters

  1.  /* used for wand/scroll/spell of create monster */
  2.  /* returns TRUE iff you know monsters have been created */
  3.  boolean
  4.  create_critters(cnt, mptr, neverask)
  5.  int cnt;
  6.  struct permonst *mptr; /* usually null; used for confused reading */
  7.  boolean neverask;
  8.  {
  9.      coord c;
  10.      int x, y;
  11.      struct monst *mon;
  12.      boolean known = FALSE;
  13.      boolean ask = (wizard && !neverask);
  14.  
  15.      while (cnt--) {
  16.          if (ask) {
  17.              if (create_particular()) {
  18.                  known = TRUE;
  19.                  continue;
  20.              } else
  21.                  ask = FALSE; /* ESC will shut off prompting */
  22.          }
  23.          x = u.ux, y = u.uy;
  24.          /* if in water, try to encourage an aquatic monster
  25.             by finding and then specifying another wet location */
  26.          if (!mptr && u.uinwater && enexto(&c, x, y, &mons[PM_GIANT_EEL]))
  27.              x = c.x, y = c.y;
  28.  
  29.          mon = makemon(mptr, x, y, NO_MM_FLAGS);
  30.          if (mon && canspotmon(mon))
  31.              known = TRUE;
  32.      }
  33.      return known;
  34.  }
  35.  

uncommon

  1.  STATIC_OVL boolean
  2.  uncommon(mndx)
  3.  int mndx;
  4.  {
  5.      if (mons[mndx].geno & (G_NOGEN | G_UNIQ))
  6.          return TRUE;
  7.      if (mvitals[mndx].mvflags & G_GONE)
  8.          return TRUE;
  9.      if (Inhell)
  10.          return (boolean) (mons[mndx].maligntyp > A_NEUTRAL);
  11.      else
  12.          return (boolean) ((mons[mndx].geno & G_HELL) != 0);
  13.  }
  14.  

align_shift

  1.  /*
  2.   *      shift the probability of a monster's generation by
  3.   *      comparing the dungeon alignment and monster alignment.
  4.   *      return an integer in the range of 0-5.
  5.   */
  6.  STATIC_OVL int
  7.  align_shift(ptr)
  8.  register struct permonst *ptr;
  9.  {
  10.      static NEARDATA long oldmoves = 0L; /* != 1, starting value of moves */
  11.      static NEARDATA s_level *lev;
  12.      register int alshift;
  13.  
  14.      if (oldmoves != moves) {
  15.          lev = Is_special(&u.uz);
  16.          oldmoves = moves;
  17.      }
  18.      switch ((lev) ? lev->flags.align : dungeons[u.uz.dnum].flags.align) {
  19.      default: /* just in case */
  20.      case AM_NONE:
  21.          alshift = 0;
  22.          break;
  23.      case AM_LAWFUL:
  24.          alshift = (ptr->maligntyp + 20) / (2 * ALIGNWEIGHT);
  25.          break;
  26.      case AM_NEUTRAL:
  27.          alshift = (20 - abs(ptr->maligntyp)) / ALIGNWEIGHT;
  28.          break;
  29.      case AM_CHAOTIC:
  30.          alshift = (-(ptr->maligntyp - 20)) / (2 * ALIGNWEIGHT);
  31.          break;
  32.      }
  33.      return alshift;
  34.  }
  35.  

rndmonst

  1.  static NEARDATA struct {
  2.      int choice_count;
  3.      char mchoices[SPECIAL_PM]; /* value range is 0..127 */
  4.  } rndmonst_state = { -1, { 0 } };
  5.  

rndmonst

  1.  /* select a random monster type */
  2.  struct permonst *
  3.  rndmonst()
  4.  {
  5.      register struct permonst *ptr;
  6.      register int mndx, ct;
  7.  
  8.      if (u.uz.dnum == quest_dnum && rn2(7) && (ptr = qt_montype()) != 0)
  9.          return ptr;
  10.  
  11.      if (rndmonst_state.choice_count < 0) { /* need to recalculate */
  12.          int zlevel, minmlev, maxmlev;
  13.          boolean elemlevel;
  14.          boolean upper;
  15.  
  16.          rndmonst_state.choice_count = 0;
  17.          /* look for first common monster */
  18.          for (mndx = LOW_PM; mndx < SPECIAL_PM; mndx++) {
  19.              if (!uncommon(mndx))
  20.                  break;
  21.              rndmonst_state.mchoices[mndx] = 0;
  22.          }
  23.          if (mndx == SPECIAL_PM) {
  24.              /* evidently they've all been exterminated */
  25.              debugpline0("rndmonst: no common mons!");
  26.              return (struct permonst *) 0;
  27.          } /* else `mndx' now ready for use below */
  28.          zlevel = level_difficulty();
  29.          /* determine the level of the weakest monster to make. */
  30.          minmlev = zlevel / 6;
  31.          /* determine the level of the strongest monster to make. */
  32.          maxmlev = (zlevel + u.ulevel) / 2;
  33.          upper = Is_rogue_level(&u.uz);
  34.          elemlevel = In_endgame(&u.uz) && !Is_astralevel(&u.uz);
  35.  
  36.          /*
  37.           * Find out how many monsters exist in the range we have selected.
  38.           */
  39.          for ( ; mndx < SPECIAL_PM; mndx++) { /* (`mndx' initialized above) */
  40.              ptr = &mons[mndx];
  41.              rndmonst_state.mchoices[mndx] = 0;
  42.              if (tooweak(mndx, minmlev) || toostrong(mndx, maxmlev))
  43.                  continue;
  44.              if (upper && !isupper(def_monsyms[(int) (ptr->mlet)].sym))
  45.                  continue;
  46.              if (elemlevel && wrong_elem_type(ptr))
  47.                  continue;
  48.              if (uncommon(mndx))
  49.                  continue;
  50.              if (Inhell && (ptr->geno & G_NOHELL))
  51.                  continue;
  52.              ct = (int) (ptr->geno & G_FREQ) + align_shift(ptr);
  53.              if (ct < 0 || ct > 127)
  54.                  panic("rndmonst: bad count [#%d: %d]", mndx, ct);
  55.              rndmonst_state.choice_count += ct;
  56.              rndmonst_state.mchoices[mndx] = (char) ct;
  57.          }
  58.          /*
  59.           *      Possible modification:  if choice_count is "too low",
  60.           *      expand minmlev..maxmlev range and try again.
  61.           */
  62.      } /* choice_count+mchoices[] recalc */
  63.  
  64.      if (rndmonst_state.choice_count <= 0) {
  65.          /* maybe no common mons left, or all are too weak or too strong */
  66.          debugpline1("rndmonst: choice_count=%d", rndmonst_state.choice_count);
  67.          return (struct permonst *) 0;
  68.      }
  69.  
  70.      /*
  71.       *  Now, select a monster at random.
  72.       */
  73.      ct = rnd(rndmonst_state.choice_count);
  74.      for (mndx = LOW_PM; mndx < SPECIAL_PM; mndx++)
  75.          if ((ct -= (int) rndmonst_state.mchoices[mndx]) <= 0)
  76.              break;
  77.  
  78.      if (mndx == SPECIAL_PM || uncommon(mndx)) { /* shouldn't happen */
  79.          impossible("rndmonst: bad `mndx' [#%d]", mndx);
  80.          return (struct permonst *) 0;
  81.      }
  82.      return &mons[mndx];
  83.  }
  84.  

reset_rndmonst

  1.  /* called when you change level (experience or dungeon depth) or when
  2.     monster species can no longer be created (genocide or extinction) */
  3.  void
  4.  reset_rndmonst(mndx)
  5.  int mndx; /* particular species that can no longer be created */
  6.  {
  7.      /* cached selection info is out of date */
  8.      if (mndx == NON_PM) {
  9.          rndmonst_state.choice_count = -1; /* full recalc needed */
  10.      } else if (mndx < SPECIAL_PM) {
  11.          rndmonst_state.choice_count -= rndmonst_state.mchoices[mndx];
  12.          rndmonst_state.mchoices[mndx] = 0;
  13.      } /* note: safe to ignore extinction of unique monsters */
  14.  }
  15.  

mk_gen_ok

  1.  /* decide whether it's ok to generate a candidate monster by mkclass() */
  2.  STATIC_OVL boolean
  3.  mk_gen_ok(mndx, mvflagsmask, genomask)
  4.  int mndx, mvflagsmask, genomask;
  5.  {
  6.      struct permonst *ptr = &mons[mndx];
  7.  
  8.      if (mvitals[mndx].mvflags & mvflagsmask)
  9.          return FALSE;
  10.      if (ptr->geno & genomask)
  11.          return FALSE;
  12.      if (is_placeholder(ptr))
  13.          return FALSE;
  14.  #ifdef MAIL
  15.      /* special levels might ask for random demon type; reject this one */
  16.      if (ptr == &mons[PM_MAIL_DAEMON])
  17.          return FALSE;
  18.  #endif
  19.      return TRUE;
  20.  }
  21.  

mkclass

  1.  /* Make one of the multiple types of a given monster class.
  2.   * The second parameter specifies a special casing bit mask
  3.   * to allow the normal genesis masks to be deactivated.
  4.   * Returns Null if no monsters in that class can be made.
  5.   */
  6.  struct permonst *
  7.  mkclass(class, spc)
  8.  char class;
  9.  int spc;
  10.  {
  11.      register int first, last, num = 0;
  12.      int maxmlev, mask = (G_NOGEN | G_UNIQ) & ~spc;
  13.  
  14.      maxmlev = level_difficulty() >> 1;
  15.      if (class < 1 || class >= MAXMCLASSES) {
  16.          impossible("mkclass called with bad class!");
  17.          return (struct permonst *) 0;
  18.      }
  19.      /*  Assumption #1:  monsters of a given class are contiguous in the
  20.       *                  mons[] array.
  21.       */
  22.      for (first = LOW_PM; first < SPECIAL_PM; first++)
  23.          if (mons[first].mlet == class)
  24.              break;
  25.      if (first == SPECIAL_PM)
  26.          return (struct permonst *) 0;
  27.  
  28.      for (last = first; last < SPECIAL_PM && mons[last].mlet == class; last++)
  29.          if (mk_gen_ok(last, G_GONE, mask)) {
  30.              /* consider it */
  31.              if (num && toostrong(last, maxmlev)
  32.                  && monstr[last] != monstr[last - 1] && rn2(2))
  33.                  break;
  34.              num += mons[last].geno & G_FREQ;
  35.          }
  36.      if (!num)
  37.          return (struct permonst *) 0;
  38.  
  39.      /*  Assumption #2:  monsters of a given class are presented in ascending
  40.       *                  order of strength.
  41.       */
  42.      for (num = rnd(num); num > 0; first++)
  43.          if (mk_gen_ok(first, G_GONE, mask)) {
  44.              /* skew towards lower value monsters at lower exp. levels */
  45.              num -= mons[first].geno & G_FREQ;
  46.              if (num && adj_lev(&mons[first]) > (u.ulevel * 2)) {
  47.                  /* but not when multiple monsters are same level */
  48.                  if (mons[first].mlevel != mons[first + 1].mlevel)
  49.                      num--;
  50.              }
  51.          }
  52.      first--; /* correct an off-by-one error */
  53.  
  54.      return &mons[first];
  55.  }
  56.  

mkclass_poly

  1.  /* like mkclass(), but excludes difficulty considerations; used when
  2.     player with polycontrol picks a class instead of a specific type;
  3.     genocided types are avoided but extinct ones are acceptable; we don't
  4.     check polyok() here--caller accepts some choices !polyok() would reject */
  5.  int
  6.  mkclass_poly(class)
  7.  int class;
  8.  {
  9.      register int first, last, num = 0;
  10.  
  11.      for (first = LOW_PM; first < SPECIAL_PM; first++)
  12.          if (mons[first].mlet == class)
  13.              break;
  14.      if (first == SPECIAL_PM)
  15.          return NON_PM;
  16.  
  17.      for (last = first; last < SPECIAL_PM && mons[last].mlet == class; last++)
  18.          if (mk_gen_ok(last, G_GENOD, (G_NOGEN | G_UNIQ)))
  19.              num += mons[last].geno & G_FREQ;
  20.      if (!num)
  21.          return NON_PM;
  22.  
  23.      for (num = rnd(num); num > 0; first++)
  24.          if (mk_gen_ok(first, G_GENOD, (G_NOGEN | G_UNIQ)))
  25.              num -= mons[first].geno & G_FREQ;
  26.      first--; /* correct an off-by-one error */
  27.  
  28.      return first;
  29.  }
  30.  

adj_lev

  1.  /* adjust strength of monsters based on u.uz and u.ulevel */
  2.  int
  3.  adj_lev(ptr)
  4.  register struct permonst *ptr;
  5.  {
  6.      int tmp, tmp2;
  7.  
  8.      if (ptr == &mons[PM_WIZARD_OF_YENDOR]) {
  9.          /* does not depend on other strengths, but does get stronger
  10.           * every time he is killed
  11.           */
  12.          tmp = ptr->mlevel + mvitals[PM_WIZARD_OF_YENDOR].died;
  13.          if (tmp > 49)
  14.              tmp = 49;
  15.          return tmp;
  16.      }
  17.  
  18.      if ((tmp = ptr->mlevel) > 49)
  19.          return 50; /* "special" demons/devils */
  20.      tmp2 = (level_difficulty() - tmp);
  21.      if (tmp2 < 0)
  22.          tmp--; /* if mlevel > u.uz decrement tmp */
  23.      else
  24.          tmp += (tmp2 / 5); /* else increment 1 per five diff */
  25.  
  26.      tmp2 = (u.ulevel - ptr->mlevel); /* adjust vs. the player */
  27.      if (tmp2 > 0)
  28.          tmp += (tmp2 / 4); /* level as well */
  29.  
  30.      tmp2 = (3 * ((int) ptr->mlevel)) / 2; /* crude upper limit */
  31.      if (tmp2 > 49)
  32.          tmp2 = 49;                                      /* hard upper limit */
  33.      return ((tmp > tmp2) ? tmp2 : (tmp > 0 ? tmp : 0)); /* 0 lower limit */
  34.  }
  35.  

grow_up

  1.  /* monster earned experience and will gain some hit points; it might also
  2.     grow into a bigger monster (baby to adult, soldier to officer, etc) */
  3.  struct permonst *
  4.  grow_up(mtmp, victim)
  5.  struct monst *mtmp, *victim;
  6.  {
  7.      int oldtype, newtype, max_increase, cur_increase, lev_limit, hp_threshold;
  8.      struct permonst *ptr = mtmp->data;
  9.  
  10.      /* monster died after killing enemy but before calling this function */
  11.      /* currently possible if killing a gas spore */
  12.      if (mtmp->mhp <= 0)
  13.          return (struct permonst *) 0;
  14.  
  15.      /* note:  none of the monsters with special hit point calculations
  16.         have both little and big forms */
  17.      oldtype = monsndx(ptr);
  18.      newtype = little_to_big(oldtype);
  19.      if (newtype == PM_PRIEST && mtmp->female)
  20.          newtype = PM_PRIESTESS;
  21.  
  22.      /* growth limits differ depending on method of advancement */
  23.      if (victim) {                       /* killed a monster */
  24.          /*
  25.           * The HP threshold is the maximum number of hit points for the
  26.           * current level; once exceeded, a level will be gained.
  27.           * Possible bug: if somehow the hit points are already higher
  28.           * than that, monster will gain a level without any increase in HP.
  29.           */
  30.          hp_threshold = mtmp->m_lev * 8; /* normal limit */
  31.          if (!mtmp->m_lev)
  32.              hp_threshold = 4;
  33.          else if (is_golem(ptr)) /* strange creatures */
  34.              hp_threshold = ((mtmp->mhpmax / 10) + 1) * 10 - 1;
  35.          else if (is_home_elemental(ptr))
  36.              hp_threshold *= 3;
  37.          lev_limit = 3 * (int) ptr->mlevel / 2; /* same as adj_lev() */
  38.          /* If they can grow up, be sure the level is high enough for that */
  39.          if (oldtype != newtype && mons[newtype].mlevel > lev_limit)
  40.              lev_limit = (int) mons[newtype].mlevel;
  41.          /* number of hit points to gain; unlike for the player, we put
  42.             the limit at the bottom of the next level rather than the top */
  43.          max_increase = rnd((int) victim->m_lev + 1);
  44.          if (mtmp->mhpmax + max_increase > hp_threshold + 1)
  45.              max_increase = max((hp_threshold + 1) - mtmp->mhpmax, 0);
  46.          cur_increase = (max_increase > 1) ? rn2(max_increase) : 0;
  47.      } else {
  48.          /* a gain level potion or wraith corpse; always go up a level
  49.             unless already at maximum (49 is hard upper limit except
  50.             for demon lords, who start at 50 and can't go any higher) */
  51.          max_increase = cur_increase = rnd(8);
  52.          hp_threshold = 0; /* smaller than `mhpmax + max_increase' */
  53.          lev_limit = 50;   /* recalc below */
  54.      }
  55.  
  56.      mtmp->mhpmax += max_increase;
  57.      mtmp->mhp += cur_increase;
  58.      if (mtmp->mhpmax <= hp_threshold)
  59.          return ptr; /* doesn't gain a level */
  60.  
  61.      if (is_mplayer(ptr))
  62.          lev_limit = 30; /* same as player */
  63.      else if (lev_limit < 5)
  64.          lev_limit = 5; /* arbitrary */
  65.      else if (lev_limit > 49)
  66.          lev_limit = (ptr->mlevel > 49 ? 50 : 49);
  67.  
  68.      if ((int) ++mtmp->m_lev >= mons[newtype].mlevel && newtype != oldtype) {
  69.          ptr = &mons[newtype];
  70.          if (mvitals[newtype].mvflags & G_GENOD) { /* allow G_EXTINCT */
  71.              if (canspotmon(mtmp))
  72.                  pline("As %s grows up into %s, %s %s!", mon_nam(mtmp),
  73.                        an(ptr->mname), mhe(mtmp),
  74.                        nonliving(ptr) ? "expires" : "dies");
  75.              set_mon_data(mtmp, ptr, -1); /* keep mvitals[] accurate */
  76.              mondied(mtmp);
  77.              return (struct permonst *) 0;
  78.          } else if (canspotmon(mtmp)) {
  79.              pline("%s %s %s.", Monnam(mtmp),
  80.                    humanoid(ptr) ? "becomes" : "grows up into",
  81.                    an(ptr->mname));
  82.          }
  83.          set_mon_data(mtmp, ptr, 1);    /* preserve intrinsics */
  84.          newsym(mtmp->mx, mtmp->my);    /* color may change */
  85.          lev_limit = (int) mtmp->m_lev; /* never undo increment */
  86.      }
  87.      /* sanity checks */
  88.      if ((int) mtmp->m_lev > lev_limit) {
  89.          mtmp->m_lev--; /* undo increment */
  90.          /* HP might have been allowed to grow when it shouldn't */
  91.          if (mtmp->mhpmax == hp_threshold + 1)
  92.              mtmp->mhpmax--;
  93.      }
  94.      if (mtmp->mhpmax > 50 * 8)
  95.          mtmp->mhpmax = 50 * 8; /* absolute limit */
  96.      if (mtmp->mhp > mtmp->mhpmax)
  97.          mtmp->mhp = mtmp->mhpmax;
  98.  
  99.      return ptr;
  100.  }
  101.  

mongets

  1.  int
  2.  mongets(mtmp, otyp)
  3.  register struct monst *mtmp;
  4.  int otyp;
  5.  {
  6.      register struct obj *otmp;
  7.      int spe;
  8.  
  9.      if (!otyp)
  10.          return 0;
  11.      otmp = mksobj(otyp, TRUE, FALSE);
  12.      if (otmp) {
  13.          if (mtmp->data->mlet == S_DEMON) {
  14.              /* demons never get blessed objects */
  15.              if (otmp->blessed)
  16.                  curse(otmp);
  17.          } else if (is_lminion(mtmp)) {
  18.              /* lawful minions don't get cursed, bad, or rusting objects */
  19.              otmp->cursed = FALSE;
  20.              if (otmp->spe < 0)
  21.                  otmp->spe = 0;
  22.              otmp->oerodeproof = TRUE;
  23.          } else if (is_mplayer(mtmp->data) && is_sword(otmp)) {
  24.              otmp->spe = (3 + rn2(4));
  25.          }
  26.  
  27.          if (otmp->otyp == CANDELABRUM_OF_INVOCATION) {
  28.              otmp->spe = 0;
  29.              otmp->age = 0L;
  30.              otmp->lamplit = FALSE;
  31.              otmp->blessed = otmp->cursed = FALSE;
  32.          } else if (otmp->otyp == BELL_OF_OPENING) {
  33.              otmp->blessed = otmp->cursed = FALSE;
  34.          } else if (otmp->otyp == SPE_BOOK_OF_THE_DEAD) {
  35.              otmp->blessed = FALSE;
  36.              otmp->cursed = TRUE;
  37.          }
  38.  
  39.          /* leaders don't tolerate inferior quality battle gear */
  40.          if (is_prince(mtmp->data)) {
  41.              if (otmp->oclass == WEAPON_CLASS && otmp->spe < 1)
  42.                  otmp->spe = 1;
  43.              else if (otmp->oclass == ARMOR_CLASS && otmp->spe < 0)
  44.                  otmp->spe = 0;
  45.          }
  46.  
  47.          spe = otmp->spe;
  48.          (void) mpickobj(mtmp, otmp); /* might free otmp */
  49.          return spe;
  50.      }
  51.      return 0;
  52.  }
  53.  

golemhp

  1.  int
  2.  golemhp(type)
  3.  int type;
  4.  {
  5.      switch (type) {
  6.      case PM_STRAW_GOLEM:
  7.          return 20;
  8.      case PM_PAPER_GOLEM:
  9.          return 20;
  10.      case PM_ROPE_GOLEM:
  11.          return 30;
  12.      case PM_LEATHER_GOLEM:
  13.          return 40;
  14.      case PM_GOLD_GOLEM:
  15.          return 40;
  16.      case PM_WOOD_GOLEM:
  17.          return 50;
  18.      case PM_FLESH_GOLEM:
  19.          return 40;
  20.      case PM_CLAY_GOLEM:
  21.          return 50;
  22.      case PM_STONE_GOLEM:
  23.          return 60;
  24.      case PM_GLASS_GOLEM:
  25.          return 60;
  26.      case PM_IRON_GOLEM:
  27.          return 80;
  28.      default:
  29.          return 0;
  30.      }
  31.  }
  32.  

peace_minded

  1.  /*
  2.   *      Alignment vs. yours determines monster's attitude to you.
  3.   *      (Some "animal" types are co-aligned, but also hungry.)
  4.   */
  5.  boolean
  6.  peace_minded(ptr)
  7.  register struct permonst *ptr;
  8.  {
  9.      aligntyp mal = ptr->maligntyp, ual = u.ualign.type;
  10.  
  11.      if (always_peaceful(ptr))
  12.          return TRUE;
  13.      if (always_hostile(ptr))
  14.          return FALSE;
  15.      if (ptr->msound == MS_LEADER || ptr->msound == MS_GUARDIAN)
  16.          return TRUE;
  17.      if (ptr->msound == MS_NEMESIS)
  18.          return FALSE;
  19.  
  20.      if (race_peaceful(ptr))
  21.          return TRUE;
  22.      if (race_hostile(ptr))
  23.          return FALSE;
  24.  
  25.      /* the monster is hostile if its alignment is different from the
  26.       * player's */
  27.      if (sgn(mal) != sgn(ual))
  28.          return FALSE;
  29.  
  30.      /* Negative monster hostile to player with Amulet. */
  31.      if (mal < A_NEUTRAL && u.uhave.amulet)
  32.          return FALSE;
  33.  
  34.      /* minions are hostile to players that have strayed at all */
  35.      if (is_minion(ptr))
  36.          return (boolean) (u.ualign.record >= 0);
  37.  
  38.      /* Last case:  a chance of a co-aligned monster being
  39.       * hostile.  This chance is greater if the player has strayed
  40.       * (u.ualign.record negative) or the monster is not strongly aligned.
  41.       */
  42.      return (boolean) (!!rn2(16 + (u.ualign.record < -15 ? -15
  43.                                                          : u.ualign.record))
  44.                        && !!rn2(2 + abs(mal)));
  45.  }
  46.  

set_malign

  1.  /* Set malign to have the proper effect on player alignment if monster is
  2.   * killed.  Negative numbers mean it's bad to kill this monster; positive
  3.   * numbers mean it's good.  Since there are more hostile monsters than
  4.   * peaceful monsters, the penalty for killing a peaceful monster should be
  5.   * greater than the bonus for killing a hostile monster to maintain balance.
  6.   * Rules:
  7.   *   it's bad to kill peaceful monsters, potentially worse to kill always-
  8.   *      peaceful monsters;
  9.   *   it's never bad to kill a hostile monster, although it may not be good.
  10.   */
  11.  void
  12.  set_malign(mtmp)
  13.  struct monst *mtmp;
  14.  {
  15.      schar mal = mtmp->data->maligntyp;
  16.      boolean coaligned;
  17.  
  18.      if (mtmp->ispriest || mtmp->isminion) {
  19.          /* some monsters have individual alignments; check them */
  20.          if (mtmp->ispriest && EPRI(mtmp))
  21.              mal = EPRI(mtmp)->shralign;
  22.          else if (mtmp->isminion && EMIN(mtmp))
  23.              mal = EMIN(mtmp)->min_align;
  24.          /* unless alignment is none, set mal to -5,0,5 */
  25.          /* (see align.h for valid aligntyp values)     */
  26.          if (mal != A_NONE)
  27.              mal *= 5;
  28.      }
  29.  
  30.      coaligned = (sgn(mal) == sgn(u.ualign.type));
  31.      if (mtmp->data->msound == MS_LEADER) {
  32.          mtmp->malign = -20;
  33.      } else if (mal == A_NONE) {
  34.          if (mtmp->mpeaceful)
  35.              mtmp->malign = 0;
  36.          else
  37.              mtmp->malign = 20; /* really hostile */
  38.      } else if (always_peaceful(mtmp->data)) {
  39.          int absmal = abs(mal);
  40.          if (mtmp->mpeaceful)
  41.              mtmp->malign = -3 * max(5, absmal);
  42.          else
  43.              mtmp->malign = 3 * max(5, absmal); /* renegade */
  44.      } else if (always_hostile(mtmp->data)) {
  45.          int absmal = abs(mal);
  46.          if (coaligned)
  47.              mtmp->malign = 0;
  48.          else
  49.              mtmp->malign = max(5, absmal);
  50.      } else if (coaligned) {
  51.          int absmal = abs(mal);
  52.          if (mtmp->mpeaceful)
  53.              mtmp->malign = -3 * max(3, absmal);
  54.          else /* renegade */
  55.              mtmp->malign = max(3, absmal);
  56.      } else /* not coaligned and therefore hostile */
  57.          mtmp->malign = abs(mal);
  58.  }
  59.  

newmcorpsenm

  1.  /* allocate a new mcorpsenm field for a monster; only need mextra itself */
  2.  void
  3.  newmcorpsenm(mtmp)
  4.  struct monst *mtmp;
  5.  {
  6.      if (!mtmp->mextra)
  7.          mtmp->mextra = newmextra();
  8.      MCORPSENM(mtmp) = NON_PM; /* not initialized yet */
  9.  }
  10.  

freemcorpsenm

  1.  /* release monster's mcorpsenm field; basically a no-op */
  2.  void
  3.  freemcorpsenm(mtmp)
  4.  struct monst *mtmp;
  5.  {
  6.      if (has_mcorpsenm(mtmp))
  7.          MCORPSENM(mtmp) = NON_PM;
  8.  }
  9.  

set_mimic_sym

  1.  static NEARDATA char syms[] = {
  2.      MAXOCLASSES,  MAXOCLASSES + 1, RING_CLASS,   WAND_CLASS,   WEAPON_CLASS,
  3.      FOOD_CLASS,   COIN_CLASS,      SCROLL_CLASS, POTION_CLASS, ARMOR_CLASS,
  4.      AMULET_CLASS, TOOL_CLASS,      ROCK_CLASS,   GEM_CLASS,    SPBOOK_CLASS,
  5.      S_MIMIC_DEF,  S_MIMIC_DEF,
  6.  };
  7.  
  8.  void
  9.  set_mimic_sym(mtmp)
  10.  register struct monst *mtmp;
  11.  {
  12.      int typ, roomno, rt;
  13.      unsigned appear, ap_type;
  14.      int s_sym;
  15.      struct obj *otmp;
  16.      int mx, my;
  17.  
  18.      if (!mtmp)
  19.          return;
  20.      mx = mtmp->mx;
  21.      my = mtmp->my;
  22.      typ = levl[mx][my].typ;
  23.      /* only valid for INSIDE of room */
  24.      roomno = levl[mx][my].roomno - ROOMOFFSET;
  25.      if (roomno >= 0)
  26.          rt = rooms[roomno].rtype;
  27.  #ifdef SPECIALIZATION
  28.      else if (IS_ROOM(typ))
  29.          rt = OROOM, roomno = 0;
  30.  #endif
  31.      else
  32.          rt = 0; /* roomno < 0 case for GCC_WARN */
  33.  
  34.      if (OBJ_AT(mx, my)) {
  35.          ap_type = M_AP_OBJECT;
  36.          appear = level.objects[mx][my]->otyp;
  37.      } else if (IS_DOOR(typ) || IS_WALL(typ) || typ == SDOOR || typ == SCORR) {
  38.          ap_type = M_AP_FURNITURE;
  39.          /*
  40.           *  If there is a wall to the left that connects to this
  41.           *  location, then the mimic mimics a horizontal closed door.
  42.           *  This does not allow doors to be in corners of rooms.
  43.           *  Since rogue has no closed doors, mimic a wall there
  44.           *  (yes, mimics can end up on this level by various means).
  45.           */
  46.          if (mx != 0 && (levl[mx - 1][my].typ == HWALL
  47.                          || levl[mx - 1][my].typ == TLCORNER
  48.                          || levl[mx - 1][my].typ == TRWALL
  49.                          || levl[mx - 1][my].typ == BLCORNER
  50.                          || levl[mx - 1][my].typ == TDWALL
  51.                          || levl[mx - 1][my].typ == CROSSWALL
  52.                          || levl[mx - 1][my].typ == TUWALL))
  53.              appear = Is_rogue_level(&u.uz) ? S_hwall : S_hcdoor;
  54.          else
  55.              appear = Is_rogue_level(&u.uz) ? S_vwall : S_vcdoor;
  56.          if (!mtmp->minvis || See_invisible)
  57.              block_point(mx, my); /* vision */
  58.      } else if (level.flags.is_maze_lev && !In_sokoban(&u.uz) && rn2(2)) {
  59.          ap_type = M_AP_OBJECT;
  60.          appear = STATUE;
  61.      } else if (roomno < 0 && !t_at(mx, my)) {
  62.          ap_type = M_AP_OBJECT;
  63.          appear = BOULDER;
  64.          if (!mtmp->minvis || See_invisible)
  65.              block_point(mx, my); /* vision */
  66.      } else if (rt == ZOO || rt == VAULT) {
  67.          ap_type = M_AP_OBJECT;
  68.          appear = GOLD_PIECE;
  69.      } else if (rt == DELPHI) {
  70.          if (rn2(2)) {
  71.              ap_type = M_AP_OBJECT;
  72.              appear = STATUE;
  73.          } else {
  74.              ap_type = M_AP_FURNITURE;
  75.              appear = S_fountain;
  76.          }
  77.      } else if (rt == TEMPLE) {
  78.          ap_type = M_AP_FURNITURE;
  79.          appear = S_altar;
  80.          /*
  81.           * We won't bother with beehives, morgues, barracks, throne rooms
  82.           * since they shouldn't contain too many mimics anyway...
  83.           */
  84.      } else if (rt >= SHOPBASE) {
  85.          s_sym = get_shop_item(rt - SHOPBASE);
  86.          if (s_sym < 0) {
  87.              ap_type = M_AP_OBJECT;
  88.              appear = -s_sym;
  89.          } else {
  90.              if (s_sym == RANDOM_CLASS)
  91.                  s_sym = syms[rn2((int) sizeof(syms) - 2) + 2];
  92.              goto assign_sym;
  93.          }
  94.      } else {
  95.          s_sym = syms[rn2((int) sizeof(syms))];
  96.      assign_sym:
  97.          if (s_sym == MAXOCLASSES || s_sym == MAXOCLASSES + 1) {
  98.              ap_type = M_AP_FURNITURE;
  99.              appear = (s_sym == MAXOCLASSES) ? S_upstair : S_dnstair;
  100.          } else {
  101.              ap_type = M_AP_OBJECT;
  102.              if (s_sym == S_MIMIC_DEF) {
  103.                  appear = STRANGE_OBJECT;
  104.              } else if (s_sym == COIN_CLASS) {
  105.                  appear = GOLD_PIECE;
  106.              } else {
  107.                  otmp = mkobj((char) s_sym, FALSE);
  108.                  appear = otmp->otyp;
  109.                  /* make sure container contents are free'ed */
  110.                  obfree(otmp, (struct obj *) 0);
  111.              }
  112.          }
  113.      }
  114.      mtmp->m_ap_type = ap_type;
  115.      mtmp->mappearance = appear;
  116.      if (ap_type == M_AP_OBJECT && (appear == STATUE || appear == CORPSE
  117.                                     || appear == FIGURINE || appear == EGG)) {
  118.          newmcorpsenm(mtmp);
  119.          MCORPSENM(mtmp) = rndmonnum();
  120.          if (appear == EGG && !can_be_hatched(MCORPSENM(mtmp)))
  121.              MCORPSENM(mtmp) = NON_PM; /* revert to generic egg */
  122.      }
  123.  }
  124.  

bagotricks

  1.  /* release monster from bag of tricks; return number of monsters created */
  2.  int
  3.  bagotricks(bag, tipping, seencount)
  4.  struct obj *bag;
  5.  boolean tipping; /* caller emptying entire contents; affects shop handling */
  6.  int *seencount;  /* secondary output */
  7.  {
  8.      int moncount = 0;
  9.  
  10.      if (!bag || bag->otyp != BAG_OF_TRICKS) {
  11.          impossible("bad bag o' tricks");
  12.      } else if (bag->spe < 1) {
  13.          /* if tipping known empty bag, give normal empty container message */
  14.          pline1((tipping && bag->cknown) ? "It's empty." : nothing_happens);
  15.          /* now known to be empty if sufficiently discovered */
  16.          if (bag->dknown && objects[bag->otyp].oc_name_known)
  17.              bag->cknown = 1;
  18.      } else {
  19.          struct monst *mtmp;
  20.          int creatcnt = 1, seecount = 0;
  21.  
  22.          consume_obj_charge(bag, !tipping);
  23.  
  24.          if (!rn2(23))
  25.              creatcnt += rnd(7);
  26.          do {
  27.              mtmp = makemon((struct permonst *) 0, u.ux, u.uy, NO_MM_FLAGS);
  28.              if (mtmp) {
  29.                  ++moncount;
  30.                  if (canspotmon(mtmp))
  31.                      ++seecount;
  32.              }
  33.          } while (--creatcnt > 0);
  34.          if (seecount) {
  35.              if (seencount)
  36.                  *seencount += seecount;
  37.              if (bag->dknown)
  38.                  makeknown(BAG_OF_TRICKS);
  39.          } else if (!tipping) {
  40.              pline1(!moncount ? nothing_happens : "Nothing seems to happen.");
  41.          }
  42.      }
  43.      return moncount;
  44.  }
  45.  
  46.  /*makemon.c*/