]> granicus.if.org Git - nethack/commitdiff
Merge branch 'NetHack-3.6'
authornhmall <nhmall@nethack.org>
Sat, 8 Jun 2019 13:38:27 +0000 (09:38 -0400)
committernhmall <nhmall@nethack.org>
Sat, 8 Jun 2019 13:38:27 +0000 (09:38 -0400)
1  2 
include/display.h
include/extern.h
include/monst.h
include/rm.h
include/vision.h
src/light.c
src/save.c
src/weapon.c
src/zap.c

Simple merge
Simple merge
diff --cc include/monst.h
Simple merge
diff --cc include/rm.h
index e001d8e0c866444a7c4a2feddd24c73f6e858300,1190a355b4ed8f8c4a41e3a9aae1fb807f77ce4d..e104fc20fdf87a1af88a4e0c5c86d11bc0c1512c
@@@ -615,12 -624,16 +615,16 @@@ typedef struct 
  /*
   * Macros for encapsulation of level.monsters references.
   */
+ #if 0
  #define MON_AT(x, y)                            \
 -    (level.monsters[x][y] != (struct monst *) 0 \
 -     && !(level.monsters[x][y])->mburied)
 +    (g.level.monsters[x][y] != (struct monst *) 0 \
 +     && !(g.level.monsters[x][y])->mburied)
  #define MON_BURIED_AT(x, y)                     \
 -    (level.monsters[x][y] != (struct monst *) 0 \
 -     && (level.monsters[x][y])->mburied)
 +    (g.level.monsters[x][y] != (struct monst *) 0 \
 +     && (g.level.monsters[x][y])->mburied)
+ #else   /* without 'mburied' */
 -#define MON_AT(x, y) (level.monsters[x][y] != (struct monst *) 0)
++#define MON_AT(x, y) (g.level.monsters[x][y] != (struct monst *) 0)
+ #endif
  #ifdef EXTRA_SANITY_CHECKS
  #define place_worm_seg(m, x, y) \
      do {                                                        \
Simple merge
diff --cc src/light.c
index 51e3a0d97660851280282f1d2c4f8fa244114dfd,7c2dc1f2de2ac75a2165b1e834023d2e3bae5f08..ab0e619f45fd3e8df4bf151e5d7e0cb3627ca7d2
@@@ -63,9 -65,9 +63,9 @@@ anything *id
          return;
      }
  
-     ls = (light_source *) alloc(sizeof(light_source));
+     ls = (light_source *) alloc(sizeof *ls);
  
 -    ls->next = light_base;
 +    ls->next = g.light_base;
      ls->x = x;
      ls->y = y;
      ls->range = range;
