Source:NetHack 3.6.1/src/priest.c

From NetHackWiki
(Redirected from Source:Ref/mstatusline)
Jump to: navigation, search

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

Top of file

  1.  /* NetHack 3.6	priest.c	$NHDT-Date: 1501725407 2017/08/03 01:56:47 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.44 $ */
  2.  /* Copyright (c) Izchak Miller, Steve Linhart, 1989.              */
  3.  /* NetHack may be freely redistributed.  See license for details. */

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.

  1.  
  2.  #include "hack.h"
  3.  #include "mfndpos.h"
  4.  
  5.  /* these match the categorizations shown by enlightenment */
  6.  #define ALGN_SINNED (-4) /* worse than strayed (-1..-3) */
  7.  #define ALGN_PIOUS 14    /* better than fervent (9..13) */
  8.  
  9.  STATIC_DCL boolean FDECL(histemple_at, (struct monst *, XCHAR_P, XCHAR_P));
  10.  STATIC_DCL boolean FDECL(has_shrine, (struct monst *));
  11.  

newepri

  1.  void
  2.  newepri(mtmp)
  3.  struct monst *mtmp;
  4.  {
  5.      if (!mtmp->mextra)
  6.          mtmp->mextra = newmextra();
  7.      if (!EPRI(mtmp)) {
  8.          EPRI(mtmp) = (struct epri *) alloc(sizeof(struct epri));
  9.          (void) memset((genericptr_t) EPRI(mtmp), 0, sizeof(struct epri));
  10.      }
  11.  }
  12.  

free_epri

  1.  void
  2.  free_epri(mtmp)
  3.  struct monst *mtmp;
  4.  {
  5.      if (mtmp->mextra && EPRI(mtmp)) {
  6.          free((genericptr_t) EPRI(mtmp));
  7.          EPRI(mtmp) = (struct epri *) 0;
  8.      }
  9.      mtmp->ispriest = 0;
  10.  }
  11.  

move_special

  1.  /*
  2.   * Move for priests and shopkeepers.  Called from shk_move() and pri_move().
  3.   * Valid returns are  1: moved  0: didn't  -1: let m_move do it  -2: died.
  4.   */
  5.  int
  6.  move_special(mtmp, in_his_shop, appr, uondoor, avoid, omx, omy, gx, gy)
  7.  register struct monst *mtmp;
  8.  boolean in_his_shop;
  9.  schar appr;
  10.  boolean uondoor, avoid;
  11.  register xchar omx, omy, gx, gy;
  12.  {
  13.      register xchar nx, ny, nix, niy;
  14.      register schar i;
  15.      schar chcnt, cnt;
  16.      coord poss[9];
  17.      long info[9];
  18.      long allowflags;
  19.      struct obj *ib = (struct obj *) 0;
  20.  
  21.      if (omx == gx && omy == gy)
  22.          return 0;
  23.      if (mtmp->mconf) {
  24.          avoid = FALSE;
  25.          appr = 0;
  26.      }
  27.  
  28.      nix = omx;
  29.      niy = omy;
  30.      if (mtmp->isshk)
  31.          allowflags = ALLOW_SSM;
  32.      else
  33.          allowflags = ALLOW_SSM | ALLOW_SANCT;
  34.      if (passes_walls(mtmp->data))
  35.          allowflags |= (ALLOW_ROCK | ALLOW_WALL);
  36.      if (throws_rocks(mtmp->data))
  37.          allowflags |= ALLOW_ROCK;
  38.      if (tunnels(mtmp->data))
  39.          allowflags |= ALLOW_DIG;
  40.      if (!nohands(mtmp->data) && !verysmall(mtmp->data)) {
  41.          allowflags |= OPENDOOR;
  42.          if (monhaskey(mtmp, TRUE))
  43.              allowflags |= UNLOCKDOOR;
  44.      }
  45.      if (is_giant(mtmp->data))
  46.          allowflags |= BUSTDOOR;
  47.      cnt = mfndpos(mtmp, poss, info, allowflags);
  48.  
  49.      if (mtmp->isshk && avoid && uondoor) { /* perhaps we cannot avoid him */
  50.          for (i = 0; i < cnt; i++)
  51.              if (!(info[i] & NOTONL))
  52.                  goto pick_move;
  53.          avoid = FALSE;
  54.      }
  55.  
  56.  #define GDIST(x, y) (dist2(x, y, gx, gy))
  57.  pick_move:
  58.      chcnt = 0;
  59.      for (i = 0; i < cnt; i++) {
  60.          nx = poss[i].x;
  61.          ny = poss[i].y;
  62.          if (IS_ROOM(levl[nx][ny].typ)
  63.              || (mtmp->isshk && (!in_his_shop || ESHK(mtmp)->following))) {
  64.              if (avoid && (info[i] & NOTONL))
  65.                  continue;
  66.              if ((!appr && !rn2(++chcnt))
  67.                  || (appr && GDIST(nx, ny) < GDIST(nix, niy))) {
  68.                  nix = nx;
  69.                  niy = ny;
  70.              }
  71.          }
  72.      }
  73.      if (mtmp->ispriest && avoid && nix == omx && niy == omy
  74.          && onlineu(omx, omy)) {
  75.          /* might as well move closer as long it's going to stay
  76.           * lined up */
  77.          avoid = FALSE;
  78.          goto pick_move;
  79.      }
  80.  
  81.      if (nix != omx || niy != omy) {
  82.          remove_monster(omx, omy);
  83.          place_monster(mtmp, nix, niy);
  84.          newsym(nix, niy);
  85.          if (mtmp->isshk && !in_his_shop && inhishop(mtmp))
  86.              check_special_room(FALSE);
  87.          if (ib) {
  88.              if (cansee(mtmp->mx, mtmp->my))
  89.                  pline("%s picks up %s.", Monnam(mtmp),
  90.                        distant_name(ib, doname));
  91.              obj_extract_self(ib);
  92.              (void) mpickobj(mtmp, ib);
  93.          }
  94.          return 1;
  95.      }
  96.      return 0;
  97.  }
  98.  

