]> granicus.if.org Git - nethack/commitdiff
Merge branch 'NetHack-3.6'
authornhmall <nhmall@nethack.org>
Wed, 5 Jun 2019 12:08:32 +0000 (08:08 -0400)
committernhmall <nhmall@nethack.org>
Wed, 5 Jun 2019 12:08:32 +0000 (08:08 -0400)
29 files changed:
1  2 
include/decl.h
include/extern.h
include/flag.h
src/apply.c
src/ball.c
src/do.c
src/do_wear.c
src/eat.c
src/end.c
src/files.c
src/hack.c
src/makemon.c
src/mkmaze.c
src/mkobj.c
src/mon.c
src/objnam.c
src/pickup.c
src/polyself.c
src/potion.c
src/pray.c
src/read.c
src/sit.c
src/steed.c
src/teleport.c
src/timeout.c
src/wield.c
src/zap.c
sys/winnt/Makefile.msc
util/makedefs.c

diff --cc include/decl.h
index 497463ae4517382622f3c2980214fb88b04acf44,5ebaa326e6181daab3ba7b935f96208b80042b2f..d07cc3ef40637926fcea54527ce35da308626f63
@@@ -380,6 -429,15 +380,13 @@@ struct plinemsg_type 
  /* bitmask for callers of hide_unhide_msgtypes() */
  #define MSGTYP_MASK_REP_SHOW ((1 << MSGTYP_NOREP) | (1 << MSGTYP_NOSHOW))
  
 -E struct plinemsg_type *plinemsg_types;
+ enum bcargs {override_restriction = -1};
+ struct breadcrumbs {
+     const char *funcnm;
+     int linenum;
+     boolean in_effect;
+ };
 -
  #ifdef PANICTRACE
  E const char *ARGV0;
  #endif
Simple merge
diff --cc include/flag.h
Simple merge
diff --cc src/apply.c
Simple merge
diff --cc src/ball.c
Simple merge
diff --cc src/do.c
Simple merge
diff --cc src/do_wear.c
Simple merge
diff --cc src/eat.c
Simple merge
diff --cc src/end.c
Simple merge
diff --cc src/files.c
index c7b81b2e011624a5ef71f6d7618c13c551c274b7,92940c9b08b93e5bb511cde856830e8f5f487940..d56e104968179c86c7eb7a44416dd146f3b9b3f4
@@@ -2889,10 -2946,10 +2889,10 @@@ struct obj *obj
      /* subset of starting inventory pre-ID */
      obj->dknown = 1;
      if (Role_if(PM_PRIEST))
