]> granicus.if.org Git - nethack/commitdiff
R1049 - various wand of digging bugs
authorcohrs <cohrs>
Wed, 21 Aug 2002 23:06:58 +0000 (23:06 +0000)
committercohrs <cohrs>
Wed, 21 Aug 2002 23:06:58 +0000 (23:06 +0000)
- Breaking wand of digging dug through rock which should be undiggable.
Checks assumed pits would never show up in solid rock.
- Breaking wand of digging near shop walls wouldn't anger the shopkeeper
Checks assumed pits would never show up in walls, also, added a special
case to pay_for_damage to handle the case where you're falling thru and
can't be asked to pay.
- Shop walls wouldn't be restored if there are pits in the way.
Checks assumed pits would never show up in walls.
- If there was a hole outside the shop, you could kick stuff out of the
door into the hole without shopkeeper noticing.  Added the missing check.

doc/fixes34.1
include/extern.h
src/apply.c
src/dig.c
src/dokick.c
src/explode.c
src/hack.c
src/shk.c
src/trap.c
src/zap.c

index 42ee888ae2ee7ad509e75eead6a53c526121b948..4f25e63906a58ea935a7bf0b95438309666e7e58 100644 (file)
@@ -212,6 +212,11 @@ don't see chest trap gas colors while Blind
 adjust fruit name in potion juice messages if it has the form "foo of bar"
 wielded camera passes harmlessly through shade
 reading spellbooks while confused should allow tearing the book
+Breaking wand of digging dug through rock which should be undiggable.
+Breaking wand of digging near shop walls wouldn't anger the shopkeeper
+Shop walls wouldn't be restored if there were pits in the way.
+If there were a hole outside a shop, you could kick stuff out of the door
+       into the hole without the shopkeeper noticing.
 
 
 Platform- and/or Interface-Specific Fixes
index 0915fe706d24c8cafa92bf2e2883532e43d3a608..cbc02543c7d72a29df52a2e1211d9ff511b68bf1 100644 (file)
@@ -1779,7 +1779,7 @@ E int FDECL(shk_move, (struct monst *));
 E void FDECL(after_shk_move, (struct monst *));
 E boolean FDECL(is_fshk, (struct monst *));
 E void FDECL(shopdig, (int));
-E void FDECL(pay_for_damage, (const char *));
+E void FDECL(pay_for_damage, (const char *,BOOLEAN_P));
 E boolean FDECL(costly_spot, (XCHAR_P,XCHAR_P));
 E struct obj *FDECL(shop_object, (XCHAR_P,XCHAR_P));
 E void FDECL(price_quote, (struct obj *));
index c432f24d81d868526ca432cb0a872f03559e1175..6e1e645dcb5ec2b210732e6cbbfeff49cc7d74cd 100644 (file)
@@ -2556,6 +2556,7 @@ do_break_wand(obj)
     register struct monst *mon;
     int dmg, damage;
     boolean affects_objects;
+    boolean shop_damage = FALSE;
     int expltype = EXPL_MAGICAL;
     char confirm[QBUFSZ], the_wand[BUFSZ], buf[BUFSZ];
 
@@ -2643,10 +2644,13 @@ do_break_wand(obj)
        if (!isok(x,y)) continue;
 
        if (obj->otyp == WAN_DIGGING) {
-           if(dig_check(BY_OBJECT, FALSE, x, y))
+           if(dig_check(BY_OBJECT, FALSE, x, y)) {
+               if ((IS_WALL(levl[x][y].typ) || IS_DOOR(levl[x][y].typ)) &&
+                   *in_rooms(x,y,SHOPBASE)) shop_damage = TRUE;
                digactualhole(x, y, BY_OBJECT,
                              (rn2(obj->spe) < 3 || !Can_dig_down(&u.uz)) ?
                               PIT : HOLE);
+           }
            continue;
        } else if(obj->otyp == WAN_CREATE_MONSTER) {
            /* u.ux,u.uy creates it near you--x,y might create it in rock */
@@ -2679,6 +2683,10 @@ do_break_wand(obj)
        }
     }
 
+    /* Note: if player fell thru, this call is a no-op.
+       Damage is handled in digactualhole in that case */
+    if (shop_damage) pay_for_damage("dig into", FALSE);
+
     if (obj->otyp == WAN_LIGHT)
        litroom(TRUE, obj);     /* only needs to be done once */
 