temple_occupied

  1.  char
  2.  temple_occupied(array)
  3.  register char *array;
  4.  {
  5.      register char *ptr;
  6.  
  7.      for (ptr = array; *ptr; ptr++)
  8.          if (rooms[*ptr - ROOMOFFSET].rtype == TEMPLE)
  9.              return *ptr;
  10.      return '\0';
  11.  }
  12.  

histemple_at

  1.  STATIC_OVL boolean
  2.  histemple_at(priest, x, y)
  3.  register struct monst *priest;
  4.  register xchar x, y;
  5.  {
  6.      return (boolean) (priest && priest->ispriest
  7.                        && (EPRI(priest)->shroom == *in_rooms(x, y, TEMPLE))
  8.                        && on_level(&(EPRI(priest)->shrlevel), &u.uz));
  9.  }
  10.  

inhistemple

  1.  boolean
  2.  inhistemple(priest)
  3.  struct monst *priest;
  4.  {
  5.      /* make sure we have a priest */
  6.      if (!priest || !priest->ispriest)
  7.          return FALSE;
  8.      /* priest must be on right level and in right room */
  9.      if (!histemple_at(priest, priest->mx, priest->my))
  10.          return FALSE;
  11.      /* temple room must still contain properly aligned altar */
  12.      return has_shrine(priest);
  13.  }
  14.  

pri_move

  1.  /*
  2.   * pri_move: return 1: moved  0: didn't  -1: let m_move do it  -2: died
  3.   */
  4.  int
  5.  pri_move(priest)
  6.  register struct monst *priest;
  7.  {
  8.      register xchar gx, gy, omx, omy;
  9.      schar temple;
  10.      boolean avoid = TRUE;
  11.  
  12.      omx = priest->mx;
  13.      omy = priest->my;
  14.  
  15.      if (!histemple_at(priest, omx, omy))
  16.          return -1;
  17.  
  18.      temple = EPRI(priest)->shroom;
  19.  
  20.      gx = EPRI(priest)->shrpos.x;
  21.      gy = EPRI(priest)->shrpos.y;
  22.  
  23.      gx += rn1(3, -1); /* mill around the altar */
  24.      gy += rn1(3, -1);
  25.  
  26.      if (!priest->mpeaceful
  27.          || (Conflict && !resist(priest, RING_CLASS, 0, 0))) {
  28.          if (monnear(priest, u.ux, u.uy)) {
  29.              if (Displaced)
  30.                  Your("displaced image doesn't fool %s!", mon_nam(priest));
  31.              (void) mattacku(priest);
  32.              return 0;
  33.          } else if (index(u.urooms, temple)) {
  34.              /* chase player if inside temple & can see him */
  35.              if (priest->mcansee && m_canseeu(priest)) {
  36.                  gx = u.ux;
  37.                  gy = u.uy;
  38.              }
  39.              avoid = FALSE;
  40.          }
  41.      } else if (Invis)
  42.          avoid = FALSE;
  43.  
  44.      return move_special(priest, FALSE, TRUE, FALSE, avoid, omx, omy, gx, gy);
  45.  }
  46.  

priestini

  1.  /* exclusively for mktemple() */
  2.  void
  3.  priestini(lvl, sroom, sx, sy, sanctum)
  4.  d_level *lvl;
  5.  struct mkroom *sroom;
  6.  int sx, sy;
  7.  boolean sanctum; /* is it the seat of the high priest? */
  8.  {
  9.      struct monst *priest;
  10.      struct obj *otmp;
  11.      int cnt;
  12.  
  13.      if (MON_AT(sx + 1, sy))
  14.          (void) rloc(m_at(sx + 1, sy), FALSE); /* insurance */
  15.  
  16.      priest = makemon(&mons[sanctum ? PM_HIGH_PRIEST : PM_ALIGNED_PRIEST],
  17.                       sx + 1, sy, MM_EPRI);
  18.      if (priest) {
  19.          EPRI(priest)->shroom = (schar) ((sroom - rooms) + ROOMOFFSET);
  20.          EPRI(priest)->shralign = Amask2align(levl[sx][sy].altarmask);
  21.          EPRI(priest)->shrpos.x = sx;
  22.          EPRI(priest)->shrpos.y = sy;
  23.          assign_level(&(EPRI(priest)->shrlevel), lvl);
  24.          priest->mtrapseen = ~0; /* traps are known */
  25.          priest->mpeaceful = 1;
  26.          priest->ispriest = 1;
  27.          priest->isminion = 0;
  28.          priest->msleeping = 0;
  29.          set_malign(priest); /* mpeaceful may have changed */
  30.  
  31.          /* now his/her goodies... */
  32.          if (sanctum && EPRI(priest)->shralign == A_NONE
  33.              && on_level(&sanctum_level, &u.uz)) {
  34.              (void) mongets(priest, AMULET_OF_YENDOR);
  35.          }
  36.          /* 2 to 4 spellbooks */
  37.          for (cnt = rn1(3, 2); cnt > 0; --cnt) {
  38.              (void) mpickobj(priest, mkobj(SPBOOK_CLASS, FALSE));
  39.          }
  40.          /* robe [via makemon()] */
  41.          if (rn2(2) && (otmp = which_armor(priest, W_ARMC)) != 0) {
  42.              if (p_coaligned(priest))
  43.                  uncurse(otmp);
  44.              else
  45.                  curse(otmp);
  46.          }
  47.      }
  48.  }
  49.  

mon_aligntyp

  1.  /* get a monster's alignment type without caller needing EPRI & EMIN */
  2.  aligntyp
  3.  mon_aligntyp(mon)
  4.  struct monst *mon;
  5.  {
  6.      aligntyp algn = mon->ispriest ? EPRI(mon)->shralign
  7.                                    : mon->isminion ? EMIN(mon)->min_align
  8.                                                    : mon->data->maligntyp;
  9.  
  10.      if (algn == A_NONE)
  11.          return A_NONE; /* negative but differs from chaotic */
  12.      return (algn > 0) ? A_LAWFUL : (algn < 0) ? A_CHAOTIC : A_NEUTRAL;
  13.  }
  14.  

