Source:NetHack 3.6.0/src/mkroom.c

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

Below is the full text to mkroom.c from the source code of NetHack 3.6.0. To link to a particular line, write [[Source:NetHack 3.6.0/src/mkroom.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	mkroom.c	$NHDT-Date: 1446887530 2015/11/07 09:12:10 $  $NHDT-Branch: master $:$NHDT-Revision: 1.24 $ */
  2.  /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
  3.  /* NetHack may be freely redistributed.  See license for details. */
  4.  
  5.  /*
  6.   * Entry points:
  7.   *      mkroom() -- make and stock a room of a given type
  8.   *      nexttodoor() -- return TRUE if adjacent to a door
  9.   *      has_dnstairs() -- return TRUE if given room has a down staircase
  10.   *      has_upstairs() -- return TRUE if given room has an up staircase
  11.   *      courtmon() -- generate a court monster
  12.   *      save_rooms() -- save rooms into file fd
  13.   *      rest_rooms() -- restore rooms from file fd
  14.   *      cmap_to_type() -- convert S_xxx symbol to XXX topology code
  15.   */
  16.  
  17.  #include "hack.h"
  18.  
  19.  STATIC_DCL boolean FDECL(isbig, (struct mkroom *));
  20.  STATIC_DCL struct mkroom *FDECL(pick_room, (BOOLEAN_P));
  21.  STATIC_DCL void NDECL(mkshop), FDECL(mkzoo, (int)), NDECL(mkswamp);
  22.  STATIC_DCL void NDECL(mktemple);
  23.  STATIC_DCL coord *FDECL(shrine_pos, (int));
  24.  STATIC_DCL struct permonst *NDECL(morguemon);
  25.  STATIC_DCL struct permonst *NDECL(squadmon);
  26.  STATIC_DCL void FDECL(save_room, (int, struct mkroom *));
  27.  STATIC_DCL void FDECL(rest_room, (int, struct mkroom *));
  28.  
  29.  #define sq(x) ((x) * (x))
  30.  
  31.  extern const struct shclass shtypes[]; /* defined in shknam.c */
  32.  

isbig

  1.  STATIC_OVL boolean
  2.  isbig(sroom)
  3.  register struct mkroom *sroom;
  4.  {
  5.      register int area = (sroom->hx - sroom->lx + 1)
  6.                          * (sroom->hy - sroom->ly + 1);
  7.  
  8.      return (boolean) (area > 20);
  9.  }
  10.  

mkroom

  1.  /* make and stock a room of a given type */
  2.  void
  3.  mkroom(roomtype)
  4.  int roomtype;
  5.  {
  6.      if (roomtype >= SHOPBASE)
  7.          mkshop(); /* someday, we should be able to specify shop type */
  8.      else
  9.          switch (roomtype) {
  10.          case COURT:
  11.              mkzoo(COURT);
  12.              break;
  13.          case ZOO:
  14.              mkzoo(ZOO);
  15.              break;
  16.          case BEEHIVE:
  17.              mkzoo(BEEHIVE);
  18.              break;
  19.          case MORGUE:
  20.              mkzoo(MORGUE);
  21.              break;
  22.          case BARRACKS:
  23.              mkzoo(BARRACKS);
  24.              break;
  25.          case SWAMP:
  26.              mkswamp();
  27.              break;
  28.          case TEMPLE:
  29.              mktemple();
  30.              break;
  31.          case LEPREHALL:
  32.              mkzoo(LEPREHALL);
  33.              break;
  34.          case COCKNEST:
  35.              mkzoo(COCKNEST);
  36.              break;
  37.          case ANTHOLE:
  38.              mkzoo(ANTHOLE);
  39.              break;
  40.          default:
  41.              impossible("Tried to make a room of type %d.", roomtype);
  42.          }
  43.  }
  44.  

mkshop

  1.  STATIC_OVL void
  2.  mkshop()
  3.  {
  4.      register struct mkroom *sroom;
  5.      int i = -1;
  6.      char *ep = (char *) 0; /* (init == lint suppression) */
  7.  
  8.      /* first determine shoptype */
  9.      if (wizard) {
  10.  #ifndef MAC
  11.          ep = nh_getenv("SHOPTYPE");
  12.          if (ep) {
  13.              if (*ep == 'z' || *ep == 'Z') {
  14.                  mkzoo(ZOO);
  15.                  return;
  16.              }
  17.              if (*ep == 'm' || *ep == 'M') {
  18.                  mkzoo(MORGUE);
  19.                  return;
  20.              }
  21.              if (*ep == 'b' || *ep == 'B') {
  22.                  mkzoo(BEEHIVE);
  23.                  return;
  24.              }
  25.              if (*ep == 't' || *ep == 'T' || *ep == '\\') {
  26.                  mkzoo(COURT);
  27.                  return;
  28.              }
  29.              if (*ep == 's' || *ep == 'S') {
  30.                  mkzoo(BARRACKS);
  31.                  return;
  32.              }
  33.              if (*ep == 'a' || *ep == 'A') {
  34.                  mkzoo(ANTHOLE);
  35.                  return;
  36.              }
  37.              if (*ep == 'c' || *ep == 'C') {
  38.                  mkzoo(COCKNEST);
  39.                  return;
  40.              }
  41.              if (*ep == 'l' || *ep == 'L') {
  42.                  mkzoo(LEPREHALL);
  43.                  return;
  44.              }
  45.              if (*ep == '_') {
  46.                  mktemple();
  47.                  return;
  48.              }
  49.              if (*ep == '}') {
  50.                  mkswamp();
  51.                  return;
  52.              }
  53.              for (i = 0; shtypes[i].name; i++)
  54.                  if (*ep == def_oc_syms[(int) shtypes[i].symb].sym)
  55.                      goto gottype;
  56.              if (*ep == 'g' || *ep == 'G')
  57.                  i = 0;
  58.              else if (*ep == 'v' || *ep == 'V')
  59.                  i = FODDERSHOP - SHOPBASE; /* veggy food */
  60.              else
  61.                  i = -1;
  62.          }
  63.  #endif
  64.      }
  65.  #ifndef MAC
  66.  gottype:
  67.  #endif
  68.      for (sroom = &rooms[0];; sroom++) {
  69.          if (sroom->hx < 0)
  70.              return;
  71.          if (sroom - rooms >= nroom) {
  72.              pline("rooms not closed by -1?");
  73.              return;
  74.          }
  75.          if (sroom->rtype != OROOM)
  76.              continue;
  77.          if (has_dnstairs(sroom) || has_upstairs(sroom))
  78.              continue;
  79.          if ((wizard && ep && sroom->doorct != 0) || sroom->doorct == 1)
  80.              break;
  81.      }
  82.      if (!sroom->rlit) {
  83.          int x, y;
  84.  
  85.          for (x = sroom->lx - 1; x <= sroom->hx + 1; x++)
  86.              for (y = sroom->ly - 1; y <= sroom->hy + 1; y++)
  87.                  levl[x][y].lit = 1;
  88.          sroom->rlit = 1;
  89.      }
  90.  
  91.      if (i < 0) { /* shoptype not yet determined */
  92.          register int j;
  93.  
  94.          /* pick a shop type at random */
  95.          for (j = rnd(100), i = 0; (j -= shtypes[i].prob) > 0; i++)
  96.              continue;
  97.  
  98.          /* big rooms cannot be wand or book shops,
  99.           * - so make them general stores
  100.           */
  101.          if (isbig(sroom) && (shtypes[i].symb == WAND_CLASS
  102.                               || shtypes[i].symb == SPBOOK_CLASS))
  103.              i = 0;
  104.      }
  105.      sroom->rtype = SHOPBASE + i;
  106.  
  107.      /* set room bits before stocking the shop */
  108.  #ifdef SPECIALIZATION
  109.      topologize(sroom, FALSE); /* doesn't matter - this is a special room */
  110.  #else
  111.      topologize(sroom);
  112.  #endif
  113.  
  114.      /* stock the room with a shopkeeper and artifacts */
  115.      stock_room(i, sroom);
  116.  }
  117.  

pick_room

  1.  /* pick an unused room, preferably with only one door */
  2.  STATIC_OVL struct mkroom *
  3.  pick_room(strict)
  4.  register boolean strict;
  5.  {
  6.      register struct mkroom *sroom;
  7.      register int i = nroom;
  8.  
  9.      for (sroom = &rooms[rn2(nroom)]; i--; sroom++) {
  10.          if (sroom == &rooms[nroom])
  11.              sroom = &rooms[0];
  12.          if (sroom->hx < 0)
  13.              return (struct mkroom *) 0;
  14.          if (sroom->rtype != OROOM)
  15.              continue;
  16.          if (!strict) {
  17.              if (has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
  18.                  continue;
  19.          } else if (has_upstairs(sroom) || has_dnstairs(sroom))
  20.              continue;
  21.          if (sroom->doorct == 1 || !rn2(5) || wizard)
  22.              return sroom;
  23.      }
  24.      return (struct mkroom *) 0;
  25.  }
  26.  

mkzoo

  1.  STATIC_OVL void
  2.  mkzoo(type)
  3.  int type;
  4.  {
  5.      register struct mkroom *sroom;
  6.  
  7.      if ((sroom = pick_room(FALSE)) != 0) {
  8.          sroom->rtype = type;
  9.          fill_zoo(sroom);
  10.      }
  11.  }
  12.  

fill_zoo

  1.  void
  2.  fill_zoo(sroom)
  3.  struct mkroom *sroom;
  4.  {
  5.      struct monst *mon;
  6.      register int sx, sy, i;
  7.      int sh, tx = 0, ty = 0, goldlim = 0, type = sroom->rtype;
  8.      int rmno = (int) ((sroom - rooms) + ROOMOFFSET);
  9.      coord mm;
  10.  
  11.      sh = sroom->fdoor;
  12.      switch (type) {
  13.      case COURT:
  14.          if (level.flags.is_maze_lev) {
  15.              for (tx = sroom->lx; tx <= sroom->hx; tx++)
  16.                  for (ty = sroom->ly; ty <= sroom->hy; ty++)
  17.                      if (IS_THRONE(levl[tx][ty].typ))
  18.                          goto throne_placed;
  19.          }
  20.          i = 100;
  21.          do { /* don't place throne on top of stairs */
  22.              (void) somexy(sroom, &mm);
  23.              tx = mm.x;
  24.              ty = mm.y;
  25.          } while (occupied((xchar) tx, (xchar) ty) && --i > 0);
  26.      throne_placed:
  27.          /* TODO: try to ensure the enthroned monster is an M2_PRINCE */
  28.          break;
  29.      case BEEHIVE:
  30.          tx = sroom->lx + (sroom->hx - sroom->lx + 1) / 2;
  31.          ty = sroom->ly + (sroom->hy - sroom->ly + 1) / 2;
  32.          if (sroom->irregular) {
  33.              /* center might not be valid, so put queen elsewhere */
  34.              if ((int) levl[tx][ty].roomno != rmno || levl[tx][ty].edge) {
  35.                  (void) somexy(sroom, &mm);
  36.                  tx = mm.x;
  37.                  ty = mm.y;
  38.              }
  39.          }
  40.          break;
  41.      case ZOO:
  42.      case LEPREHALL:
  43.          goldlim = 500 * level_difficulty();
  44.          break;
  45.      }
  46.  
  47.      for (sx = sroom->lx; sx <= sroom->hx; sx++)
  48.          for (sy = sroom->ly; sy <= sroom->hy; sy++) {
  49.              if (sroom->irregular) {
  50.                  if ((int) levl[sx][sy].roomno != rmno || levl[sx][sy].edge
  51.                      || (sroom->doorct
  52.                          && distmin(sx, sy, doors[sh].x, doors[sh].y) <= 1))
  53.                      continue;
  54.              } else if (!SPACE_POS(levl[sx][sy].typ)
  55.                         || (sroom->doorct
  56.                             && ((sx == sroom->lx && doors[sh].x == sx - 1)
  57.                                 || (sx == sroom->hx && doors[sh].x == sx + 1)
  58.                                 || (sy == sroom->ly && doors[sh].y == sy - 1)
  59.                                 || (sy == sroom->hy
  60.                                     && doors[sh].y == sy + 1))))
  61.                  continue;
  62.              /* don't place monster on explicitly placed throne */
  63.              if (type == COURT && IS_THRONE(levl[sx][sy].typ))
  64.                  continue;
  65.              mon = makemon((type == COURT)
  66.                             ? courtmon()
  67.                             : (type == BARRACKS)
  68.                                ? squadmon()
  69.                                : (type == MORGUE)
  70.                                   ? morguemon()
  71.                                   : (type == BEEHIVE)
  72.                                       ? (sx == tx && sy == ty
  73.                                           ? &mons[PM_QUEEN_BEE]
  74.                                           : &mons[PM_KILLER_BEE])
  75.                                       : (type == LEPREHALL)
  76.                                           ? &mons[PM_LEPRECHAUN]
  77.                                           : (type == COCKNEST)
  78.                                               ? &mons[PM_COCKATRICE]
  79.                                               : (type == ANTHOLE)
  80.                                                   ? antholemon()
  81.                                                   : (struct permonst *) 0,
  82.                            sx, sy, NO_MM_FLAGS);
  83.              if (mon) {
  84.                  mon->msleeping = 1;
  85.                  if (type == COURT && mon->mpeaceful) {
  86.                      mon->mpeaceful = 0;
  87.                      set_malign(mon);
  88.                  }
  89.              }
  90.              switch (type) {
  91.              case ZOO:
  92.              case LEPREHALL:
  93.                  if (sroom->doorct) {
  94.                      int distval = dist2(sx, sy, doors[sh].x, doors[sh].y);
  95.                      i = sq(distval);
  96.                  } else
  97.                      i = goldlim;
  98.                  if (i >= goldlim)
  99.                      i = 5 * level_difficulty();
  100.                  goldlim -= i;
  101.                  (void) mkgold((long) rn1(i, 10), sx, sy);
  102.                  break;
  103.              case MORGUE:
  104.                  if (!rn2(5))
  105.                      (void) mk_tt_object(CORPSE, sx, sy);
  106.                  if (!rn2(10)) /* lots of treasure buried with dead */
  107.                      (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy,
  108.                                       TRUE, FALSE);
  109.                  if (!rn2(5))
  110.                      make_grave(sx, sy, (char *) 0);
  111.                  break;
  112.              case BEEHIVE:
  113.                  if (!rn2(3))
  114.                      (void) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy, TRUE,
  115.                                       FALSE);
  116.                  break;
  117.              case BARRACKS:
  118.                  if (!rn2(20)) /* the payroll and some loot */
  119.                      (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy,
  120.                                       TRUE, FALSE);
  121.                  break;
  122.              case COCKNEST:
  123.                  if (!rn2(3)) {
  124.                      struct obj *sobj = mk_tt_object(STATUE, sx, sy);
  125.  
  126.                      if (sobj) {
  127.                          for (i = rn2(5); i; i--)
  128.                              (void) add_to_container(
  129.                                  sobj, mkobj(RANDOM_CLASS, FALSE));
  130.                          sobj->owt = weight(sobj);
  131.                      }
  132.                  }
  133.                  break;
  134.              case ANTHOLE:
  135.                  if (!rn2(3))
  136.                      (void) mkobj_at(FOOD_CLASS, sx, sy, FALSE);
  137.                  break;
  138.              }
  139.          }
  140.      switch (type) {
  141.      case COURT: {
  142.          struct obj *chest;
  143.          levl[tx][ty].typ = THRONE;
  144.          (void) somexy(sroom, &mm);
  145.          (void) mkgold((long) rn1(50 * level_difficulty(), 10), mm.x, mm.y);
  146.          /* the royal coffers */
  147.          chest = mksobj_at(CHEST, mm.x, mm.y, TRUE, FALSE);
  148.          chest->spe = 2; /* so it can be found later */
  149.          level.flags.has_court = 1;
  150.          break;
  151.      }
  152.      case BARRACKS:
  153.          level.flags.has_barracks = 1;
  154.          break;
  155.      case ZOO:
  156.          level.flags.has_zoo = 1;
  157.          break;
  158.      case MORGUE:
  159.          level.flags.has_morgue = 1;
  160.          break;
  161.      case SWAMP:
  162.          level.flags.has_swamp = 1;
  163.          break;
  164.      case BEEHIVE:
  165.          level.flags.has_beehive = 1;
  166.          break;
  167.      }
  168.  }
  169.  

mkundead

  1.  /* make a swarm of undead around mm */
  2.  void
  3.  mkundead(mm, revive_corpses, mm_flags)
  4.  coord *mm;
  5.  boolean revive_corpses;
  6.  int mm_flags;
  7.  {
  8.      int cnt = (level_difficulty() + 1) / 10 + rnd(5);
  9.      struct permonst *mdat;
  10.      struct obj *otmp;
  11.      coord cc;
  12.  
  13.      while (cnt--) {
  14.          mdat = morguemon();
  15.          if (mdat && enexto(&cc, mm->x, mm->y, mdat)
  16.              && (!revive_corpses
  17.                  || !(otmp = sobj_at(CORPSE, cc.x, cc.y))
  18.                  || !revive(otmp, FALSE)))
  19.              (void) makemon(mdat, cc.x, cc.y, mm_flags);
  20.      }
  21.      level.flags.graveyard = TRUE; /* reduced chance for undead corpse */
  22.  }
  23.  

morguemon

  1.  STATIC_OVL struct permonst *
  2.  morguemon()
  3.  {
  4.      register int i = rn2(100), hd = rn2(level_difficulty());
  5.  
  6.      if (hd > 10 && i < 10) {
  7.          if (Inhell || In_endgame(&u.uz)) {
  8.              return mkclass(S_DEMON, 0);
  9.          } else {
  10.              int ndemon_res = ndemon(A_NONE);
  11.              if (ndemon_res != NON_PM)
  12.                  return &mons[ndemon_res];
  13.              /* else do what? As is, it will drop to ghost/wraith/zombie */
  14.          }
  15.      }
  16.  
  17.      if (hd > 8 && i > 85)
  18.          return mkclass(S_VAMPIRE, 0);
  19.  
  20.      return ((i < 20) ? &mons[PM_GHOST]
  21.                       : (i < 40) ? &mons[PM_WRAITH]
  22.                                  : mkclass(S_ZOMBIE, 0));
  23.  }
  24.  

antholemon

  1.  struct permonst *
  2.  antholemon()
  3.  {
  4.      int mtyp, indx, trycnt = 0;
  5.  
  6.      /* casts are for dealing with time_t */
  7.      indx = (int) ((long) ubirthday % 3L);
  8.      indx += level_difficulty();
  9.      /* Same monsters within a level, different ones between levels */
  10.      do {
  11.          switch ((indx + trycnt) % 3) {
  12.          case 0:
  13.              mtyp = PM_SOLDIER_ANT;
  14.              break;
  15.          case 1:
  16.              mtyp = PM_FIRE_ANT;
  17.              break;
  18.          default:
  19.              mtyp = PM_GIANT_ANT;
  20.              break;
  21.          }
  22.          /* try again if chosen type has been genocided or used up */
  23.      } while (++trycnt < 3 && (mvitals[mtyp].mvflags & G_GONE));
  24.  
  25.      return ((mvitals[mtyp].mvflags & G_GONE) ? (struct permonst *) 0
  26.                                               : &mons[mtyp]);
  27.  }
  28.  

mkswamp

  1.  STATIC_OVL void
  2.  mkswamp() /* Michiel Huisjes & Fred de Wilde */
  3.  {
  4.      register struct mkroom *sroom;
  5.      register int sx, sy, i, eelct = 0;
  6.  
  7.      for (i = 0; i < 5; i++) { /* turn up to 5 rooms swampy */
  8.          sroom = &rooms[rn2(nroom)];
  9.          if (sroom->hx < 0 || sroom->rtype != OROOM || has_upstairs(sroom)
  10.              || has_dnstairs(sroom))
  11.              continue;
  12.  
  13.          /* satisfied; make a swamp */
  14.          sroom->rtype = SWAMP;
  15.          for (sx = sroom->lx; sx <= sroom->hx; sx++)
  16.              for (sy = sroom->ly; sy <= sroom->hy; sy++)
  17.                  if (!OBJ_AT(sx, sy) && !MON_AT(sx, sy) && !t_at(sx, sy)
  18.                      && !nexttodoor(sx, sy)) {
  19.                      if ((sx + sy) % 2) {
  20.                          levl[sx][sy].typ = POOL;
  21.                          if (!eelct || !rn2(4)) {
  22.                              /* mkclass() won't do, as we might get kraken */
  23.                              (void) makemon(rn2(5)
  24.                                                ? &mons[PM_GIANT_EEL]
  25.                                                : rn2(2)
  26.                                                   ? &mons[PM_PIRANHA]
  27.                                                   : &mons[PM_ELECTRIC_EEL],
  28.                                             sx, sy, NO_MM_FLAGS);
  29.                              eelct++;
  30.                          }
  31.                      } else if (!rn2(4)) /* swamps tend to be moldy */
  32.                          (void) makemon(mkclass(S_FUNGUS, 0), sx, sy,
  33.                                         NO_MM_FLAGS);
  34.                  }
  35.          level.flags.has_swamp = 1;
  36.      }
  37.  }
  38.  

shrine_pos

  1.  STATIC_OVL coord *
  2.  shrine_pos(roomno)
  3.  int roomno;
  4.  {
  5.      static coord buf;
  6.      int delta;
  7.      struct mkroom *troom = &rooms[roomno - ROOMOFFSET];
  8.  
  9.      /* if width and height are odd, placement will be the exact center;
  10.         if either or both are even, center point is a hypothetical spot
  11.         between map locations and placement will be adjacent to that */
  12.      delta = troom->hx - troom->lx;
  13.      buf.x = troom->lx + delta / 2;
  14.      if ((delta % 2) && rn2(2))
  15.          buf.x++;
  16.      delta = troom->hy - troom->ly;
  17.      buf.y = troom->ly + delta / 2;
  18.      if ((delta % 2) && rn2(2))
  19.          buf.y++;
  20.      return &buf;
  21.  }
  22.  

mktemple

  1.  STATIC_OVL void
  2.  mktemple()
  3.  {
  4.      register struct mkroom *sroom;
  5.      coord *shrine_spot;
  6.      register struct rm *lev;
  7.  
  8.      if (!(sroom = pick_room(TRUE)))
  9.          return;
  10.  
  11.      /* set up Priest and shrine */
  12.      sroom->rtype = TEMPLE;
  13.      /*
  14.       * In temples, shrines are blessed altars
  15.       * located in the center of the room
  16.       */
  17.      shrine_spot = shrine_pos((int) ((sroom - rooms) + ROOMOFFSET));
  18.      lev = &levl[shrine_spot->x][shrine_spot->y];
  19.      lev->typ = ALTAR;
  20.      lev->altarmask = induced_align(80);
  21.      priestini(&u.uz, sroom, shrine_spot->x, shrine_spot->y, FALSE);
  22.      lev->altarmask |= AM_SHRINE;
  23.      level.flags.has_temple = 1;
  24.  }
  25.  

nexttodoor

  1.  boolean
  2.  nexttodoor(sx, sy)
  3.  register int sx, sy;
  4.  {
  5.      register int dx, dy;
  6.      register struct rm *lev;
  7.  
  8.      for (dx = -1; dx <= 1; dx++)
  9.          for (dy = -1; dy <= 1; dy++) {
  10.              if (!isok(sx + dx, sy + dy))
  11.                  continue;
  12.              lev = &levl[sx + dx][sy + dy];
  13.              if (IS_DOOR(lev->typ) || lev->typ == SDOOR)
  14.                  return TRUE;
  15.          }
  16.      return FALSE;
  17.  }
  18.  

has_dnstairs

  1.  boolean
  2.  has_dnstairs(sroom)
  3.  register struct mkroom *sroom;
  4.  {
  5.      if (sroom == dnstairs_room)
  6.          return TRUE;
  7.      if (sstairs.sx && !sstairs.up)
  8.          return (boolean) (sroom == sstairs_room);
  9.      return FALSE;
  10.  }
  11.  

has_upstairs

  1.  boolean
  2.  has_upstairs(sroom)
  3.  register struct mkroom *sroom;
  4.  {
  5.      if (sroom == upstairs_room)
  6.          return TRUE;
  7.      if (sstairs.sx && sstairs.up)
  8.          return (boolean) (sroom == sstairs_room);
  9.      return FALSE;
  10.  }
  11.  

somex

  1.  int
  2.  somex(croom)
  3.  register struct mkroom *croom;
  4.  {
  5.      return rn1(croom->hx - croom->lx + 1, croom->lx);
  6.  }
  7.  

somey

  1.  int
  2.  somey(croom)
  3.  register struct mkroom *croom;
  4.  {
  5.      return rn1(croom->hy - croom->ly + 1, croom->ly);
  6.  }
  7.  

inside_room

  1.  boolean
  2.  inside_room(croom, x, y)
  3.  struct mkroom *croom;
  4.  xchar x, y;
  5.  {
  6.      return (boolean) (x >= croom->lx - 1 && x <= croom->hx + 1
  7.                        && y >= croom->ly - 1 && y <= croom->hy + 1);
  8.  }
  9.  

somexy

  1.  boolean
  2.  somexy(croom, c)
  3.  struct mkroom *croom;
  4.  coord *c;
  5.  {
  6.      int try_cnt = 0;
  7.      int i;
  8.  
  9.      if (croom->irregular) {
  10.          i = (int) ((croom - rooms) + ROOMOFFSET);
  11.  
  12.          while (try_cnt++ < 100) {
  13.              c->x = somex(croom);
  14.              c->y = somey(croom);
  15.              if (!levl[c->x][c->y].edge && (int) levl[c->x][c->y].roomno == i)
  16.                  return TRUE;
  17.          }
  18.          /* try harder; exhaustively search until one is found */
  19.          for (c->x = croom->lx; c->x <= croom->hx; c->x++)
  20.              for (c->y = croom->ly; c->y <= croom->hy; c->y++)
  21.                  if (!levl[c->x][c->y].edge
  22.                      && (int) levl[c->x][c->y].roomno == i)
  23.                      return TRUE;
  24.          return FALSE;
  25.      }
  26.  
  27.      if (!croom->nsubrooms) {
  28.          c->x = somex(croom);
  29.          c->y = somey(croom);
  30.          return TRUE;
  31.      }
  32.  
  33.      /* Check that coords doesn't fall into a subroom or into a wall */
  34.  
  35.      while (try_cnt++ < 100) {
  36.          c->x = somex(croom);
  37.          c->y = somey(croom);
  38.          if (IS_WALL(levl[c->x][c->y].typ))
  39.              continue;
  40.          for (i = 0; i < croom->nsubrooms; i++)
  41.              if (inside_room(croom->sbrooms[i], c->x, c->y))
  42.                  goto you_lose;
  43.          break;
  44.      you_lose:
  45.          ;
  46.      }
  47.      if (try_cnt >= 100)
  48.          return FALSE;
  49.      return TRUE;
  50.  }
  51.  

search_special

  1.  /*
  2.   * Search for a special room given its type (zoo, court, etc...)
  3.   *	Special values :
  4.   *		- ANY_SHOP
  5.   *		- ANY_TYPE
  6.   */
  7.  struct mkroom *
  8.  search_special(type)
  9.  schar type;
  10.  {
  11.      register struct mkroom *croom;
  12.  
  13.      for (croom = &rooms[0]; croom->hx >= 0; croom++)
  14.          if ((type == ANY_TYPE && croom->rtype != OROOM)
  15.              || (type == ANY_SHOP && croom->rtype >= SHOPBASE)
  16.              || croom->rtype == type)
  17.              return croom;
  18.      for (croom = &subrooms[0]; croom->hx >= 0; croom++)
  19.          if ((type == ANY_TYPE && croom->rtype != OROOM)
  20.              || (type == ANY_SHOP && croom->rtype >= SHOPBASE)
  21.              || croom->rtype == type)
  22.              return croom;
  23.      return (struct mkroom *) 0;
  24.  }
  25.  

courmon

  1.  struct permonst *
  2.  courtmon()
  3.  {
  4.      int i = rn2(60) + rn2(3 * level_difficulty());
  5.  
  6.      if (i > 100)
  7.          return mkclass(S_DRAGON, 0);
  8.      else if (i > 95)
  9.          return mkclass(S_GIANT, 0);
  10.      else if (i > 85)
  11.          return mkclass(S_TROLL, 0);
  12.      else if (i > 75)
  13.          return mkclass(S_CENTAUR, 0);
  14.      else if (i > 60)
  15.          return mkclass(S_ORC, 0);
  16.      else if (i > 45)
  17.          return &mons[PM_BUGBEAR];
  18.      else if (i > 30)
  19.          return &mons[PM_HOBGOBLIN];
  20.      else if (i > 15)
  21.          return mkclass(S_GNOME, 0);
  22.      else
  23.          return mkclass(S_KOBOLD, 0);
  24.  }
  25.  

squadmon

  1.  #define NSTYPES (PM_CAPTAIN - PM_SOLDIER + 1)
  2.  
  3.  static struct {
  4.      unsigned pm;
  5.      unsigned prob;
  6.  } squadprob[NSTYPES] = { { PM_SOLDIER, 80 },
  7.                           { PM_SERGEANT, 15 },
  8.                           { PM_LIEUTENANT, 4 },
  9.                           { PM_CAPTAIN, 1 } };
  10.  
  11.  /* return soldier types. */
  12.  STATIC_OVL struct permonst *
  13.  squadmon()
  14.  {
  15.      int sel_prob, i, cpro, mndx;
  16.  
  17.      sel_prob = rnd(80 + level_difficulty());
  18.  
  19.      cpro = 0;
  20.      for (i = 0; i < NSTYPES; i++) {
  21.          cpro += squadprob[i].prob;
  22.          if (cpro > sel_prob) {
  23.              mndx = squadprob[i].pm;
  24.              goto gotone;
  25.          }
  26.      }
  27.      mndx = squadprob[rn2(NSTYPES)].pm;
  28.  gotone:
  29.      if (!(mvitals[mndx].mvflags & G_GONE))
  30.          return &mons[mndx];
  31.      else
  32.          return (struct permonst *) 0;
  33.  }
  34.  

save_room

  1.  /*
  2.   * save_room : A recursive function that saves a room and its subrooms
  3.   * (if any).
  4.   */
  5.  STATIC_OVL void
  6.  save_room(fd, r)
  7.  int fd;
  8.  struct mkroom *r;
  9.  {
  10.      short i;
  11.  
  12.      /*
  13.       * Well, I really should write only useful information instead
  14.       * of writing the whole structure. That is I should not write
  15.       * the subrooms pointers, but who cares ?
  16.       */
  17.      bwrite(fd, (genericptr_t) r, sizeof (struct mkroom));
  18.      for (i = 0; i < r->nsubrooms; i++)
  19.          save_room(fd, r->sbrooms[i]);
  20.  }
  21.  

save_rooms

  1.  /*
  2.   * save_rooms : Save all the rooms on disk!
  3.   */
  4.  void
  5.  save_rooms(fd)
  6.  int fd;
  7.  {
  8.      short i;
  9.  
  10.      /* First, write the number of rooms */
  11.      bwrite(fd, (genericptr_t) &nroom, sizeof(nroom));
  12.      for (i = 0; i < nroom; i++)
  13.          save_room(fd, &rooms[i]);
  14.  }
  15.  

rest_room

  1.  STATIC_OVL void
  2.  rest_room(fd, r)
  3.  int fd;
  4.  struct mkroom *r;
  5.  {
  6.      short i;
  7.  
  8.      mread(fd, (genericptr_t) r, sizeof(struct mkroom));
  9.      for (i = 0; i < r->nsubrooms; i++) {
  10.          r->sbrooms[i] = &subrooms[nsubroom];
  11.          rest_room(fd, &subrooms[nsubroom]);
  12.          subrooms[nsubroom++].resident = (struct monst *) 0;
  13.      }
  14.  }
  15.  

rest_rooms

  1.  /*
  2.   * rest_rooms : That's for restoring rooms. Read the rooms structure from
  3.   * the disk.
  4.   */
  5.  void
  6.  rest_rooms(fd)
  7.  int fd;
  8.  {
  9.      short i;
  10.  
  11.      mread(fd, (genericptr_t) &nroom, sizeof(nroom));
  12.      nsubroom = 0;
  13.      for (i = 0; i < nroom; i++) {
  14.          rest_room(fd, &rooms[i]);
  15.          rooms[i].resident = (struct monst *) 0;
  16.      }
  17.      rooms[nroom].hx = -1; /* restore ending flags */
  18.      subrooms[nsubroom].hx = -1;
  19.  }
  20.  

cmap_to_type

  1.  /* convert a display symbol for terrain into topology type;
  2.     used for remembered terrain when mimics pose as furniture */
  3.  int
  4.  cmap_to_type(sym)
  5.  int sym;
  6.  {
  7.      int typ = STONE; /* catchall */
  8.  
  9.      switch (sym) {
  10.      case S_stone:
  11.          typ = STONE;
  12.          break;
  13.      case S_vwall:
  14.          typ = VWALL;
  15.          break;
  16.      case S_hwall:
  17.          typ = HWALL;
  18.          break;
  19.      case S_tlcorn:
  20.          typ = TLCORNER;
  21.          break;
  22.      case S_trcorn:
  23.          typ = TRCORNER;
  24.          break;
  25.      case S_blcorn:
  26.          typ = BLCORNER;
  27.          break;
  28.      case S_brcorn:
  29.          typ = BRCORNER;
  30.          break;
  31.      case S_crwall:
  32.          typ = CROSSWALL;
  33.          break;
  34.      case S_tuwall:
  35.          typ = TUWALL;
  36.          break;
  37.      case S_tdwall:
  38.          typ = TDWALL;
  39.          break;
  40.      case S_tlwall:
  41.          typ = TLWALL;
  42.          break;
  43.      case S_trwall:
  44.          typ = TRWALL;
  45.          break;
  46.      case S_ndoor:  /* no door (empty doorway) */
  47.      case S_vodoor: /* open door in vertical wall */
  48.      case S_hodoor: /* open door in horizontal wall */
  49.      case S_vcdoor: /* closed door in vertical wall */
  50.      case S_hcdoor:
  51.          typ = DOOR;
  52.          break;
  53.      case S_bars:
  54.          typ = IRONBARS;
  55.          break;
  56.      case S_tree:
  57.          typ = TREE;
  58.          break;
  59.      case S_room:
  60.          typ = ROOM;
  61.          break;
  62.      case S_corr:
  63.      case S_litcorr:
  64.          typ = CORR;
  65.          break;
  66.      case S_upstair:
  67.      case S_dnstair:
  68.          typ = STAIRS;
  69.          break;
  70.      case S_upladder:
  71.      case S_dnladder:
  72.          typ = LADDER;
  73.          break;
  74.      case S_altar:
  75.          typ = ALTAR;
  76.          break;
  77.      case S_grave:
  78.          typ = GRAVE;
  79.          break;
  80.      case S_throne:
  81.          typ = THRONE;
  82.          break;
  83.      case S_sink:
  84.          typ = SINK;
  85.          break;
  86.      case S_fountain:
  87.          typ = FOUNTAIN;
  88.          break;
  89.      case S_pool:
  90.          typ = POOL;
  91.          break;
  92.      case S_ice:
  93.          typ = ICE;
  94.          break;
  95.      case S_lava:
  96.          typ = LAVAPOOL;
  97.          break;
  98.      case S_vodbridge: /* open drawbridge spanning north/south */
  99.      case S_hodbridge:
  100.          typ = DRAWBRIDGE_DOWN;
  101.          break;        /* east/west */
  102.      case S_vcdbridge: /* closed drawbridge in vertical wall */
  103.      case S_hcdbridge:
  104.          typ = DBWALL;
  105.          break;
  106.      case S_air:
  107.          typ = AIR;
  108.          break;
  109.      case S_cloud:
  110.          typ = CLOUD;
  111.          break;
  112.      case S_water:
  113.          typ = WATER;
  114.          break;
  115.      default:
  116.          break; /* not a cmap symbol? */
  117.      }
  118.      return typ;
  119.  }
  120.  
  121.  /*mkroom.c*/