index 7016de891d2523fcbdb2d350d7206203470c62a6..48fa802585dacf53e7d0f1ba85e67d6ef3e8d19f 100644 (file)
--- a/src/dig.c
+++ b/src/dig.c
@@ -186,7 +186,7 @@ dig_check(madeby, verbose, x, y)
        } else if (Is_waterlevel(&u.uz)) {
            if(verbose) pline_The("water splashes and subsides.");
            return(FALSE);
-       } else if ((IS_WALL(levl[x][y].typ) &&
+       } else if ((IS_ROCK(levl[x][y].typ) && levl[x][y].typ != SDOOR &&
                      (levl[x][y].wall_info & W_NONDIGGABLE) != 0)
                || (ttmp &&
                      (ttmp->ttyp == MAGIC_PORTAL || !Can_dig_down(&u.uz)))) {
@@ -381,7 +381,7 @@ dig()
                    newsym(dpx, dpy);
                if(digtxt && !digging.quiet) pline(digtxt); /* after newsym */
                if(dmgtxt)
-                   pay_for_damage(dmgtxt);
+                   pay_for_damage(dmgtxt, FALSE);
 
                if(Is_earthlevel(&u.uz) && !rn2(3)) {
                    register struct monst *mtmp;
@@ -531,7 +531,7 @@ int ttyp;
 
            if(madeby_u) {
                You("dig a pit in the %s.", surface_type);
-               if (shopdoor) pay_for_damage("ruin");
+               if (shopdoor) pay_for_damage("ruin", FALSE);
            } else if (!madeby_obj && canseemon(madeby))
                pline("%s digs a pit in the %s.", Monnam(madeby), surface_type);
            else if (cansee(x, y) && flags.verbose)
@@ -580,13 +580,15 @@ int ttyp;
                        impact_drop((struct obj *)0, x, y, 0);
                    if (oldobjs != newobjs)
                        (void) pickup(1);
-                   if (shopdoor && madeby_u) pay_for_damage("ruin");
+                   if (shopdoor && madeby_u) pay_for_damage("ruin", FALSE);
 
                } else {
                    d_level newlevel;
 
                    if (*u.ushops && madeby_u)
                        shopdig(1); /* shk might snatch pack */
+                   /* handle earlier damage, eg breaking wand of digging */
+                   else if (!madeby_u) pay_for_damage("dig into", TRUE);
 
                    You("fall through...");
                    /* Earlier checks must ensure that the destination
@@ -599,7 +601,7 @@ int ttyp;
                    spoteffects(FALSE);
                }
            } else {
-               if (shopdoor && madeby_u) pay_for_damage("ruin");
+               if (shopdoor && madeby_u) pay_for_damage("ruin", FALSE);
                if (newobjs)
                    impact_drop((struct obj *)0, x, y, 0);
                if (mtmp) {
@@ -643,7 +645,8 @@ boolean pit_only;
        boolean nohole = !Can_dig_down(&u.uz);
 
        if ((ttmp && (ttmp->ttyp == MAGIC_PORTAL || nohole)) ||
-          (IS_WALL(lev->typ) && (lev->wall_info & W_NONDIGGABLE) != 0)) {
+          (IS_ROCK(lev->typ) && lev->typ != SDOOR &&
+           (lev->wall_info & W_NONDIGGABLE) != 0)) {
                pline_The("%s here is too hard to dig in.", surface(u.ux,u.uy));
 
        } else if (is_pool(u.ux, u.uy) || is_lava(u.ux, u.uy)) {
@@ -1261,7 +1264,7 @@ zap_dig()
        } /* while */
        tmp_at(DISP_END,0);     /* closing call */
        if (shopdoor || shopwall)
-           pay_for_damage(shopdoor ? "destroy" : "dig into");
+           pay_for_damage(shopdoor ? "destroy" : "dig into", FALSE);
        return;
 }
 
index 5de4508b2c8b760f74d3231ea5d2e6d9ea7a253b..a37fe27e79b4a7497d1104d533d1ae6ed406e44f 100644 (file)
@@ -541,8 +541,15 @@ xchar x, y;
        }
 
        /* the object might have fallen down a hole */
-       if (kickobj->where == OBJ_MIGRATING)
+       if (kickobj->where == OBJ_MIGRATING) {
+           if (costly) {
+               if(isgold)
+                   costly_gold(x, y, kickobj->quan);
+               else (void)stolen_value(kickobj, x, y,
+                                       (boolean)shkp->mpeaceful, FALSE);
+           }
            return 1;
+       }
 
        bhitroom = *in_rooms(bhitpos.x, bhitpos.y, SHOPBASE);
        if (costly && (!costly_spot(bhitpos.x, bhitpos.y) ||
@@ -1014,7 +1021,7 @@ dumb:
                unblock_point(x,y);             /* vision */
                if (shopdoor) {
                    add_damage(x, y, 400L);
-                   pay_for_damage("break");
+                   pay_for_damage("break", FALSE);
                }
                if (in_town(x, y))
                  for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
index 543b199d0df05e3cff3b0b6d4902cd274757d9d2..5413bdf8fa2533f054394006b5a3ebad3737d9b9 100644 (file)
@@ -367,7 +367,8 @@ int expltype;
        if (shopdamage) {
                pay_for_damage(adtyp == AD_FIRE ? "burn away" :
                               adtyp == AD_COLD ? "shatter" :
-                              adtyp == AD_DISN ? "disintegrate" : "destroy");
+                              adtyp == AD_DISN ? "disintegrate" : "destroy",
+                              FALSE);
        }
 
        /* explosions are noisy */
index 9afbb169b3251ec894c514418b63a21806783e6f..0e366318a09a37190a2ebc41f788eec1382fd64b 100644 (file)
@@ -422,7 +422,7 @@ still_chewing(x,y)
     unblock_point(x, y);       /* vision */
     newsym(x, y);
     if (digtxt) You(digtxt);   /* after newsym */
-    if (dmgtxt) pay_for_damage(dmgtxt);
+    if (dmgtxt) pay_for_damage(dmgtxt, FALSE);
     (void) memset((genericptr_t)&digging, 0, sizeof digging);
     return 0;
 }
index caf38a3c7203c6c64bcb852022a1853fc6fd5b70..15429ec3540e9aa4715b980782ef774d18d6f9a9 100644 (file)
--- a/src/shk.c
+++ b/src/shk.c
@@ -3410,8 +3410,9 @@ coord *mm;
 #endif /* KOPS */
 
 void
-pay_for_damage(dmgstr)
+pay_for_damage(dmgstr, cant_mollify)
 const char *dmgstr;
+boolean cant_mollify;
 {
        register struct monst *shkp = (struct monst *)0;
        char shops_affected[5];
@@ -3521,11 +3522,11 @@ const char *dmgstr;
            (void) mnearto(shkp, x, y, TRUE);
        }
 
-       if((um_dist(x, y, 1) && !uinshp) ||
+       if((um_dist(x, y, 1) && !uinshp) || cant_mollify ||
 #ifndef GOLDOBJ
-                       (u.ugold + ESHK(shkp)->credit) < cost_of_damage
+          (u.ugold + ESHK(shkp)->credit) < cost_of_damage
 #else
-                       (money_cnt(invent) + ESHK(shkp)->credit) < cost_of_damage
+          (money_cnt(invent) + ESHK(shkp)->credit) < cost_of_damage
 #endif
                                || !rn2(50)) {
                if(um_dist(x, y, 1) && !uinshp) {
index f26a300da7ce89907ab2dca6fbaa3cd425b2249b..062c2136bb20d22c2229c7d16484d3a9a3adc545 100644 (file)
@@ -283,9 +283,11 @@ register int x, y, typ;
            case TRAPDOOR:
                lev = &levl[x][y];
                if (*in_rooms(x, y, SHOPBASE) &&
-                       ((typ == HOLE || typ == TRAPDOOR) || IS_DOOR(lev->typ)))
+                       ((typ == HOLE || typ == TRAPDOOR) ||
+                        IS_DOOR(lev->typ) || IS_WALL(lev->typ)))
                    add_damage(x, y,            /* schedule repair */
-                       (IS_DOOR(lev->typ) && !flags.mon_moving) ? 200L : 0L);
+                              ((IS_DOOR(lev->typ) || IS_WALL(lev->typ))
+                               && !flags.mon_moving) ? 200L : 0L);
                lev->doormask = 0;      /* subsumes altarmask, icedpool... */
                if (IS_ROOM(lev->typ)) /* && !IS_AIR(lev->typ) */
                    lev->typ = ROOM;
index cabaf61c9ba98947d04793f5972620877d70beab..bab3b5a02b81d7c13264be8f182b8e22a1ac95b0 100644 (file)
--- a/src/zap.c
+++ b/src/zap.c
@@ -2783,7 +2783,7 @@ struct obj *obj;                  /* object tossed/used */
        if (weapon != ZAPPED_WAND && weapon != INVIS_BEAM) tmp_at(DISP_END, 0);
 
        if(shopdoor)
-           pay_for_damage("destroy");
+           pay_for_damage("destroy", FALSE);
 
        return (struct monst *)0;
 }
@@ -3456,7 +3456,7 @@ register int dx,dy;
     if (shopdamage)
        pay_for_damage(abstype == ZT_FIRE ?  "burn away" :
                       abstype == ZT_COLD ?  "shatter" :
-                      abstype == ZT_DEATH ? "disintegrate" : "destroy");
+                      abstype == ZT_DEATH ? "disintegrate" : "destroy", FALSE);
     bhitpos = save_bhitpos;
 }
 #endif /*OVLB*/