priestname

  1.  /*
  2.   * Specially aligned monsters are named specially.
  3.   *      - aligned priests with ispriest and high priests have shrines
  4.   *              they retain ispriest and epri when polymorphed
  5.   *      - aligned priests without ispriest are roamers
  6.   *              they have isminion set and use emin rather than epri
  7.   *      - minions do not have ispriest but have isminion and emin
  8.   *      - caller needs to inhibit Hallucination if it wants to force
  9.   *              the true name even when under that influence
  10.   */
  11.  char *
  12.  priestname(mon, pname)
  13.  register struct monst *mon;
  14.  char *pname; /* caller-supplied output buffer */
  15.  {
  16.      boolean do_hallu = Hallucination,
  17.              aligned_priest = mon->data == &mons[PM_ALIGNED_PRIEST],
  18.              high_priest = mon->data == &mons[PM_HIGH_PRIEST];
  19.      char whatcode = '\0';
  20.      const char *what = do_hallu ? rndmonnam(&whatcode) : mon->data->mname;
  21.  
  22.      if (!mon->ispriest && !mon->isminion) /* should never happen...  */
  23.          return strcpy(pname, what);       /* caller must be confused */
  24.  
  25.      *pname = '\0';
  26.      if (!do_hallu || !bogon_is_pname(whatcode))
  27.          Strcat(pname, "the ");
  28.      if (mon->minvis)
  29.          Strcat(pname, "invisible ");
  30.      if (mon->isminion && EMIN(mon)->renegade)
  31.          Strcat(pname, "renegade ");
  32.  
  33.      if (mon->ispriest || aligned_priest) { /* high_priest implies ispriest */
  34.          if (!aligned_priest && !high_priest) {
  35.              ; /* polymorphed priest; use ``what'' as is */
  36.          } else {
  37.              if (high_priest)
  38.                  Strcat(pname, "high ");
  39.              if (Hallucination)
  40.                  what = "poohbah";
  41.              else if (mon->female)
  42.                  what = "priestess";
  43.              else
  44.                  what = "priest";
  45.          }
  46.      } else {
  47.          if (mon->mtame && !strcmpi(what, "Angel"))
  48.              Strcat(pname, "guardian ");
  49.      }
  50.  
  51.      Strcat(pname, what);
  52.      /* same as distant_monnam(), more or less... */
  53.      if (do_hallu || !high_priest || !Is_astralevel(&u.uz)
  54.          || distu(mon->mx, mon->my) <= 2 || program_state.gameover) {
  55.          Strcat(pname, " of ");
  56.          Strcat(pname, halu_gname(mon_aligntyp(mon)));
  57.      }
  58.      return pname;
  59.  }
  60.  

p_coaligned

  1.  boolean
  2.  p_coaligned(priest)
  3.  struct monst *priest;
  4.  {
  5.      return (boolean) (u.ualign.type == mon_aligntyp(priest));
  6.  }
  7.  

has_shrine

  1.  STATIC_OVL boolean
  2.  has_shrine(pri)
  3.  struct monst *pri;
  4.  {
  5.      struct rm *lev;
  6.      struct epri *epri_p;
  7.  
  8.      if (!pri || !pri->ispriest)
  9.          return FALSE;
  10.      epri_p = EPRI(pri);
  11.      lev = &levl[epri_p->shrpos.x][epri_p->shrpos.y];
  12.      if (!IS_ALTAR(lev->typ) || !(lev->altarmask & AM_SHRINE))
  13.          return FALSE;
  14.      return (boolean) (epri_p->shralign
  15.                        == (Amask2align(lev->altarmask & ~AM_SHRINE)));
  16.  }
  17.  

findpriest

  1.  struct monst *
  2.  findpriest(roomno)
  3.  char roomno;
  4.  {
  5.      register struct monst *mtmp;
  6.  
  7.      for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  8.          if (DEADMONSTER(mtmp))
  9.              continue;
  10.          if (mtmp->ispriest && (EPRI(mtmp)->shroom == roomno)
  11.              && histemple_at(mtmp, mtmp->mx, mtmp->my))
  12.              return mtmp;
  13.      }
  14.      return (struct monst *) 0;
  15.  }
  16.  

