OSDN Git Service

upgrade to 3.6.2
[jnethack/source.git] / src / lock.c
index 5092c3f..9b4f32d 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 lock.c  $NHDT-Date: 1521499715 2018/03/19 22:48:35 $  $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.80 $ */
+/* NetHack 3.6 lock.c  $NHDT-Date: 1548978605 2019/01/31 23:50:05 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.84 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2011. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -253,12 +253,13 @@ boolean destroyit;
             if (!rn2(3) || otmp->oclass == POTION_CLASS) {
                 chest_shatter_msg(otmp);
                 if (costly)
-                    loss +=
-                        stolen_value(otmp, u.ux, u.uy, peaceful_shk, TRUE);
+                    loss += stolen_value(otmp, u.ux, u.uy, peaceful_shk, TRUE);
                 if (otmp->quan == 1L) {
                     obfree(otmp, (struct obj *) 0);
                     continue;
                 }
+                /* this works because we're sure to have at least 1 left;
+                   otherwise it would fail since otmp is not in inventory */
                 useup(otmp);
             }
             if (box->otyp == ICE_BOX && otmp->otyp == CORPSE) {
@@ -326,10 +327,14 @@ forcelock(VOID_ARGS)
     You("succeed in forcing the lock.");
 */
     pline("\8c®\82ð\82±\82\8aJ\82¯\82½\81D");
+    exercise(xlock.picktyp ? A_DEX : A_STR, TRUE);
+    /* breakchestlock() might destroy xlock.box; if so, xlock context will
+       be cleared (delobj -> obfree -> maybe_reset_pick); but it might not,
+       so explicitly clear that manually */
     breakchestlock(xlock.box, (boolean) (!xlock.picktyp && !rn2(3)));
+    reset_pick(); /* lock-picking context is no longer valid */
 
-    exercise((xlock.picktyp) ? A_DEX : A_STR, TRUE);
-    return ((xlock.usedtime = 0));
+    return 0;
 }
 
 void
@@ -337,15 +342,28 @@ reset_pick()
 {
     xlock.usedtime = xlock.chance = xlock.picktyp = 0;
     xlock.magic_key = FALSE;
-    xlock.door = 0;
-    xlock.box = 0;
+    xlock.door = (struct rm *) 0;
+    xlock.box = (struct obj *) 0;
 }
 
-/* level change; don't reset if hero is carrying xlock.box with him/her */
+/* level change or object deletion; context may no longer be valid */
 void
-maybe_reset_pick()
+maybe_reset_pick(container)
+struct obj *container; /* passed from obfree() */
 {
-    if (!xlock.box || !carried(xlock.box))
+    /*
+     * If a specific container, only clear context if it is for that
+     * particular container (which is being deleted).  Other stuff on
+     * the current dungeon level remains valid.
+     * However if 'container' is Null, clear context if not carrying
+     * xlock.box (which might be Null if context is for a door).
+     * Used for changing levels, where a floor container or a door is
+     * being left behind and won't be valid on the new level but a
+     * carried container will still be.  There might not be any context,
+     * in which case redundantly clearing it is harmless.
+     */
+    if (container ? (container == xlock.box)
+                  : (!xlock.box || !carried(xlock.box)))
         reset_pick();
 }
 
@@ -590,8 +608,8 @@ struct obj *pick;
 
         door = &levl[cc.x][cc.y];
         mtmp = m_at(cc.x, cc.y);
-        if (mtmp && canseemon(mtmp) && mtmp->m_ap_type != M_AP_FURNITURE
-            && mtmp->m_ap_type != M_AP_OBJECT) {
+        if (mtmp && canseemon(mtmp) && M_AP_TYPE(mtmp) != M_AP_FURNITURE
+            && M_AP_TYPE(mtmp) != M_AP_OBJECT) {
             if (picktyp == CREDIT_CARD
                 && (mtmp->isshk || mtmp->data == &mons[PM_ORACLE]))
 /*JP
@@ -998,8 +1016,8 @@ boolean quietly;
 {
     register struct monst *mtmp = m_at(x, y);
 
-    if (mtmp && mtmp->m_ap_type != M_AP_FURNITURE) {
-        if (mtmp->m_ap_type == M_AP_OBJECT)
+    if (mtmp && M_AP_TYPE(mtmp) != M_AP_FURNITURE) {
+        if (M_AP_TYPE(mtmp) == M_AP_OBJECT)
             goto objhere;
         if (!quietly) {
             if ((mtmp->mx != x) || (mtmp->my != y)) {
@@ -1028,7 +1046,7 @@ boolean quietly;
         return TRUE;
     }
     if (OBJ_AT(x, y)) {
   objhere:
+ objhere:
         if (!quietly)
 /*JP
             pline("%s's in the way.", Something);
@@ -1112,7 +1130,7 @@ doclose()
 */
             pline("\92µ\82Ë\8b´\82ð\95Â\82ß\82é\96¾\94\92\82È\95û\96@\82Í\82È\82¢\81D");
         else {
       nodoor:
+ nodoor:
 /*JP
             You("%s no door there.", Blind ? "feel" : "see");
 */
@@ -1295,7 +1313,7 @@ int x, y;
                 return FALSE;
             }
             block_point(x, y);
-            door->typ = SDOOR;
+            door->typ = SDOOR, door->doormask = D_NODOOR;
             if (vis)
 /*JP
                 pline_The("doorway vanishes!");