@@@ -208,6 -210,80 +208,80 @@@ char **cs_rows
      }
  }
  
 -    for (ls = light_base; ls; ls = ls->next) {
+ /* lit 'obj' has been thrown or kicked and is passing through x,y on the
+    way to its destination; show its light so that hero has a chance to
+    remember terrain, objects, and monsters being revealed */
+ void
+ show_transient_light(obj, x, y)
+ struct obj *obj;
+ int x, y;
+ {
+     light_source *ls;
+     struct monst *mon;
+     int radius_squared;
+     /* caller has verified obj->lamplit and that hero is not Blind;
+        validate light source and obtain its radius (for monster sightings) */
 -        place_object(obj, bhitpos.x, bhitpos.y); /* temporarily put on map */
++    for (ls = g.light_base; ls; ls = ls->next) {
+         if (ls->type != LS_OBJECT)
+             continue;
+         if (ls->id.a_obj == obj)
+             break;
+     }
+     if (!ls || obj->where != OBJ_FREE) {
+         impossible("transient light %s %s is not %s?",
+                    obj->lamplit ? "lit" : "unlit", xname(obj),
+                    !ls ? "a light source" : "free");
+     } else {
+         /* "expensive" but rare */
++        place_object(obj, g.bhitpos.x, g.bhitpos.y); /* temporarily put on map */
+         vision_recalc(0);
+         flush_screen(0);
+         delay_output();
+         remove_object(obj); /* take back off of map */
+         radius_squared = ls->range * ls->range;
+         for (mon = fmon; mon; mon = mon->nmon) {
+             if (DEADMONSTER(mon))
+                 continue;
+             /* light range is the radius of a circle and we're limiting
+                canseemon() to a square exclosing that circle, but setting
+                mtemplit 'erroneously' for a seen monster is not a problem;
+                it just flags monsters for another canseemon() check when
+                'obj' has reached its destination after missile traversal */
+             if (dist2(mon->mx, mon->my, x, y) <= radius_squared
+                 && canseemon(mon))
+                 mon->mtemplit = 1;
+             /* [what about worm tails?] */
+         }
+     }
+ }
+ /* draw "remembered, unseen monster" glyph at locations where a monster
+    was flagged for being visible during transient light movement but can't
+    be seen now */
+ void
+ transient_light_cleanup()
+ {
+     struct monst *mon;
+     int mtempcount = 0;
+     for (mon = fmon; mon; mon = mon->nmon) {
+         if (DEADMONSTER(mon))
+             continue;
+         if (mon->mtemplit) {
+             mon->mtemplit = 0;
+             ++mtempcount;
+             if (!canseemon(mon))
+                 map_invisible(mon->mx, mon->my);
+         }
+     }
+     if (mtempcount) {
+         vision_recalc(0);
+         flush_screen(0);
+     }
+ }
  /* (mon->mx == 0) implies migrating */
  #define mon_is_local(mon) ((mon)->mx > 0)
  
diff --cc src/save.c
Simple merge
diff --cc src/weapon.c
Simple merge
diff --cc src/zap.c
index aa53e0f843bf52e37375fa9c0227d4d8d567f841,1563d434ce9a79a042ce31d92facfe7f60df9eb7..60bcee3a70248e212064a8ee4cd40655dcfd307a
+++ b/src/zap.c
@@@ -3264,21 -3272,25 +3264,25 @@@ struct obj **pobj; /* object tossed/use
          if (is_pick(obj) && inside_shop(x, y)
              && (mtmp = shkcatch(obj, x, y)) != 0) {
              tmp_at(DISP_END, 0);
-             return mtmp;
+             result = mtmp;
+             goto bhit_done;
          }
  
 -        typ = levl[bhitpos.x][bhitpos.y].typ;
 +        typ = levl[g.bhitpos.x][g.bhitpos.y].typ;
  
-         /* iron bars will block anything big enough */
-         if ((weapon == THROWN_WEAPON || weapon == KICKED_WEAPON)
-             && typ == IRONBARS
-             && hits_bars(pobj, x - ddx, y - ddy, g.bhitpos.x, g.bhitpos.y,
-                          point_blank ? 0 : !rn2(5), 1)) {
-             /* caveat: obj might now be null... */
-             obj = *pobj;
-             g.bhitpos.x -= ddx;
-             g.bhitpos.y -= ddy;
-             break;
+         /* iron bars will block anything big enough and break some things */
+         if (weapon == THROWN_WEAPON || weapon == KICKED_WEAPON) {
+             if (typ == IRONBARS
 -                && hits_bars(pobj, x - ddx, y - ddy, bhitpos.x, bhitpos.y,
++                && hits_bars(pobj, x - ddx, y - ddy, g.bhitpos.x, g.bhitpos.y,
+                              point_blank ? 0 : !rn2(5), 1)) {
+                 /* caveat: obj might now be null... */
+                 obj = *pobj;
 -                bhitpos.x -= ddx;
 -                bhitpos.y -= ddy;
++                g.bhitpos.x -= ddx;
++                g.bhitpos.y -= ddy;
+                 break;
+             } else if (obj->lamplit && !Blind) {
 -                show_transient_light(obj, bhitpos.x, bhitpos.y);
++                show_transient_light(obj, g.bhitpos.x, g.bhitpos.y);
+             }
          }
  
          if (weapon == ZAPPED_WAND && find_drawbridge(&x, &y)) {
                  if (!tethered_weapon)
                      tmp_at(DISP_END, 0);
  
 -                if (cansee(bhitpos.x, bhitpos.y) && !canspotmon(mtmp))
 -                    map_invisible(bhitpos.x, bhitpos.y);
 +                if (cansee(g.bhitpos.x, g.bhitpos.y) && !canspotmon(mtmp))
 +                    map_invisible(g.bhitpos.x, g.bhitpos.y);
-                 return mtmp;
+                 result = mtmp;
+                 goto bhit_done;
              } else {
                  /* ZAPPED_WAND */
                  (*fhitm)(mtmp, obj);
          } else {
              if (weapon == KICKED_WEAPON
                  && ((obj->oclass == COIN_CLASS
 -                     && OBJ_AT(bhitpos.x, bhitpos.y))
 -                    || ship_object(obj, bhitpos.x, bhitpos.y,
 -                                   costly_spot(bhitpos.x, bhitpos.y)))) {
 +                     && OBJ_AT(g.bhitpos.x, g.bhitpos.y))
 +                    || ship_object(obj, g.bhitpos.x, g.bhitpos.y,
 +                                   costly_spot(g.bhitpos.x, g.bhitpos.y)))) {
                  tmp_at(DISP_END, 0);
-                 return (struct monst *) 0;
+                 goto bhit_done; /* result == (struct monst *) 0 */
              }
          }
          if (weapon == ZAPPED_WAND && (IS_DOOR(typ) || typ == SDOOR)) {