intemple

  1.  /* called from check_special_room() when the player enters the temple room */
  2.  void
  3.  intemple(roomno)
  4.  int roomno;
  5.  {
  6.      struct monst *priest, *mtmp;
  7.      struct epri *epri_p;
  8.      boolean shrined, sanctum, can_speak;
  9.      long *this_time, *other_time;
  10.      const char *msg1, *msg2;
  11.      char buf[BUFSZ];
  12.  
  13.      /* don't do anything if hero is already in the room */
  14.      if (temple_occupied(u.urooms0))
  15.          return;
  16.  
  17.      if ((priest = findpriest((char) roomno)) != 0) {
  18.          /* tended */
  19.  
  20.          epri_p = EPRI(priest);
  21.          shrined = has_shrine(priest);
  22.          sanctum = (priest->data == &mons[PM_HIGH_PRIEST]
  23.                     && (Is_sanctum(&u.uz) || In_endgame(&u.uz)));
  24.          can_speak = (priest->mcanmove && !priest->msleeping);
  25.          if (can_speak && !Deaf && moves >= epri_p->intone_time) {
  26.              unsigned save_priest = priest->ispriest;
  27.  
  28.              /* don't reveal the altar's owner upon temple entry in
  29.                 the endgame; for the Sanctum, the next message names
  30.                 Moloch so suppress the "of Moloch" for him here too */
  31.              if (sanctum && !Hallucination)
  32.                  priest->ispriest = 0;
  33.              pline("%s intones:",
  34.                    canseemon(priest) ? Monnam(priest) : "A nearby voice");
  35.              priest->ispriest = save_priest;
  36.              epri_p->intone_time = moves + (long) d(10, 500); /* ~2505 */
  37.              /* make sure that we don't suppress entry message when
  38.                 we've just given its "priest intones" introduction */
  39.              epri_p->enter_time = 0L;
  40.          }
  41.          msg1 = msg2 = 0;
  42.          if (sanctum && Is_sanctum(&u.uz)) {
  43.              if (priest->mpeaceful) {
  44.                  /* first time inside */
  45.                  msg1 = "Infidel, you have entered Moloch's Sanctum!";
  46.                  msg2 = "Be gone!";
  47.                  priest->mpeaceful = 0;
  48.                  /* became angry voluntarily; no penalty for attacking him */
  49.                  set_malign(priest);
  50.              } else {
  51.                  /* repeat visit, or attacked priest before entering */
  52.                  msg1 = "You desecrate this place by your presence!";
  53.              }
  54.          } else if (moves >= epri_p->enter_time) {
  55.              Sprintf(buf, "Pilgrim, you enter a %s place!",
  56.                      !shrined ? "desecrated" : "sacred");
  57.              msg1 = buf;
  58.          }
  59.          if (msg1 && can_speak && !Deaf) {
  60.              verbalize1(msg1);
  61.              if (msg2)
  62.                  verbalize1(msg2);
  63.              epri_p->enter_time = moves + (long) d(10, 100); /* ~505 */
  64.          }
  65.          if (!sanctum) {
  66.              if (!shrined || !p_coaligned(priest)
  67.                  || u.ualign.record <= ALGN_SINNED) {
  68.                  msg1 = "have a%s forbidding feeling...";
  69.                  msg2 = (!shrined || !p_coaligned(priest)) ? "" : " strange";
  70.                  this_time = &epri_p->hostile_time;
  71.                  other_time = &epri_p->peaceful_time;
  72.              } else {
  73.                  msg1 = "experience %s sense of peace.";
  74.                  msg2 = (u.ualign.record >= ALGN_PIOUS) ? "a" : "an unusual";
  75.                  this_time = &epri_p->peaceful_time;
  76.                  other_time = &epri_p->hostile_time;
  77.              }
  78.              /* give message if we haven't seen it recently or
  79.                 if alignment update has caused it to switch from
  80.                 forbidding to sense-of-peace or vice versa */
  81.              if (moves >= *this_time || *other_time >= *this_time) {
  82.                  You(msg1, msg2);
  83.                  *this_time = moves + (long) d(10, 20); /* ~55 */
  84.                  /* avoid being tricked by the RNG:  switch might have just
  85.                     happened and previous random threshold could be larger */
  86.                  if (*this_time <= *other_time)
  87.                      *other_time = *this_time - 1L;
  88.              }
  89.          }
  90.          /* recognize the Valley of the Dead and Moloch's Sanctum
  91.             once hero has encountered the temple priest on those levels */
  92.          mapseen_temple(priest);
  93.      } else {
  94.          /* untended */
  95.  
  96.          switch (rn2(4)) {
  97.          case 0:
  98.              You("have an eerie feeling...");
  99.              break;
  100.          case 1:
  101.              You_feel("like you are being watched.");
  102.              break;
  103.          case 2:
  104.              pline("A shiver runs down your %s.", body_part(SPINE));
  105.              break;
  106.          default:
  107.              break; /* no message; unfortunately there's no
  108.                        EPRI(priest)->eerie_time available to
  109.                        make sure we give one the first time */
  110.          }
  111.          if (!rn2(5)
  112.              && (mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy, NO_MM_FLAGS))
  113.                     != 0) {
  114.              int ngen = mvitals[PM_GHOST].born;
  115.              if (canspotmon(mtmp))
  116.                  pline("A%s ghost appears next to you%c",
  117.                        ngen < 5 ? "n enormous" : "",
  118.                        ngen < 10 ? '!' : '.');
  119.              else
  120.                  You("sense a presence close by!");
  121.              mtmp->mpeaceful = 0;
  122.              set_malign(mtmp);
  123.              if (flags.verbose)
  124.                  You("are frightened to death, and unable to move.");
  125.              nomul(-3);
  126.              multi_reason = "being terrified of a ghost";
  127.              nomovemsg = "You regain your composure.";
  128.          }
  129.      }
  130.  }
  131.  

forget_temple_entry

  1.  /* reset the move counters used to limit temple entry feedback;
  2.     leaving the level and then returning yields a fresh start */
  3.  void
  4.  forget_temple_entry(priest)
  5.  struct monst *priest;
  6.  {
  7.      struct epri *epri_p = priest->ispriest ? EPRI(priest) : 0;
  8.  
  9.      if (!epri_p) {
  10.          impossible("attempting to manipulate shrine data for non-priest?");
  11.          return;
  12.      }
  13.      epri_p->intone_time = epri_p->enter_time = epri_p->peaceful_time =
  14.          epri_p->hostile_time = 0L;
  15.  }
  16.  

