Source:NetHack 3.6.0/src/lock.c

From NetHackWiki
(Redirected from Source:NetHack 3.6.0/lock.c)
Jump to: navigation, search

Below is the full text to lock.c from the source code of NetHack 3.6.0. To link to a particular line, write [[Source:NetHack 3.6.0/src/lock.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	lock.c	$NHDT-Date: 1446955300 2015/11/08 04:01:40 $  $NHDT-Branch: master $:$NHDT-Revision: 1.67 $ */
  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.  STATIC_PTR int NDECL(picklock);
  8.  STATIC_PTR int NDECL(forcelock);
  9.  
  10.  /* at most one of `door' and `box' should be non-null at any given time */
  11.  STATIC_VAR NEARDATA struct xlock_s {
  12.      struct rm *door;
  13.      struct obj *box;
  14.      int picktyp, /* key|pick|card for unlock, sharp vs blunt for #force */
  15.          chance, usedtime;
  16.  } xlock;
  17.  
  18.  STATIC_DCL const char *NDECL(lock_action);
  19.  STATIC_DCL boolean FDECL(obstructed, (int, int, BOOLEAN_P));
  20.  STATIC_DCL void FDECL(chest_shatter_msg, (struct obj *));
  21.  

picking_lock

  1.  boolean
  2.  picking_lock(x, y)
  3.  int *x, *y;
  4.  {
  5.      if (occupation == picklock) {
  6.          *x = u.ux + u.dx;
  7.          *y = u.uy + u.dy;
  8.          return TRUE;
  9.      } else {
  10.          *x = *y = 0;
  11.          return FALSE;
  12.      }
  13.  }
  14.  

picking_at

  1.  boolean
  2.  picking_at(x, y)
  3.  int x, y;
  4.  {
  5.      return (boolean) (occupation == picklock && xlock.door == &levl[x][y]);
  6.  }
  7.  

lock_action

  1.  /* produce an occupation string appropriate for the current activity */
  2.  STATIC_OVL const char *
  3.  lock_action()
  4.  {
  5.      /* "unlocking"+2 == "locking" */
  6.      static const char *actions[] = {
  7.          "unlocking the door",   /* [0] */
  8.          "unlocking the chest",  /* [1] */
  9.          "unlocking the box",    /* [2] */
  10.          "picking the lock"      /* [3] */
  11.      };
  12.  
  13.      /* if the target is currently unlocked, we're trying to lock it now */
  14.      if (xlock.door && !(xlock.door->doormask & D_LOCKED))
  15.          return actions[0] + 2; /* "locking the door" */
  16.      else if (xlock.box && !xlock.box->olocked)
  17.          return xlock.box->otyp == CHEST ? actions[1] + 2 : actions[2] + 2;
  18.      /* otherwise we're trying to unlock it */
  19.      else if (xlock.picktyp == LOCK_PICK)
  20.          return actions[3]; /* "picking the lock" */
  21.      else if (xlock.picktyp == CREDIT_CARD)
  22.          return actions[3]; /* same as lock_pick */
  23.      else if (xlock.door)
  24.          return actions[0]; /* "unlocking the door" */
  25.      else if (xlock.box)
  26.          return xlock.box->otyp == CHEST ? actions[1] : actions[2];
  27.      else
  28.          return actions[3];
  29.  }
  30.  

picklock

  1.  /* try to open/close a lock */
  2.  STATIC_PTR int
  3.  picklock(VOID_ARGS)
  4.  {
  5.      if (xlock.box) {
  6.          if ((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy)) {
  7.              return ((xlock.usedtime = 0)); /* you or it moved */
  8.          }
  9.      } else { /* door */
  10.          if (xlock.door != &(levl[u.ux + u.dx][u.uy + u.dy])) {
  11.              return ((xlock.usedtime = 0)); /* you moved */
  12.          }
  13.          switch (xlock.door->doormask) {
  14.          case D_NODOOR:
  15.              pline("This doorway has no door.");
  16.              return ((xlock.usedtime = 0));
  17.          case D_ISOPEN:
  18.              You("cannot lock an open door.");
  19.              return ((xlock.usedtime = 0));
  20.          case D_BROKEN:
  21.              pline("This door is broken.");
  22.              return ((xlock.usedtime = 0));
  23.          }
  24.      }
  25.  
  26.      if (xlock.usedtime++ >= 50 || nohands(youmonst.data)) {
  27.          You("give up your attempt at %s.", lock_action());
  28.          exercise(A_DEX, TRUE); /* even if you don't succeed */
  29.          return ((xlock.usedtime = 0));
  30.      }
  31.  
  32.      if (rn2(100) >= xlock.chance)
  33.          return 1; /* still busy */
  34.  
  35.      You("succeed in %s.", lock_action());
  36.      if (xlock.door) {
  37.          if (xlock.door->doormask & D_TRAPPED) {
  38.              b_trapped("door", FINGER);
  39.              xlock.door->doormask = D_NODOOR;
  40.              unblock_point(u.ux + u.dx, u.uy + u.dy);
  41.              if (*in_rooms(u.ux + u.dx, u.uy + u.dy, SHOPBASE))
  42.                  add_damage(u.ux + u.dx, u.uy + u.dy, 0L);
  43.              newsym(u.ux + u.dx, u.uy + u.dy);
  44.          } else if (xlock.door->doormask & D_LOCKED)
  45.              xlock.door->doormask = D_CLOSED;
  46.          else
  47.              xlock.door->doormask = D_LOCKED;
  48.      } else {
  49.          xlock.box->olocked = !xlock.box->olocked;
  50.          xlock.box->lknown = 1;
  51.          if (xlock.box->otrapped)
  52.              (void) chest_trap(xlock.box, FINGER, FALSE);
  53.      }
  54.      exercise(A_DEX, TRUE);
  55.      return ((xlock.usedtime = 0));
  56.  }
  57.  

breakchestlock

  1.  void
  2.  breakchestlock(box, destroyit)
  3.  struct obj *box;
  4.  boolean destroyit;
  5.  {
  6.      if (!destroyit) { /* bill for the box but not for its contents */
  7.          struct obj *hide_contents = box->cobj;
  8.  
  9.          box->cobj = 0;
  10.          costly_alteration(box, COST_BRKLCK);
  11.          box->cobj = hide_contents;
  12.          box->olocked = 0;
  13.          box->obroken = 1;
  14.          box->lknown = 1;
  15.      } else { /* #force has destroyed this box (at <u.ux,u.uy>) */
  16.          struct obj *otmp;
  17.          struct monst *shkp = (*u.ushops && costly_spot(u.ux, u.uy))
  18.                                   ? shop_keeper(*u.ushops)
  19.                                   : 0;
  20.          boolean costly = (boolean) (shkp != 0),
  21.                  peaceful_shk = costly && (boolean) shkp->mpeaceful;
  22.          long loss = 0L;
  23.  
  24.          pline("In fact, you've totally destroyed %s.", the(xname(box)));
  25.          /* Put the contents on ground at the hero's feet. */
  26.          while ((otmp = box->cobj) != 0) {
  27.              obj_extract_self(otmp);
  28.              if (!rn2(3) || otmp->oclass == POTION_CLASS) {
  29.                  chest_shatter_msg(otmp);
  30.                  if (costly)
  31.                      loss +=
  32.                          stolen_value(otmp, u.ux, u.uy, peaceful_shk, TRUE);
  33.                  if (otmp->quan == 1L) {
  34.                      obfree(otmp, (struct obj *) 0);
  35.                      continue;
  36.                  }
  37.                  useup(otmp);
  38.              }
  39.              if (box->otyp == ICE_BOX && otmp->otyp == CORPSE) {
  40.                  otmp->age = monstermoves - otmp->age; /* actual age */
  41.                  start_corpse_timeout(otmp);
  42.              }
  43.              place_object(otmp, u.ux, u.uy);
  44.              stackobj(otmp);
  45.          }
  46.          if (costly)
  47.              loss += stolen_value(box, u.ux, u.uy, peaceful_shk, TRUE);
  48.          if (loss)
  49.              You("owe %ld %s for objects destroyed.", loss, currency(loss));
  50.          delobj(box);
  51.      }
  52.  }
  53.  

forcelock

  1.  /* try to force a locked chest */
  2.  STATIC_PTR int
  3.  forcelock(VOID_ARGS)
  4.  {
  5.      if ((xlock.box->ox != u.ux) || (xlock.box->oy != u.uy))
  6.          return ((xlock.usedtime = 0)); /* you or it moved */
  7.  
  8.      if (xlock.usedtime++ >= 50 || !uwep || nohands(youmonst.data)) {
  9.          You("give up your attempt to force the lock.");
  10.          if (xlock.usedtime >= 50) /* you made the effort */
  11.              exercise((xlock.picktyp) ? A_DEX : A_STR, TRUE);
  12.          return ((xlock.usedtime = 0));
  13.      }
  14.  
  15.      if (xlock.picktyp) { /* blade */
  16.          if (rn2(1000 - (int) uwep->spe) > (992 - greatest_erosion(uwep) * 10)
  17.              && !uwep->cursed && !obj_resists(uwep, 0, 99)) {
  18.              /* for a +0 weapon, probability that it survives an unsuccessful
  19.               * attempt to force the lock is (.992)^50 = .67
  20.               */
  21.              pline("%sour %s broke!", (uwep->quan > 1L) ? "One of y" : "Y",
  22.                    xname(uwep));
  23.              useup(uwep);
  24.              You("give up your attempt to force the lock.");
  25.              exercise(A_DEX, TRUE);
  26.              return ((xlock.usedtime = 0));
  27.          }
  28.      } else             /* blunt */
  29.          wake_nearby(); /* due to hammering on the container */
  30.  
  31.      if (rn2(100) >= xlock.chance)
  32.          return 1; /* still busy */
  33.  
  34.      You("succeed in forcing the lock.");
  35.      breakchestlock(xlock.box, (boolean) (!xlock.picktyp && !rn2(3)));
  36.  
  37.      exercise((xlock.picktyp) ? A_DEX : A_STR, TRUE);
  38.      return ((xlock.usedtime = 0));
  39.  }
  40.  

reset_pick

  1.  void
  2.  reset_pick()
  3.  {
  4.      xlock.usedtime = xlock.chance = xlock.picktyp = 0;
  5.      xlock.door = 0;
  6.      xlock.box = 0;
  7.  }
  8.  

pick_lock

  1.  /* for doapply(); if player gives a direction or resumes an interrupted
  2.     previous attempt then it costs hero a move even if nothing ultimately
  3.     happens; when told "can't do that" before being asked for direction
  4.     or player cancels with ESC while giving direction, it doesn't */
  5.  #define PICKLOCK_LEARNED_SOMETHING (-1) /* time passes */
  6.  #define PICKLOCK_DID_NOTHING 0          /* no time passes */
  7.  #define PICKLOCK_DID_SOMETHING 1
  8.  
  9.  /* player is applying a key, lock pick, or credit card */
  10.  int
  11.  pick_lock(pick)
  12.  struct obj *pick;
  13.  {
  14.      int picktyp, c, ch;
  15.      coord cc;
  16.      struct rm *door;
  17.      struct obj *otmp;
  18.      char qbuf[QBUFSZ];
  19.  
  20.      picktyp = pick->otyp;
  21.  
  22.      /* check whether we're resuming an interrupted previous attempt */
  23.      if (xlock.usedtime && picktyp == xlock.picktyp) {
  24.          static char no_longer[] = "Unfortunately, you can no longer %s %s.";
  25.  
  26.          if (nohands(youmonst.data)) {
  27.              const char *what = (picktyp == LOCK_PICK) ? "pick" : "key";
  28.              if (picktyp == CREDIT_CARD)
  29.                  what = "card";
  30.              pline(no_longer, "hold the", what);
  31.              reset_pick();
  32.              return PICKLOCK_LEARNED_SOMETHING;
  33.          } else if (u.uswallow || (xlock.box && !can_reach_floor(TRUE))) {
  34.              pline(no_longer, "reach the", "lock");
  35.              reset_pick();
  36.              return PICKLOCK_LEARNED_SOMETHING;
  37.          } else {
  38.              const char *action = lock_action();
  39.  
  40.              You("resume your attempt at %s.", action);
  41.              set_occupation(picklock, action, 0);
  42.              return PICKLOCK_DID_SOMETHING;
  43.          }
  44.      }
  45.  
  46.      if (nohands(youmonst.data)) {
  47.          You_cant("hold %s -- you have no hands!", doname(pick));
  48.          return PICKLOCK_DID_NOTHING;
  49.      } else if (u.uswallow) {
  50.          You_cant("%sunlock %s.", (picktyp == CREDIT_CARD) ? "" : "lock or ",
  51.                   mon_nam(u.ustuck));
  52.          return PICKLOCK_DID_NOTHING;
  53.      }
  54.  
  55.      if ((picktyp != LOCK_PICK && picktyp != CREDIT_CARD
  56.           && picktyp != SKELETON_KEY)) {
  57.          impossible("picking lock with object %d?", picktyp);
  58.          return PICKLOCK_DID_NOTHING;
  59.      }
  60.      ch = 0; /* lint suppression */
  61.  
  62.      if (!get_adjacent_loc((char *) 0, "Invalid location!", u.ux, u.uy, &cc))
  63.          return PICKLOCK_DID_NOTHING;
  64.  
  65.      if (cc.x == u.ux && cc.y == u.uy) { /* pick lock on a container */
  66.          const char *verb;
  67.          char qsfx[QBUFSZ];
  68.          boolean it;
  69.          int count;
  70.  
  71.          if (u.dz < 0) {
  72.              There("isn't any sort of lock up %s.",
  73.                    Levitation ? "here" : "there");
  74.              return PICKLOCK_LEARNED_SOMETHING;
  75.          } else if (is_lava(u.ux, u.uy)) {
  76.              pline("Doing that would probably melt %s.", yname(pick));
  77.              return PICKLOCK_LEARNED_SOMETHING;
  78.          } else if (is_pool(u.ux, u.uy) && !Underwater) {
  79.              pline_The("water has no lock.");
  80.              return PICKLOCK_LEARNED_SOMETHING;
  81.          }
  82.  
  83.          count = 0;
  84.          c = 'n'; /* in case there are no boxes here */
  85.          for (otmp = level.objects[cc.x][cc.y]; otmp; otmp = otmp->nexthere)
  86.              if (Is_box(otmp)) {
  87.                  ++count;
  88.                  if (!can_reach_floor(TRUE)) {
  89.                      You_cant("reach %s from up here.", the(xname(otmp)));
  90.                      return PICKLOCK_LEARNED_SOMETHING;
  91.                  }
  92.                  it = 0;
  93.                  if (otmp->obroken)
  94.                      verb = "fix";
  95.                  else if (!otmp->olocked)
  96.                      verb = "lock", it = 1;
  97.                  else if (picktyp != LOCK_PICK)
  98.                      verb = "unlock", it = 1;
  99.                  else
  100.                      verb = "pick";
  101.  
  102.                  /* "There is <a box> here; <verb> <it|its lock>?" */
  103.                  Sprintf(qsfx, " here; %s %s?", verb, it ? "it" : "its lock");
  104.                  (void) safe_qbuf(qbuf, "There is ", qsfx, otmp, doname,
  105.                                   ansimpleoname, "a box");
  106.                  otmp->lknown = 1;
  107.  
  108.                  c = ynq(qbuf);
  109.                  if (c == 'q')
  110.                      return 0;
  111.                  if (c == 'n')
  112.                      continue;
  113.  
  114.                  if (otmp->obroken) {
  115.                      You_cant("fix its broken lock with %s.", doname(pick));
  116.                      return PICKLOCK_LEARNED_SOMETHING;
  117.                  } else if (picktyp == CREDIT_CARD && !otmp->olocked) {
  118.                      /* credit cards are only good for unlocking */
  119.                      You_cant("do that with %s.",
  120.                               an(simple_typename(picktyp)));
  121.                      return PICKLOCK_LEARNED_SOMETHING;
  122.                  }
  123.                  switch (picktyp) {
  124.                  case CREDIT_CARD:
  125.                      ch = ACURR(A_DEX) + 20 * Role_if(PM_ROGUE);
  126.                      break;
  127.                  case LOCK_PICK:
  128.                      ch = 4 * ACURR(A_DEX) + 25 * Role_if(PM_ROGUE);
  129.                      break;
  130.                  case SKELETON_KEY:
  131.                      ch = 75 + ACURR(A_DEX);
  132.                      break;
  133.                  default:
  134.                      ch = 0;
  135.                  }
  136.                  if (otmp->cursed)
  137.                      ch /= 2;
  138.  
  139.                  xlock.picktyp = picktyp;
  140.                  xlock.box = otmp;
  141.                  xlock.door = 0;
  142.                  break;
  143.              }
  144.          if (c != 'y') {
  145.              if (!count)
  146.                  There("doesn't seem to be any sort of lock here.");
  147.              return PICKLOCK_LEARNED_SOMETHING; /* decided against all boxes */
  148.          }
  149.      } else { /* pick the lock in a door */
  150.          struct monst *mtmp;
  151.  
  152.          if (u.utrap && u.utraptype == TT_PIT) {
  153.              You_cant("reach over the edge of the pit.");
  154.              return PICKLOCK_LEARNED_SOMETHING;
  155.          }
  156.  
  157.          door = &levl[cc.x][cc.y];
  158.          mtmp = m_at(cc.x, cc.y);
  159.          if (mtmp && canseemon(mtmp) && mtmp->m_ap_type != M_AP_FURNITURE
  160.              && mtmp->m_ap_type != M_AP_OBJECT) {
  161.              if (picktyp == CREDIT_CARD
  162.                  && (mtmp->isshk || mtmp->data == &mons[PM_ORACLE]))
  163.                  verbalize("No checks, no credit, no problem.");
  164.              else
  165.                  pline("I don't think %s would appreciate that.",
  166.                        mon_nam(mtmp));
  167.              return PICKLOCK_LEARNED_SOMETHING;
  168.          } else if (mtmp && is_door_mappear(mtmp)) {
  169.              /* "The door actually was a <mimic>!" */
  170.              stumble_onto_mimic(mtmp);
  171.              /* mimic might keep the key (50% chance, 10% for PYEC) */
  172.              maybe_absorb_item(mtmp, pick, 50, 10);
  173.              return PICKLOCK_LEARNED_SOMETHING;
  174.          }
  175.          if (!IS_DOOR(door->typ)) {
  176.              if (is_drawbridge_wall(cc.x, cc.y) >= 0)
  177.                  You("%s no lock on the drawbridge.", Blind ? "feel" : "see");
  178.              else
  179.                  You("%s no door there.", Blind ? "feel" : "see");
  180.              return PICKLOCK_LEARNED_SOMETHING;
  181.          }
  182.          switch (door->doormask) {
  183.          case D_NODOOR:
  184.              pline("This doorway has no door.");
  185.              return PICKLOCK_LEARNED_SOMETHING;
  186.          case D_ISOPEN:
  187.              You("cannot lock an open door.");
  188.              return PICKLOCK_LEARNED_SOMETHING;
  189.          case D_BROKEN:
  190.              pline("This door is broken.");
  191.              return PICKLOCK_LEARNED_SOMETHING;
  192.          default:
  193.              /* credit cards are only good for unlocking */
  194.              if (picktyp == CREDIT_CARD && !(door->doormask & D_LOCKED)) {
  195.                  You_cant("lock a door with a credit card.");
  196.                  return PICKLOCK_LEARNED_SOMETHING;
  197.              }
  198.  
  199.              Sprintf(qbuf, "%s it?",
  200.                      (door->doormask & D_LOCKED) ? "Unlock" : "Lock");
  201.  
  202.              c = yn(qbuf);
  203.              if (c == 'n')
  204.                  return 0;
  205.  
  206.              switch (picktyp) {
  207.              case CREDIT_CARD:
  208.                  ch = 2 * ACURR(A_DEX) + 20 * Role_if(PM_ROGUE);
  209.                  break;
  210.              case LOCK_PICK:
  211.                  ch = 3 * ACURR(A_DEX) + 30 * Role_if(PM_ROGUE);
  212.                  break;
  213.              case SKELETON_KEY:
  214.                  ch = 70 + ACURR(A_DEX);
  215.                  break;
  216.              default:
  217.                  ch = 0;
  218.              }
  219.              xlock.door = door;
  220.              xlock.box = 0;
  221.          }
  222.      }
  223.      context.move = 0;
  224.      xlock.chance = ch;
  225.      xlock.picktyp = picktyp;
  226.      xlock.usedtime = 0;
  227.      set_occupation(picklock, lock_action(), 0);
  228.      return PICKLOCK_DID_SOMETHING;
  229.  }
  230.  

doforce

  1.  /* try to force a chest with your weapon */
  2.  int
  3.  doforce()
  4.  {
  5.      register struct obj *otmp;
  6.      register int c, picktyp;
  7.      char qbuf[QBUFSZ];
  8.  
  9.      if (u.uswallow) {
  10.          You_cant("force anything from inside here.");
  11.          return 0;
  12.      }
  13.      if (!uwep /* proper type test */
  14.          || ((uwep->oclass == WEAPON_CLASS || is_weptool(uwep))
  15.                 ? (objects[uwep->otyp].oc_skill < P_DAGGER
  16.                    || objects[uwep->otyp].oc_skill == P_FLAIL
  17.                    || objects[uwep->otyp].oc_skill > P_LANCE)
  18.                 : uwep->oclass != ROCK_CLASS)) {
  19.          You_cant("force anything %s weapon.",
  20.                   !uwep ? "when not wielding a"
  21.                         : (uwep->oclass != WEAPON_CLASS && !is_weptool(uwep))
  22.                               ? "without a proper"
  23.                               : "with that");
  24.          return 0;
  25.      }
  26.      if (!can_reach_floor(TRUE)) {
  27.          cant_reach_floor(u.ux, u.uy, FALSE, TRUE);
  28.          return 0;
  29.      }
  30.  
  31.      picktyp = is_blade(uwep) && !is_pick(uwep);
  32.      if (xlock.usedtime && xlock.box && picktyp == xlock.picktyp) {
  33.          You("resume your attempt to force the lock.");
  34.          set_occupation(forcelock, "forcing the lock", 0);
  35.          return 1;
  36.      }
  37.  
  38.      /* A lock is made only for the honest man, the thief will break it. */
  39.      xlock.box = (struct obj *) 0;
  40.      for (otmp = level.objects[u.ux][u.uy]; otmp; otmp = otmp->nexthere)
  41.          if (Is_box(otmp)) {
  42.              if (otmp->obroken || !otmp->olocked) {
  43.                  There("is %s here, but its lock is already %s.", doname(otmp),
  44.                        otmp->obroken ? "broken" : "unlocked");
  45.                  otmp->lknown = 1;
  46.                  continue;
  47.              }
  48.              (void) safe_qbuf(qbuf, "There is ", " here; force its lock?",
  49.                               otmp, doname, ansimpleoname, "a box");
  50.              otmp->lknown = 1;
  51.  
  52.              c = ynq(qbuf);
  53.              if (c == 'q')
  54.                  return 0;
  55.              if (c == 'n')
  56.                  continue;
  57.  
  58.              if (picktyp)
  59.                  You("force %s into a crack and pry.", yname(uwep));
  60.              else
  61.                  You("start bashing it with %s.", yname(uwep));
  62.              xlock.box = otmp;
  63.              xlock.chance = objects[uwep->otyp].oc_wldam * 2;
  64.              xlock.picktyp = picktyp;
  65.              xlock.usedtime = 0;
  66.              break;
  67.          }
  68.  
  69.      if (xlock.box)
  70.          set_occupation(forcelock, "forcing the lock", 0);
  71.      else
  72.          You("decide not to force the issue.");
  73.      return 1;
  74.  }
  75.  

stumble_on_door_mimic

  1.  boolean
  2.  stumble_on_door_mimic(x, y)
  3.  int x, y;
  4.  {
  5.      struct monst *mtmp;
  6.  
  7.      if ((mtmp = m_at(x, y)) && is_door_mappear(mtmp)
  8.          && !Protection_from_shape_changers) {
  9.          stumble_onto_mimic(mtmp);
  10.          return TRUE;
  11.      }
  12.      return FALSE;
  13.  }
  14.  

doopen

  1.  /* the 'O' command - try to open a door */
  2.  int
  3.  doopen()
  4.  {
  5.      return doopen_indir(0, 0);
  6.  }
  7.  

doopen_indir

  1.  /* try to open a door in direction u.dx/u.dy */
  2.  int
  3.  doopen_indir(x, y)
  4.  int x, y;
  5.  {
  6.      coord cc;
  7.      register struct rm *door;
  8.      boolean portcullis;
  9.      int res = 0;
  10.  
  11.      if (nohands(youmonst.data)) {
  12.          You_cant("open anything -- you have no hands!");
  13.          return 0;
  14.      }
  15.  
  16.      if (u.utrap && u.utraptype == TT_PIT) {
  17.          You_cant("reach over the edge of the pit.");
  18.          return 0;
  19.      }
  20.  
  21.      if (x > 0 && y > 0) {
  22.          cc.x = x;
  23.          cc.y = y;
  24.      } else if (!get_adjacent_loc((char *) 0, (char *) 0, u.ux, u.uy, &cc))
  25.          return 0;
  26.  
  27.      if ((cc.x == u.ux) && (cc.y == u.uy))
  28.          return 0;
  29.  
  30.      if (stumble_on_door_mimic(cc.x, cc.y))
  31.          return 1;
  32.  
  33.      /* when choosing a direction is impaired, use a turn
  34.         regardless of whether a door is successfully targetted */
  35.      if (Confusion || Stunned)
  36.          res = 1;
  37.  
  38.      door = &levl[cc.x][cc.y];
  39.      portcullis = (is_drawbridge_wall(cc.x, cc.y) >= 0);
  40.      if (Blind) {
  41.          int oldglyph = door->glyph;
  42.          schar oldlastseentyp = lastseentyp[cc.x][cc.y];
  43.  
  44.          feel_location(cc.x, cc.y);
  45.          if (door->glyph != oldglyph
  46.              || lastseentyp[cc.x][cc.y] != oldlastseentyp)
  47.              res = 1; /* learned something */
  48.      }
  49.  
  50.      if (portcullis || !IS_DOOR(door->typ)) {
  51.          /* closed portcullis or spot that opened bridge would span */
  52.          if (is_db_wall(cc.x, cc.y) || door->typ == DRAWBRIDGE_UP)
  53.              There("is no obvious way to open the drawbridge.");
  54.          else if (portcullis || door->typ == DRAWBRIDGE_DOWN)
  55.              pline_The("drawbridge is already open.");
  56.          else
  57.              You("%s no door there.", Blind ? "feel" : "see");
  58.          return res;
  59.      }
  60.  
  61.      if (!(door->doormask & D_CLOSED)) {
  62.          const char *mesg;
  63.  
  64.          switch (door->doormask) {
  65.          case D_BROKEN:
  66.              mesg = " is broken";
  67.              break;
  68.          case D_NODOOR:
  69.              mesg = "way has no door";
  70.              break;
  71.          case D_ISOPEN:
  72.              mesg = " is already open";
  73.              break;
  74.          default:
  75.              mesg = " is locked";
  76.              break;
  77.          }
  78.          pline("This door%s.", mesg);
  79.          return res;
  80.      }
  81.  
  82.      if (verysmall(youmonst.data)) {
  83.          pline("You're too small to pull the door open.");
  84.          return res;
  85.      }
  86.  
  87.      /* door is known to be CLOSED */
  88.      if (rnl(20) < (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3) {
  89.          pline_The("door opens.");
  90.          if (door->doormask & D_TRAPPED) {
  91.              b_trapped("door", FINGER);
  92.              door->doormask = D_NODOOR;
  93.              if (*in_rooms(cc.x, cc.y, SHOPBASE))
  94.                  add_damage(cc.x, cc.y, 0L);
  95.          } else
  96.              door->doormask = D_ISOPEN;
  97.          feel_newsym(cc.x, cc.y); /* the hero knows she opened it */
  98.          unblock_point(cc.x, cc.y); /* vision: new see through there */
  99.      } else {
  100.          exercise(A_STR, TRUE);
  101.          pline_The("door resists!");
  102.      }
  103.  
  104.      return 1;
  105.  }
  106.  

obstructed

  1.  STATIC_OVL boolean
  2.  obstructed(x, y, quietly)
  3.  register int x, y;
  4.  boolean quietly;
  5.  {
  6.      register struct monst *mtmp = m_at(x, y);
  7.  
  8.      if (mtmp && mtmp->m_ap_type != M_AP_FURNITURE) {
  9.          if (mtmp->m_ap_type == M_AP_OBJECT)
  10.              goto objhere;
  11.          if (!quietly) {
  12.              if ((mtmp->mx != x) || (mtmp->my != y)) {
  13.                  /* worm tail */
  14.                  pline("%s%s blocks the way!",
  15.                        !canspotmon(mtmp) ? Something : s_suffix(Monnam(mtmp)),
  16.                        !canspotmon(mtmp) ? "" : " tail");
  17.              } else {
  18.                  pline("%s blocks the way!",
  19.                        !canspotmon(mtmp) ? "Some creature" : Monnam(mtmp));
  20.              }
  21.          }
  22.          if (!canspotmon(mtmp))
  23.              map_invisible(x, y);
  24.          return TRUE;
  25.      }
  26.      if (OBJ_AT(x, y)) {
  27.      objhere:
  28.          if (!quietly)
  29.              pline("%s's in the way.", Something);
  30.          return TRUE;
  31.      }
  32.      return FALSE;
  33.  }
  34.  

doclose

  1.  /* the 'C' command - try to close a door */
  2.  int
  3.  doclose()
  4.  {
  5.      register int x, y;
  6.      register struct rm *door;
  7.      boolean portcullis;
  8.      int res = 0;
  9.  
  10.      if (nohands(youmonst.data)) {
  11.          You_cant("close anything -- you have no hands!");
  12.          return 0;
  13.      }
  14.  
  15.      if (u.utrap && u.utraptype == TT_PIT) {
  16.          You_cant("reach over the edge of the pit.");
  17.          return 0;
  18.      }
  19.  
  20.      if (!getdir((char *) 0))
  21.          return 0;
  22.  
  23.      x = u.ux + u.dx;
  24.      y = u.uy + u.dy;
  25.      if ((x == u.ux) && (y == u.uy)) {
  26.          You("are in the way!");
  27.          return 1;
  28.      }
  29.  
  30.      if (!isok(x, y))
  31.          goto nodoor;
  32.  
  33.      if (stumble_on_door_mimic(x, y))
  34.          return 1;
  35.  
  36.      /* when choosing a direction is impaired, use a turn
  37.         regardless of whether a door is successfully targetted */
  38.      if (Confusion || Stunned)
  39.          res = 1;
  40.  
  41.      door = &levl[x][y];
  42.      portcullis = (is_drawbridge_wall(x, y) >= 0);
  43.      if (Blind) {
  44.          int oldglyph = door->glyph;
  45.          schar oldlastseentyp = lastseentyp[x][y];
  46.  
  47.          feel_location(x, y);
  48.          if (door->glyph != oldglyph || lastseentyp[x][y] != oldlastseentyp)
  49.              res = 1; /* learned something */
  50.      }
  51.  
  52.      if (portcullis || !IS_DOOR(door->typ)) {
  53.          /* is_db_wall: closed portcullis */
  54.          if (is_db_wall(x, y) || door->typ == DRAWBRIDGE_UP)
  55.              pline_The("drawbridge is already closed.");
  56.          else if (portcullis || door->typ == DRAWBRIDGE_DOWN)
  57.              There("is no obvious way to close the drawbridge.");
  58.          else {
  59.          nodoor:
  60.              You("%s no door there.", Blind ? "feel" : "see");
  61.          }
  62.          return res;
  63.      }
  64.  
  65.      if (door->doormask == D_NODOOR) {
  66.          pline("This doorway has no door.");
  67.          return res;
  68.      } else if (obstructed(x, y, FALSE)) {
  69.          return res;
  70.      } else if (door->doormask == D_BROKEN) {
  71.          pline("This door is broken.");
  72.          return res;
  73.      } else if (door->doormask & (D_CLOSED | D_LOCKED)) {
  74.          pline("This door is already closed.");
  75.          return res;
  76.      }
  77.  
  78.      if (door->doormask == D_ISOPEN) {
  79.          if (verysmall(youmonst.data) && !u.usteed) {
  80.              pline("You're too small to push the door closed.");
  81.              return res;
  82.          }
  83.          if (u.usteed
  84.              || rn2(25) < (ACURRSTR + ACURR(A_DEX) + ACURR(A_CON)) / 3) {
  85.              pline_The("door closes.");
  86.              door->doormask = D_CLOSED;
  87.              feel_newsym(x, y); /* the hero knows she closed it */
  88.              block_point(x, y); /* vision:  no longer see there */
  89.          } else {
  90.              exercise(A_STR, TRUE);
  91.              pline_The("door resists!");
  92.          }
  93.      }
  94.  
  95.      return 1;
  96.  }
  97.  

boxlock

  1.  /* box obj was hit with spell or wand effect otmp;
  2.     returns true if something happened */
  3.  boolean
  4.  boxlock(obj, otmp)
  5.  struct obj *obj, *otmp; /* obj *is* a box */
  6.  {
  7.      boolean res = 0;
  8.  
  9.      switch (otmp->otyp) {
  10.      case WAN_LOCKING:
  11.      case SPE_WIZARD_LOCK:
  12.          if (!obj->olocked) { /* lock it; fix if broken */
  13.              pline("Klunk!");
  14.              obj->olocked = 1;
  15.              obj->obroken = 0;
  16.              if (Role_if(PM_WIZARD))
  17.                  obj->lknown = 1;
  18.              else
  19.                  obj->lknown = 0;
  20.              res = 1;
  21.          } /* else already closed and locked */
  22.          break;
  23.      case WAN_OPENING:
  24.      case SPE_KNOCK:
  25.          if (obj->olocked) { /* unlock; couldn't be broken */
  26.              pline("Klick!");
  27.              obj->olocked = 0;
  28.              res = 1;
  29.              if (Role_if(PM_WIZARD))
  30.                  obj->lknown = 1;
  31.              else
  32.                  obj->lknown = 0;
  33.          } else /* silently fix if broken */
  34.              obj->obroken = 0;
  35.          break;
  36.      case WAN_POLYMORPH:
  37.      case SPE_POLYMORPH:
  38.          /* maybe start unlocking chest, get interrupted, then zap it;
  39.             we must avoid any attempt to resume unlocking it */
  40.          if (xlock.box == obj)
  41.              reset_pick();
  42.          break;
  43.      }
  44.      return res;
  45.  }
  46.  

doorlock

  1.  /* Door/secret door was hit with spell or wand effect otmp;
  2.     returns true if something happened */
  3.  boolean
  4.  doorlock(otmp, x, y)
  5.  struct obj *otmp;
  6.  int x, y;
  7.  {
  8.      register struct rm *door = &levl[x][y];
  9.      boolean res = TRUE;
  10.      int loudness = 0;
  11.      const char *msg = (const char *) 0;
  12.      const char *dustcloud = "A cloud of dust";
  13.      const char *quickly_dissipates = "quickly dissipates";
  14.      boolean mysterywand = (otmp->oclass == WAND_CLASS && !otmp->dknown);
  15.  
  16.      if (door->typ == SDOOR) {
  17.          switch (otmp->otyp) {
  18.          case WAN_OPENING:
  19.          case SPE_KNOCK:
  20.          case WAN_STRIKING:
  21.          case SPE_FORCE_BOLT:
  22.              door->typ = DOOR;
  23.              door->doormask = D_CLOSED | (door->doormask & D_TRAPPED);
  24.              newsym(x, y);
  25.              if (cansee(x, y))
  26.                  pline("A door appears in the wall!");
  27.              if (otmp->otyp == WAN_OPENING || otmp->otyp == SPE_KNOCK)
  28.                  return TRUE;
  29.              break; /* striking: continue door handling below */
  30.          case WAN_LOCKING:
  31.          case SPE_WIZARD_LOCK:
  32.          default:
  33.              return FALSE;
  34.          }
  35.      }
  36.  
  37.      switch (otmp->otyp) {
  38.      case WAN_LOCKING:
  39.      case SPE_WIZARD_LOCK:
  40.          if (Is_rogue_level(&u.uz)) {
  41.              boolean vis = cansee(x, y);
  42.              /* Can't have real locking in Rogue, so just hide doorway */
  43.              if (vis)
  44.                  pline("%s springs up in the older, more primitive doorway.",
  45.                        dustcloud);
  46.              else
  47.                  You_hear("a swoosh.");
  48.              if (obstructed(x, y, mysterywand)) {
  49.                  if (vis)
  50.                      pline_The("cloud %s.", quickly_dissipates);
  51.                  return FALSE;
  52.              }
  53.              block_point(x, y);
  54.              door->typ = SDOOR;
  55.              if (vis)
  56.                  pline_The("doorway vanishes!");
  57.              newsym(x, y);
  58.              return TRUE;
  59.          }
  60.          if (obstructed(x, y, mysterywand))
  61.              return FALSE;
  62.          /* Don't allow doors to close over traps.  This is for pits */
  63.          /* & trap doors, but is it ever OK for anything else? */
  64.          if (t_at(x, y)) {
  65.              /* maketrap() clears doormask, so it should be NODOOR */
  66.              pline("%s springs up in the doorway, but %s.", dustcloud,
  67.                    quickly_dissipates);
  68.              return FALSE;
  69.          }
  70.  
  71.          switch (door->doormask & ~D_TRAPPED) {
  72.          case D_CLOSED:
  73.              msg = "The door locks!";
  74.              break;
  75.          case D_ISOPEN:
  76.              msg = "The door swings shut, and locks!";
  77.              break;
  78.          case D_BROKEN:
  79.              msg = "The broken door reassembles and locks!";
  80.              break;
  81.          case D_NODOOR:
  82.              msg =
  83.                 "A cloud of dust springs up and assembles itself into a door!";
  84.              break;
  85.          default:
  86.              res = FALSE;
  87.              break;
  88.          }
  89.          block_point(x, y);
  90.          door->doormask = D_LOCKED | (door->doormask & D_TRAPPED);
  91.          newsym(x, y);
  92.          break;
  93.      case WAN_OPENING:
  94.      case SPE_KNOCK:
  95.          if (door->doormask & D_LOCKED) {
  96.              msg = "The door unlocks!";
  97.              door->doormask = D_CLOSED | (door->doormask & D_TRAPPED);
  98.          } else
  99.              res = FALSE;
  100.          break;
  101.      case WAN_STRIKING:
  102.      case SPE_FORCE_BOLT:
  103.          if (door->doormask & (D_LOCKED | D_CLOSED)) {
  104.              if (door->doormask & D_TRAPPED) {
  105.                  if (MON_AT(x, y))
  106.                      (void) mb_trapped(m_at(x, y));
  107.                  else if (flags.verbose) {
  108.                      if (cansee(x, y))
  109.                          pline("KABOOM!!  You see a door explode.");
  110.                      else
  111.                          You_hear("a distant explosion.");
  112.                  }
  113.                  door->doormask = D_NODOOR;
  114.                  unblock_point(x, y);
  115.                  newsym(x, y);
  116.                  loudness = 40;
  117.                  break;
  118.              }
  119.              door->doormask = D_BROKEN;
  120.              if (flags.verbose) {
  121.                  if (cansee(x, y))
  122.                      pline_The("door crashes open!");
  123.                  else
  124.                      You_hear("a crashing sound.");
  125.              }
  126.              unblock_point(x, y);
  127.              newsym(x, y);
  128.              /* force vision recalc before printing more messages */
  129.              if (vision_full_recalc)
  130.                  vision_recalc(0);
  131.              loudness = 20;
  132.          } else
  133.              res = FALSE;
  134.          break;
  135.      default:
  136.          impossible("magic (%d) attempted on door.", otmp->otyp);
  137.          break;
  138.      }
  139.      if (msg && cansee(x, y))
  140.          pline1(msg);
  141.      if (loudness > 0) {
  142.          /* door was destroyed */
  143.          wake_nearto(x, y, loudness);
  144.          if (*in_rooms(x, y, SHOPBASE))
  145.              add_damage(x, y, 0L);
  146.      }
  147.  
  148.      if (res && picking_at(x, y)) {
  149.          /* maybe unseen monster zaps door you're unlocking */
  150.          stop_occupation();
  151.          reset_pick();
  152.      }
  153.      return res;
  154.  }
  155.  

chest_shatter_msg

  1.  STATIC_OVL void
  2.  chest_shatter_msg(otmp)
  3.  struct obj *otmp;
  4.  {
  5.      const char *disposition;
  6.      const char *thing;
  7.      long save_Blinded;
  8.  
  9.      if (otmp->oclass == POTION_CLASS) {
  10.          You("%s %s shatter!", Blind ? "hear" : "see", an(bottlename()));
  11.          if (!breathless(youmonst.data) || haseyes(youmonst.data))
  12.              potionbreathe(otmp);
  13.          return;
  14.      }
  15.      /* We have functions for distant and singular names, but not one */
  16.      /* which does _both_... */
  17.      save_Blinded = Blinded;
  18.      Blinded = 1;
  19.      thing = singular(otmp, xname);
  20.      Blinded = save_Blinded;
  21.      switch (objects[otmp->otyp].oc_material) {
  22.      case PAPER:
  23.          disposition = "is torn to shreds";
  24.          break;
  25.      case WAX:
  26.          disposition = "is crushed";
  27.          break;
  28.      case VEGGY:
  29.          disposition = "is pulped";
  30.          break;
  31.      case FLESH:
  32.          disposition = "is mashed";
  33.          break;
  34.      case GLASS:
  35.          disposition = "shatters";
  36.          break;
  37.      case WOOD:
  38.          disposition = "splinters to fragments";
  39.          break;
  40.      default:
  41.          disposition = "is destroyed";
  42.          break;
  43.      }
  44.      pline("%s %s!", An(thing), disposition);
  45.  }
  46.  
  47.  /*lock.c*/