-         obj->bknown = 1;
+         obj->bknown = 1; /* ok to bypass set_bknown() */
      /* same criteria as lift_object()'s check for available inventory slot */
      if (obj->oclass != COIN_CLASS && inv_cnt(FALSE) >= 52
 -        && !merge_choice(invent, obj)) {
 +        && !merge_choice(g.invent, obj)) {
          /* inventory overflow; can't just place & stack object since
             hero isn't in position yet, so schedule for arrival later */
          add_to_migration(obj);
diff --cc src/hack.c
index 1bbaf44d9a7a792727ddd50dfc0c2dc79330ebf8,74a13af98551d76550f8cddd8c1376040d72a602..9c08be267bf11cb43df639f6f475532f3d0dc53a
  unmul(msg_override)
  const char *msg_override;
  {
 -    multi = 0; /* caller will usually have done this already */
 +    g.multi = 0; /* caller will usually have done this already */
      if (msg_override)
 -        nomovemsg = msg_override;
 -    else if (!nomovemsg)
 -        nomovemsg = You_can_move_again;
 -    if (*nomovemsg) {
 -        pline("%s", nomovemsg);
 +        g.nomovemsg = msg_override;
 +    else if (!g.nomovemsg)
 +        g.nomovemsg = You_can_move_again;
-     if (*g.nomovemsg)
++    if (*g.nomovemsg) {
 +        pline("%s", g.nomovemsg);
+         /* follow "you survived that attempt on your life" with a message
+            about current form if it's not the default; primarily for
+            life-saving while turning into green slime but is also a reminder
+            if life-saved while poly'd and Unchanging (explore or wizard mode
+            declining to die since can't be both Unchanging and Lifesaved) */
 -        if (Upolyd && !strncmpi(nomovemsg, "You survived that ", 18))
++        if (Upolyd && !strncmpi(g.nomovemsg, "You survived that ", 18))
+             You("are %s", an(mons[u.umonnum].mname)); /* (ignore Hallu) */
+     }
 -    nomovemsg = 0;
 +    g.nomovemsg = 0;
      u.usleep = 0;
 -    multi_reason = NULL;
 -    if (afternmv) {
 -        int NDECL((*f)) = afternmv;
 +    g.multi_reason = NULL;
 +    if (g.afternmv) {
 +        int NDECL((*f)) = g.afternmv;
  
          /* clear afternmv before calling it (to override the
             encumbrance hack for levitation--see weight_cap()) */
diff --cc src/makemon.c
index b5af919cd2a3c54415a52bf04ef7b0f30b76472e,b2cb2c8a1f8cb6de2f777ecf5bd793e8e69fb1b2..9d36a3835fc2bb284230af1160b19f0c6914786d
@@@ -1120,6 -1120,7 +1120,7 @@@ int mmflags
          struct monst fakemon;
  
          cc.x = cc.y = 0; /* lint suppression */
 -        fakemon = zeromonst;
++        fakemon = cg.zeromonst;
          fakemon.data = ptr; /* set up for goodpos */
          if (!makemon_rnd_goodpos(ptr ? &fakemon : (struct monst *)0,
                                   gpflags, &cc))
diff --cc src/mkmaze.c
index 9b157750edabcbd97de36e168a2151c6bbd7c211,2a11ba4eda18107002ff3adf1636080dce5d455b..5f09d1bb37de01c0a68f80cb55d5cc7e23d0d730
@@@ -1390,10 -1400,10 +1390,10 @@@ movebubbles(
      struct bubble *b;
      struct container *cons;
      struct trap *btrap;
-     int x, y, i, j;
+     int x, y, i, j, bcpin;
  
      /* set up the portal the first time bubbles are moved */
 -    if (!wportal)
 +    if (!g.wportal)
          set_wportal();
  
      vision_recalc(2);
  
      /* put attached ball&chain back */
      if (Is_waterlevel(&u.uz) && Punished)
-         placebc();
+         lift_covet_and_placebc(bcpin);
 -    vision_full_recalc = 1;
 +    g.vision_full_recalc = 1;
  }
  
  /* when moving in water, possibly (1 in 3) alter the intended destination */
diff --cc src/mkobj.c
index 7501158f89daa5737a846fecf10962ec44b724f8,5f98fe34e8497f81f3b5179351ae0b79467e48e5..1cdf8426fac86973e626b100963cd74cf8e13138
@@@ -1389,6 -1389,19 +1389,19 @@@ register struct obj *otmp
      return (!!otmp->blessed - !!otmp->cursed);
  }
  
 -        if (obj->where == OBJ_INVENT && moves > 1L)
+ /* set the object's bless/curse-state known flag */
+ void
+ set_bknown(obj, onoff)
+ struct obj *obj;
+ unsigned onoff; /* 1 or 0 */
+ {
+     if (obj->bknown != onoff) {
+         obj->bknown = onoff;
++        if (obj->where == OBJ_INVENT && g.moves > 1L)
+             update_inventory();
+     }
+ }
  /*
   *  Calculate the weight of the given object.  This will recursively follow
   *  and calculate the weight of any containers.
diff --cc src/mon.c
index a385eb7a490084e57b36e8eee8c244c11e531e10,e281cb392295c74f7ca773ca84c8c89f50537501..670a8945ab13b5cdcad3566991c39550aa8408c8
+++ b/src/mon.c
@@@ -2683,10 -2692,11 +2690,11 @@@ struct monst *mon
              rloc_to(mon, mx, my);           /* note: mon, not mtmp */
          } else {
              /* last resort - migrate mon to the next plane */
-             if (Is_waterlevel(&u.uz) || Is_firelevel(&u.uz) || Is_earthlevel(&u.uz)) {
+             if (Is_waterlevel(&u.uz) || Is_firelevel(&u.uz)
+                 || Is_earthlevel(&u.uz)) {
                  /* try sending mon on to the next plane */
                  xchar target_lev = 0, xyloc = 0;
 -                struct trap *trap = ftrap;
 +                struct trap *trap = g.ftrap;
  
                  while (trap) {
                      if (trap->ttyp == MAGIC_PORTAL)
diff --cc src/objnam.c
index b74ffafdfd10f90bca2dd75831a2be855465aef4,5e51bee9b6a3682665d255c9b52cd1c1c3211d83..73f1dc7d4f8dba06b574307c97e08032798872f8
@@@ -444,10 -449,13 +444,13 @@@ unsigned cxn_flags; /* bitmask of CXN_x
       */
      if (!nn && ocl->oc_uses_known && ocl->oc_unique)
          obj->known = 0;
 -    if (!Blind && !distantname)
 +    if (!Blind && !g.distantname)
-         obj->dknown = TRUE;
+         obj->dknown = 1;
      if (Role_if(PM_PRIEST))
-         obj->bknown = TRUE;
+         obj->bknown = 1; /* actively avoid set_bknown();
+                           * we mustn't call update_inventory() now because
+                           * it would call xname() (via doname()) recursively
+                           * and could end up clobbering all the obufs... */
  
      if (iflags.override_ID) {
          known = dknown = bknown = TRUE;
diff --cc src/pickup.c
index 19be7a71b14f834336ed1b044dff3c521b7088f5,77356b1fef7460a12eba566f75f427d5df38e387..123fb70654a53dfec5c714a4e188a60e67cbac82
@@@ -2489,20 -2506,18 +2493,18 @@@ boolean more_containers; /* True iff #l
      } else if (obj->otrapped) {
          if (held)
              You("open %s...", the(xname(obj)));
-         obj->lknown = 1;
          (void) chest_trap(obj, HAND, FALSE);
          /* even if the trap fails, you've used up this turn */
 -        if (multi >= 0) { /* in case we didn't become paralyzed */
 +        if (g.multi >= 0) { /* in case we didn't become paralyzed */
              nomul(-1);
 -            multi_reason = "opening a container";
 -            nomovemsg = "";
 +            g.multi_reason = "opening a container";
 +            g.nomovemsg = "";
          }
 -        abort_looting = TRUE;
 +        g.abort_looting = TRUE;
          return 1;
      }
-     obj->lknown = 1;
  
 -    current_container = obj; /* for use by in/out_container */
 +    g.current_container = obj; /* for use by in/out_container */
      /*
       * From here on out, all early returns go through 'containerdone:'.
       */
diff --cc src/polyself.c
index eb5d10326ff985a4121f661590591c2ec0124f7b,3f33c8e9b8a0058ae1cca141095f6ecccc75cbc6..87143cb6122664129a0a17f5004ecebf08568f0e
@@@ -158,8 -162,8 +158,8 @@@ STATIC_OVL voi
  polyman(fmt, arg)
  const char *fmt, *arg;
  {
 -    boolean sticky = (sticks(youmonst.data) && u.ustuck && !u.uswallow),
 +    boolean sticky = (sticks(g.youmonst.data) && u.ustuck && !u.uswallow),
-             was_mimicking = (U_AP_TYPE == M_AP_OBJECT);
+             was_mimicking = (U_AP_TYPE != M_AP_NOTHING);
      boolean was_blind = !!Blind;
  
      if (Upolyd) {
          uunstick();
      find_ac();
      if (was_mimicking) {
 -        if (multi < 0)
 +        if (g.multi < 0)
              unmul("");
 -        youmonst.m_ap_type = M_AP_NOTHING;
 -        youmonst.mappearance = 0;
 +        g.youmonst.m_ap_type = M_AP_NOTHING;
++        g.youmonst.mappearance = 0;
      }
  
      newsym(u.ux, u.uy);
@@@ -628,7 -633,8 +629,8 @@@ int mntmp
      /* if becoming a non-mimic, stop mimicking anything */
      if (mons[mntmp].mlet != S_MIMIC) {
          /* as in polyman() */
 -        youmonst.m_ap_type = M_AP_NOTHING;
 -        youmonst.mappearance = 0;
 +        g.youmonst.m_ap_type = M_AP_NOTHING;
++        g.youmonst.mappearance = 0;
      }
      if (is_male(&mons[mntmp])) {
          if (flags.female)
diff --cc src/potion.c
index e80d3a06849ff98ac9c3a13b791f6cbd52511c26,a07fcd0d8c0a3e030c07253866b5699e635d499e..e6891ffdb4e648eb9d605848bb65ffbf1c4b70fc
@@@ -182,8 -185,15 +182,15 @@@ const char *msg
          if (msg)
              pline("%s", msg);
      }
-     if (!Slimed)
+     if (!Slimed) {
          dealloc_killer(find_delayed_killer(SLIMED));
 -        if (youmonst.m_ap_type == M_AP_MONSTER
 -            && youmonst.mappearance == PM_GREEN_SLIME) {
 -            youmonst.m_ap_type = M_AP_NOTHING;
 -            youmonst.mappearance = 0;
+         /* fake appearance is set late in turn-to-slime countdown */
++        if (g.youmonst.m_ap_type == M_AP_MONSTER
++            && g.youmonst.mappearance == PM_GREEN_SLIME) {
++            g.youmonst.m_ap_type = M_AP_NOTHING;
++            g.youmonst.mappearance = 0;
+         }
+     }
  }
  
  /* start or stop petrification */
diff --cc src/pray.c
Simple merge
diff --cc src/read.c
Simple merge
diff --cc src/sit.c
Simple merge
diff --cc src/steed.c
Simple merge
diff --cc src/teleport.c
index 24a4bd1869ac8f9582d5f722df4bec03f6b9d543,61ca40fa7c17f1785f46c249b9fbdb0d3b991e49..4ed074c4175d05fd5b314cc6c2037e48380df8cb
@@@ -59,16 -62,26 +59,26 @@@ unsigned gpflags
  
          mdat = mtmp->data;
          if (is_pool(x, y) && !ignorewater) {
 -            if (mtmp == &youmonst)
+             /* [what about Breathless?] */
-                 return (Levitation || Flying || Wwalking || Swimming
-                         || Amphibious);
 +            if (mtmp == &g.youmonst)
+                 return (Swimming || Amphibious
+                         || (!Is_waterlevel(&u.uz)
+                             /* water on the Plane of Water has no surface
+                                so there's no way to be on or above that */
+                             && (Levitation || Flying || Wwalking)));
              else
-                 return (is_floater(mdat) || is_flyer(mdat) || is_swimmer(mdat)
-                         || is_clinger(mdat));
+                 return (is_swimmer(mdat)
+                         || (!Is_waterlevel(&u.uz)
+                             && (is_floater(mdat) || is_flyer(mdat)
+                                 || is_clinger(mdat))));
          } else if (mdat->mlet == S_EEL && rn2(13) && !ignorewater) {
              return FALSE;
          } else if (is_lava(x, y)) {
-             if (mtmp == &g.youmonst)
+             /* 3.6.3: floating eye can levitate over lava but it avoids
+                that due the effect of the heat causing it to dry out */
+             if (mdat == &mons[PM_FLOATING_EYE])
+                 return FALSE;
 -            else if (mtmp == &youmonst)
++            else if (mtmp == &g.youmonst)
                  return (Levitation || Flying
                          || (Fire_resistance && Wwalking && uarmf
                              && uarmf->oerodeproof)
diff --cc src/timeout.c
index 971503d733e7ad4185d49d749e4d22058b3c69ae,54a2943c3d0ee3554181718b41a97720d589fb02..05f14fa9284bc835fd4ba364b6ad8e6c9fa3429f
@@@ -399,21 -399,32 +399,32 @@@ struct kinfo *kptr
       * [formerly implicit] change of form; polymon() takes care of that.
       * Temporarily ungenocide if necessary.
       */
 -    if (emits_light(youmonst.data))
 -        del_light_source(LS_MONSTER, monst_to_any(&youmonst));
 -    save_mvflags = mvitals[PM_GREEN_SLIME].mvflags;
 -    mvitals[PM_GREEN_SLIME].mvflags = save_mvflags & ~G_GENOD;
 +    if (emits_light(g.youmonst.data))
 +        del_light_source(LS_MONSTER, monst_to_any(&g.youmonst));
 +    save_mvflags = g.mvitals[PM_GREEN_SLIME].mvflags;
 +    g.mvitals[PM_GREEN_SLIME].mvflags = save_mvflags & ~G_GENOD;
+     /* become a green slime; also resets youmonst.m_ap_type+.mappearance */
      (void) polymon(PM_GREEN_SLIME);
 -    mvitals[PM_GREEN_SLIME].mvflags = save_mvflags;
 +    g.mvitals[PM_GREEN_SLIME].mvflags = save_mvflags;
      done(TURNED_SLIME);
  
      /* life-saved; even so, hero still has turned into green slime;
         player may have genocided green slimes after being infected */
 -    if ((mvitals[PM_GREEN_SLIME].mvflags & G_GENOD) != 0) {
 +    if ((g.mvitals[PM_GREEN_SLIME].mvflags & G_GENOD) != 0) {
+         char slimebuf[BUFSZ];
 -        killer.format = KILLED_BY;
 -        Strcpy(killer.name, "slimicide");
 +        g.killer.format = KILLED_BY;
 +        Strcpy(g.killer.name, "slimicide");
-         /* immediately follows "OK, so you don't die." */
-         pline("Yes, you do.  Green slime has been genocided...");
+         /* vary the message depending upon whether life-save was due to
+            amulet or due to declining to die in explore or wizard mode */
+         Strcpy(slimebuf, "green slime has been genocided...");
+         if (iflags.last_msg == PLNMSG_OK_DONT_DIE)
+             /* follows "OK, so you don't die." and arg is second sentence */
+             pline("Yes, you do.  %s", upstart(slimebuf));
+         else
+             /* follows "The medallion crumbles to dust." */
+             pline("Unfortunately, %s", slimebuf);
+         /* die again; no possibility of amulet this time */
          done(GENOCIDED);
          /* could be life-saved again (only in explore or wizard mode)
             but green slimes are gone; just stay in current form */
diff --cc src/wield.c
Simple merge
diff --cc src/zap.c
index 755fcc4d2ce8870027a9bcfb1a38cd0ee8d5c190,724dc318988a0a53d99bdc33f2fbb6c83244a754..aa53e0f843bf52e37375fa9c0227d4d8d567f841
+++ b/src/zap.c
@@@ -1891,9 -1901,9 +1893,9 @@@ struct obj *obj, *otmp
                  (void) boxlock(obj, otmp);
  
              if (obj_shudders(obj)) {
-                 boolean cover =
-                     ((obj == g.level.objects[u.ux][u.uy]) && u.uundetected
-                      && hides_under(g.youmonst.data));
 -                boolean cover = ((obj == level.objects[u.ux][u.uy])
++                boolean cover = ((obj == g.level.objects[u.ux][u.uy])
+                                  && u.uundetected
 -                                 && hides_under(youmonst.data));
++                                 && hides_under(g.youmonst.data));
  
                  if (cansee(obj->ox, obj->oy))
                      learn_it = TRUE;
@@@ -2486,22 -2497,39 +2489,39 @@@ boolean ordinary
              learn_it = TRUE;
              unpunish();
          }
-         if (u.utrap) { /* escape web or bear trap */
-             (void) openholdingtrap(&g.youmonst, &learn_it);
-         } else {
+         /* invent is hit iff hero doesn't escape from a trap */
 -        if (!u.utrap || !openholdingtrap(&youmonst, &learn_it)) {
++        if (!u.utrap || !openholdingtrap(&g.youmonst, &learn_it)) {
              struct obj *otmp;
+             boolean boxing = FALSE;
              /* unlock carried boxes */
 -            for (otmp = invent; otmp; otmp = otmp->nobj)
 +            for (otmp = g.invent; otmp; otmp = otmp->nobj)
-                 if (Is_box(otmp))
+                 if (Is_box(otmp)) {
                      (void) boxlock(otmp, obj);
+                     boxing = TRUE;
+                 }
+             if (boxing)
+                 update_inventory(); /* in case any box->lknown has changed */
              /* trigger previously escaped trapdoor */
 -            (void) openfallingtrap(&youmonst, TRUE, &learn_it);
 +            (void) openfallingtrap(&g.youmonst, TRUE, &learn_it);
          }
          break;
      case WAN_LOCKING:
      case SPE_WIZARD_LOCK:
-         if (!u.utrap) {
-             (void) closeholdingtrap(&g.youmonst, &learn_it);
+         /* similar logic to opening; invent is hit iff no trap triggered */
 -        if (u.utrap || !closeholdingtrap(&youmonst, &learn_it)) {
++        if (u.utrap || !closeholdingtrap(&g.youmonst, &learn_it)) {
+             struct obj *otmp;
+             boolean boxing = FALSE;
+             /* lock carried boxes */
 -            for (otmp = invent; otmp; otmp = otmp->nobj)
++            for (otmp = g.invent; otmp; otmp = otmp->nobj)
+                 if (Is_box(otmp)) {
+                     (void) boxlock(otmp, obj);
+                     boxing = TRUE;
+                 }
+             if (boxing)
+                 update_inventory(); /* in case any box->lknown has changed */
          }
          break;
      case WAN_DIGGING:
Simple merge
diff --cc util/makedefs.c
Simple merge