priest_talk

  1.  void
  2.  priest_talk(priest)
  3.  register struct monst *priest;
  4.  {
  5.      boolean coaligned = p_coaligned(priest);
  6.      boolean strayed = (u.ualign.record < 0);
  7.  
  8.      /* KMH, conduct */
  9.      u.uconduct.gnostic++;
  10.  
  11.      if (priest->mflee || (!priest->ispriest && coaligned && strayed)) {
  12.          pline("%s doesn't want anything to do with you!", Monnam(priest));
  13.          priest->mpeaceful = 0;
  14.          return;
  15.      }
  16.  
  17.      /* priests don't chat unless peaceful and in their own temple */
  18.      if (!inhistemple(priest) || !priest->mpeaceful
  19.          || !priest->mcanmove || priest->msleeping) {
  20.          static const char *cranky_msg[3] = {
  21.              "Thou wouldst have words, eh?  I'll give thee a word or two!",
  22.              "Talk?  Here is what I have to say!",
  23.              "Pilgrim, I would speak no longer with thee."
  24.          };
  25.  
  26.          if (!priest->mcanmove || priest->msleeping) {
  27.              pline("%s breaks out of %s reverie!", Monnam(priest),
  28.                    mhis(priest));
  29.              priest->mfrozen = priest->msleeping = 0;
  30.              priest->mcanmove = 1;
  31.          }
  32.          priest->mpeaceful = 0;
  33.          verbalize1(cranky_msg[rn2(3)]);
  34.          return;
  35.      }
  36.  
  37.      /* you desecrated the temple and now you want to chat? */
  38.      if (priest->mpeaceful && *in_rooms(priest->mx, priest->my, TEMPLE)
  39.          && !has_shrine(priest)) {
  40.          verbalize(
  41.                "Begone!  Thou desecratest this holy place with thy presence.");
  42.          priest->mpeaceful = 0;
  43.          return;
  44.      }
  45.      if (!money_cnt(invent)) {
  46.          if (coaligned && !strayed) {
  47.              long pmoney = money_cnt(priest->minvent);
  48.              if (pmoney > 0L) {
  49.                  /* Note: two bits is actually 25 cents.  Hmm. */
  50.                  pline("%s gives you %s for an ale.", Monnam(priest),
  51.                        (pmoney == 1L) ? "one bit" : "two bits");
  52.                  money2u(priest, pmoney > 1L ? 2 : 1);
  53.              } else
  54.                  pline("%s preaches the virtues of poverty.", Monnam(priest));
  55.              exercise(A_WIS, TRUE);
  56.          } else
  57.              pline("%s is not interested.", Monnam(priest));
  58.          return;
  59.      } else {
  60.          long offer;
  61.  
  62.          pline("%s asks you for a contribution for the temple.",
  63.                Monnam(priest));
  64.          if ((offer = bribe(priest)) == 0) {
  65.              verbalize("Thou shalt regret thine action!");
  66.              if (coaligned)
  67.                  adjalign(-1);
  68.          } else if (offer < (u.ulevel * 200)) {
  69.              if (money_cnt(invent) > (offer * 2L)) {
  70.                  verbalize("Cheapskate.");
  71.              } else {
  72.                  verbalize("I thank thee for thy contribution.");
  73.                  /* give player some token */
  74.                  exercise(A_WIS, TRUE);
  75.              }
  76.          } else if (offer < (u.ulevel * 400)) {
  77.              verbalize("Thou art indeed a pious individual.");
  78.              if (money_cnt(invent) < (offer * 2L)) {
  79.                  if (coaligned && u.ualign.record <= ALGN_SINNED)
  80.                      adjalign(1);
  81.                  verbalize("I bestow upon thee a blessing.");
  82.                  incr_itimeout(&HClairvoyant, rn1(500, 500));
  83.              }
  84.          } else if (offer < (u.ulevel * 600)
  85.                     /* u.ublessed is only active when Protection is
  86.                        enabled via something other than worn gear
  87.                        (theft by gremlin clears the intrinsic but not
  88.                        its former magnitude, making it recoverable) */
  89.                     && (!(HProtection & INTRINSIC)
  90.                         || (u.ublessed < 20
  91.                             && (u.ublessed < 9 || !rn2(u.ublessed))))) {
  92.              verbalize("Thy devotion has been rewarded.");
  93.              if (!(HProtection & INTRINSIC)) {
  94.                  HProtection |= FROMOUTSIDE;
  95.                  if (!u.ublessed)
  96.                      u.ublessed = rn1(3, 2);
  97.              } else
  98.                  u.ublessed++;
  99.          } else {
  100.              verbalize("Thy selfless generosity is deeply appreciated.");
  101.              if (money_cnt(invent) < (offer * 2L) && coaligned) {
  102.                  if (strayed && (moves - u.ucleansed) > 5000L) {
  103.                      u.ualign.record = 0; /* cleanse thee */
  104.                      u.ucleansed = moves;
  105.                  } else {
  106.                      adjalign(2);
  107.                  }
  108.              }
  109.          }
  110.      }
  111.  }
  112.  

mk_roamer

  1.  struct monst *
  2.  mk_roamer(ptr, alignment, x, y, peaceful)
  3.  register struct permonst *ptr;
  4.  aligntyp alignment;
  5.  xchar x, y;
  6.  boolean peaceful;
  7.  {
  8.      register struct monst *roamer;
  9.      register boolean coaligned = (u.ualign.type == alignment);
  10.  
  11.  #if 0 /* this was due to permonst's pxlth field which is now gone */
  12.      if (ptr != &mons[PM_ALIGNED_PRIEST] && ptr != &mons[PM_ANGEL])
  13.          return (struct monst *) 0;
  14.  #endif
  15.  
  16.      if (MON_AT(x, y))
  17.          (void) rloc(m_at(x, y), FALSE); /* insurance */
  18.  
  19.      if (!(roamer = makemon(ptr, x, y, MM_ADJACENTOK | MM_EMIN)))
  20.          return (struct monst *) 0;
  21.  
  22.      EMIN(roamer)->min_align = alignment;
  23.      EMIN(roamer)->renegade = (coaligned && !peaceful);
  24.      roamer->ispriest = 0;
  25.      roamer->isminion = 1;
  26.      roamer->mtrapseen = ~0; /* traps are known */
  27.      roamer->mpeaceful = peaceful;
  28.      roamer->msleeping = 0;
  29.      set_malign(roamer); /* peaceful may have changed */
  30.  
  31.      /* MORE TO COME */
  32.      return roamer;
  33.  }
  34.  

reset_hostility

  1.  void
  2.  reset_hostility(roamer)
  3.  register struct monst *roamer;
  4.  {
  5.      if (!roamer->isminion)
  6.          return;
  7.      if (roamer->data != &mons[PM_ALIGNED_PRIEST]
  8.          && roamer->data != &mons[PM_ANGEL])
  9.          return;
  10.  
  11.      if (EMIN(roamer)->min_align != u.ualign.type) {
  12.          roamer->mpeaceful = roamer->mtame = 0;
  13.          set_malign(roamer);
  14.      }
  15.      newsym(roamer->mx, roamer->my);
  16.  }
  17.  

in_your_sanctuary

  1.  boolean
  2.  in_your_sanctuary(mon, x, y)
  3.  struct monst *mon; /* if non-null, <mx,my> overrides <x,y> */
  4.  xchar x, y;
  5.  {
  6.      register char roomno;
  7.      register struct monst *priest;
  8.  
  9.      if (mon) {
  10.          if (is_minion(mon->data) || is_rider(mon->data))
  11.              return FALSE;
  12.          x = mon->mx, y = mon->my;
  13.      }
  14.      if (u.ualign.record <= ALGN_SINNED) /* sinned or worse */
  15.          return FALSE;
  16.      if ((roomno = temple_occupied(u.urooms)) == 0
  17.          || roomno != *in_rooms(x, y, TEMPLE))
  18.          return FALSE;
  19.      if ((priest = findpriest(roomno)) == 0)
  20.          return FALSE;
  21.      return (boolean) (has_shrine(priest) && p_coaligned(priest)
  22.                        && priest->mpeaceful);
  23.  }
  24.  

ghod_hitsu

  1.  /* when attacking "priest" in his temple */
  2.  void
  3.  ghod_hitsu(priest)
  4.  struct monst *priest;
  5.  {
  6.      int x, y, ax, ay, roomno = (int) temple_occupied(u.urooms);
  7.      struct mkroom *troom;
  8.  
  9.      if (!roomno || !has_shrine(priest))
  10.          return;
  11.  
  12.      ax = x = EPRI(priest)->shrpos.x;
  13.      ay = y = EPRI(priest)->shrpos.y;
  14.      troom = &rooms[roomno - ROOMOFFSET];
  15.  
  16.      if ((u.ux == x && u.uy == y) || !linedup(u.ux, u.uy, x, y, 1)) {
  17.          if (IS_DOOR(levl[u.ux][u.uy].typ)) {
  18.              if (u.ux == troom->lx - 1) {
  19.                  x = troom->hx;
  20.                  y = u.uy;
  21.              } else if (u.ux == troom->hx + 1) {
  22.                  x = troom->lx;
  23.                  y = u.uy;
  24.              } else if (u.uy == troom->ly - 1) {
  25.                  x = u.ux;
  26.                  y = troom->hy;
  27.              } else if (u.uy == troom->hy + 1) {
  28.                  x = u.ux;
  29.                  y = troom->ly;
  30.              }
  31.          } else {
  32.              switch (rn2(4)) {
  33.              case 0:
  34.                  x = u.ux;
  35.                  y = troom->ly;
  36.                  break;
  37.              case 1:
  38.                  x = u.ux;
  39.                  y = troom->hy;
  40.                  break;
  41.              case 2:
  42.                  x = troom->lx;
  43.                  y = u.uy;
  44.                  break;
  45.              default:
  46.                  x = troom->hx;
  47.                  y = u.uy;
  48.                  break;
  49.              }
  50.          }
  51.          if (!linedup(u.ux, u.uy, x, y, 1))
  52.              return;
  53.      }
  54.  
  55.      switch (rn2(3)) {
  56.      case 0:
  57.          pline("%s roars in anger:  \"Thou shalt suffer!\"",
  58.                a_gname_at(ax, ay));
  59.          break;
  60.      case 1:
  61.          pline("%s voice booms:  \"How darest thou harm my servant!\"",
  62.                s_suffix(a_gname_at(ax, ay)));
  63.          break;
  64.      default:
  65.          pline("%s roars:  \"Thou dost profane my shrine!\"",
  66.                a_gname_at(ax, ay));
  67.          break;
  68.      }
  69.  
  70.      buzz(-10 - (AD_ELEC - 1), 6, x, y, sgn(tbx),
  71.           sgn(tby)); /* bolt of lightning */
  72.      exercise(A_WIS, FALSE);
  73.  }
  74.  

angry_priest

  1.  void
  2.  angry_priest()
  3.  {
  4.      register struct monst *priest;
  5.      struct rm *lev;
  6.  
  7.      if ((priest = findpriest(temple_occupied(u.urooms))) != 0) {
  8.          struct epri *eprip = EPRI(priest);
  9.  
  10.          wakeup(priest, FALSE);
  11.          setmangry(priest, FALSE);
  12.          /*
  13.           * If the altar has been destroyed or converted, let the
  14.           * priest run loose.
  15.           * (When it's just a conversion and there happens to be
  16.           * a fresh corpse nearby, the priest ought to have an
  17.           * opportunity to try converting it back; maybe someday...)
  18.           */
  19.          lev = &levl[eprip->shrpos.x][eprip->shrpos.y];
  20.          if (!IS_ALTAR(lev->typ)
  21.              || ((aligntyp) Amask2align(lev->altarmask & AM_MASK)
  22.                  != eprip->shralign)) {
  23.              if (!EMIN(priest))
  24.                  newemin(priest);
  25.              priest->ispriest = 0; /* now a roaming minion */
  26.              priest->isminion = 1;
  27.              EMIN(priest)->min_align = eprip->shralign;
  28.              EMIN(priest)->renegade = FALSE;
  29.              /* discard priest's memory of his former shrine;
  30.                 if we ever implement the re-conversion mentioned
  31.                 above, this will need to be removed */
  32.              free_epri(priest);
  33.          }
  34.      }
  35.  }
  36.  

clearpriests

  1.  /*
  2.   * When saving bones, find priests that aren't on their shrine level,
  3.   * and remove them.  This avoids big problems when restoring bones.
  4.   * [Perhaps we should convert them into roamers instead?]
  5.   */
  6.  void
  7.  clearpriests()
  8.  {
  9.      struct monst *mtmp;
  10.  
  11.      for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
  12.          if (DEADMONSTER(mtmp))
  13.              continue;
  14.          if (mtmp->ispriest && !on_level(&(EPRI(mtmp)->shrlevel), &u.uz))
  15.              mongone(mtmp);
  16.      }
  17.  }
  18.  

restpriest

  1.  /* munge priest-specific structure when restoring -dlc */
  2.  void
  3.  restpriest(mtmp, ghostly)
  4.  register struct monst *mtmp;
  5.  boolean ghostly;
  6.  {
  7.      if (u.uz.dlevel) {
  8.          if (ghostly)
  9.              assign_level(&(EPRI(mtmp)->shrlevel), &u.uz);
  10.      }
  11.  }
  12.  

align_str

  1.  /*
  2.   * align_str(), piousness(), mstatusline() and ustatusline() used to be
  3.   * in pline.c, presumeably because the latter two generate one line of
  4.   * output.  The USE_OLDARGS config gets warnings from 2016ish-vintage
  5.   * gcc (for -Wint-to-pointer-cast, activated by -Wall or -W) when they
  6.   * follow pline() itself.  Fixing up the variadic calls like is done for
  7.   * lev_comp would be needlessly messy there.
  8.   *
  9.   * They don't belong here.  If/when enlightenment ever gets split off
  10.   * from cmd.c (which definitely doesn't belong there), they should go
  11.   * with it.
  12.   */
  13.  
  14.  const char *
  15.  align_str(alignment)
  16.  aligntyp alignment;
  17.  {
  18.      switch ((int) alignment) {
  19.      case A_CHAOTIC:
  20.          return "chaotic";
  21.      case A_NEUTRAL:
  22.          return "neutral";
  23.      case A_LAWFUL:
  24.          return "lawful";
  25.      case A_NONE:
  26.          return "unaligned";
  27.      }
  28.      return "unknown";
  29.  }
  30.  

piousness

  1.  /* used for self-probing */
  2.  char *
  3.  piousness(showneg, suffix)
  4.  boolean showneg;
  5.  const char *suffix;
  6.  {
  7.      static char buf[32]; /* bigger than "insufficiently neutral" */
  8.      const char *pio;
  9.  
  10.      /* note: piousness 20 matches MIN_QUEST_ALIGN (quest.h) */
  11.      if (u.ualign.record >= 20)
  12.          pio = "piously";
  13.      else if (u.ualign.record > 13)
  14.          pio = "devoutly";
  15.      else if (u.ualign.record > 8)
  16.          pio = "fervently";
  17.      else if (u.ualign.record > 3)
  18.          pio = "stridently";
  19.      else if (u.ualign.record == 3)
  20.          pio = "";
  21.      else if (u.ualign.record > 0)
  22.          pio = "haltingly";
  23.      else if (u.ualign.record == 0)
  24.          pio = "nominally";
  25.      else if (!showneg)
  26.          pio = "insufficiently";
  27.      else if (u.ualign.record >= -3)
  28.          pio = "strayed";
  29.      else if (u.ualign.record >= -8)
  30.          pio = "sinned";
  31.      else
  32.          pio = "transgressed";
  33.  
  34.      Sprintf(buf, "%s", pio);
  35.      if (suffix && (!showneg || u.ualign.record >= 0)) {
  36.          if (u.ualign.record != 3)
  37.              Strcat(buf, " ");
  38.          Strcat(buf, suffix);
  39.      }
  40.      return buf;
  41.  }
  42.  

mstatusline

  1.  /* stethoscope or probing applied to monster -- one-line feedback */
  2.  void
  3.  mstatusline(mtmp)
  4.  struct monst *mtmp;
  5.  {
  6.      aligntyp alignment = mon_aligntyp(mtmp);
  7.      char info[BUFSZ], monnambuf[BUFSZ];
  8.  
  9.      info[0] = 0;
  10.      if (mtmp->mtame) {
  11.          Strcat(info, ", tame");
  12.          if (wizard) {
  13.              Sprintf(eos(info), " (%d", mtmp->mtame);
  14.              if (!mtmp->isminion)
  15.                  Sprintf(eos(info), "; hungry %ld; apport %d",
  16.                          EDOG(mtmp)->hungrytime, EDOG(mtmp)->apport);
  17.              Strcat(info, ")");
  18.          }
  19.      } else if (mtmp->mpeaceful)
  20.          Strcat(info, ", peaceful");
  21.  
  22.      if (mtmp->data == &mons[PM_LONG_WORM]) {
  23.          int segndx, nsegs = count_wsegs(mtmp);
  24.  
  25.          /* the worm code internals don't consider the head of be one of
  26.             the worm's segments, but we count it as such when presenting
  27.             worm feedback to the player */
  28.          if (!nsegs) {
  29.              Strcat(info, ", single segment");
  30.          } else {
  31.              ++nsegs; /* include head in the segment count */
  32.              segndx = wseg_at(mtmp, bhitpos.x, bhitpos.y);
  33.              Sprintf(eos(info), ", %d%s of %d segments",
  34.                      segndx, ordin(segndx), nsegs);
  35.          }
  36.      }
  37.      if (mtmp->cham >= LOW_PM && mtmp->data != &mons[mtmp->cham])
  38.          /* don't reveal the innate form (chameleon, vampire, &c),
  39.             just expose the fact that this current form isn't it */
  40.          Strcat(info, ", shapechanger");
  41.      /* pets eating mimic corpses mimic while eating, so this comes first */
  42.      if (mtmp->meating)
  43.          Strcat(info, ", eating");
  44.      /* a stethoscope exposes mimic before getting here so this
  45.         won't be relevant for it, but wand of probing doesn't */
  46.      if (mtmp->mundetected || mtmp->m_ap_type)
  47.          mhidden_description(mtmp, TRUE, eos(info));
  48.      if (mtmp->mcan)
  49.          Strcat(info, ", cancelled");
  50.      if (mtmp->mconf)
  51.          Strcat(info, ", confused");
  52.      if (mtmp->mblinded || !mtmp->mcansee)
  53.          Strcat(info, ", blind");
  54.      if (mtmp->mstun)
  55.          Strcat(info, ", stunned");
  56.      if (mtmp->msleeping)
  57.          Strcat(info, ", asleep");
  58.  #if 0 /* unfortunately mfrozen covers temporary sleep and being busy \
  59.           (donning armor, for instance) as well as paralysis */
  60.      else if (mtmp->mfrozen)
  61.          Strcat(info, ", paralyzed");
  62.  #else
  63.      else if (mtmp->mfrozen || !mtmp->mcanmove)
  64.          Strcat(info, ", can't move");
  65.  #endif
  66.      /* [arbitrary reason why it isn't moving] */
  67.      else if (mtmp->mstrategy & STRAT_WAITMASK)
  68.          Strcat(info, ", meditating");
  69.      if (mtmp->mflee)
  70.          Strcat(info, ", scared");
  71.      if (mtmp->mtrapped)
  72.          Strcat(info, ", trapped");
  73.      if (mtmp->mspeed)
  74.          Strcat(info, (mtmp->mspeed == MFAST) ? ", fast"
  75.                        : (mtmp->mspeed == MSLOW) ? ", slow"
  76.                           : ", [? speed]");
  77.      if (mtmp->minvis)
  78.          Strcat(info, ", invisible");
  79.      if (mtmp == u.ustuck)
  80.          Strcat(info, sticks(youmonst.data) ? ", held by you"
  81.                        : !u.uswallow ? ", holding you"
  82.                           : attacktype_fordmg(u.ustuck->data, AT_ENGL, AD_DGST)
  83.                              ? ", digesting you"
  84.                              : is_animal(u.ustuck->data) ? ", swallowing you"
  85.                                 : ", engulfing you");
  86.      if (mtmp == u.usteed)
  87.          Strcat(info, ", carrying you");
  88.  
  89.      /* avoid "Status of the invisible newt ..., invisible" */
  90.      /* and unlike a normal mon_nam, use "saddled" even if it has a name */
  91.      Strcpy(monnambuf, x_monnam(mtmp, ARTICLE_THE, (char *) 0,
  92.                                 (SUPPRESS_IT | SUPPRESS_INVISIBLE), FALSE));
  93.  
  94.      pline("Status of %s (%s):  Level %d  HP %d(%d)  AC %d%s.", monnambuf,
  95.            align_str(alignment), mtmp->m_lev, mtmp->mhp, mtmp->mhpmax,
  96.            find_mac(mtmp), info);
  97.  }
  98.  

ustatusline

  1.  /* stethoscope or probing applied to hero -- one-line feedback */
  2.  void
  3.  ustatusline()
  4.  {
  5.      char info[BUFSZ];
  6.  
  7.      info[0] = '\0';
  8.      if (Sick) {
  9.          Strcat(info, ", dying from");
  10.          if (u.usick_type & SICK_VOMITABLE)
  11.              Strcat(info, " food poisoning");
  12.          if (u.usick_type & SICK_NONVOMITABLE) {
  13.              if (u.usick_type & SICK_VOMITABLE)
  14.                  Strcat(info, " and");
  15.              Strcat(info, " illness");
  16.          }
  17.      }
  18.      if (Stoned)
  19.          Strcat(info, ", solidifying");
  20.      if (Slimed)
  21.          Strcat(info, ", becoming slimy");
  22.      if (Strangled)
  23.          Strcat(info, ", being strangled");
  24.      if (Vomiting)
  25.          Strcat(info, ", nauseated"); /* !"nauseous" */
  26.      if (Confusion)
  27.          Strcat(info, ", confused");
  28.      if (Blind) {
  29.          Strcat(info, ", blind");
  30.          if (u.ucreamed) {
  31.              if ((long) u.ucreamed < Blinded || Blindfolded
  32.                  || !haseyes(youmonst.data))
  33.                  Strcat(info, ", cover");
  34.              Strcat(info, "ed by sticky goop");
  35.          } /* note: "goop" == "glop"; variation is intentional */
  36.      }
  37.      if (Stunned)
  38.          Strcat(info, ", stunned");
  39.      if (!u.usteed && Wounded_legs) {
  40.          const char *what = body_part(LEG);
  41.          if ((Wounded_legs & BOTH_SIDES) == BOTH_SIDES)
  42.              what = makeplural(what);
  43.          Sprintf(eos(info), ", injured %s", what);
  44.      }
  45.      if (Glib)
  46.          Sprintf(eos(info), ", slippery %s", makeplural(body_part(HAND)));
  47.      if (u.utrap)
  48.          Strcat(info, ", trapped");
  49.      if (Fast)
  50.          Strcat(info, Very_fast ? ", very fast" : ", fast");
  51.      if (u.uundetected)
  52.          Strcat(info, ", concealed");
  53.      if (Invis)
  54.          Strcat(info, ", invisible");
  55.      if (u.ustuck) {
  56.          if (sticks(youmonst.data))
  57.              Strcat(info, ", holding ");
  58.          else
  59.              Strcat(info, ", held by ");
  60.          Strcat(info, mon_nam(u.ustuck));
  61.      }
  62.  
  63.      pline("Status of %s (%s):  Level %d  HP %d(%d)  AC %d%s.", plname,
  64.            piousness(FALSE, align_str(u.ualign.type)),
  65.            Upolyd ? mons[u.umonnum].mlevel : u.ulevel, Upolyd ? u.mh : u.uhp,
  66.            Upolyd ? u.mhmax : u.uhpmax, u.uac, info);
  67.  }
  68.  
  69.  /*priest.c*/