]> granicus.if.org Git - nethack/commitdiff
Charge hero for making off with shop-owned boulder
authorMichael Meyer <me@entrez.cc>
Mon, 14 Nov 2022 19:59:29 +0000 (14:59 -0500)
committerPatR <rankin@nethack.org>
Sat, 19 Nov 2022 08:13:13 +0000 (00:13 -0800)
Pushing a shop-owned boulder out of the shop wouldn't charge the hero
anything.  Remedy this (and remove the boulder from the bill if the hero
then pushes it back in).  Also tried to handle a couple other uncharged
boulder "theft" scenarios: pushing a boulder into lava or water, into a
trapdoor or hole, or into a level teleporter (various other traps
already charged for the boulder -- it was pretty inconsistent).

I externified onbill() for this, since relying on otmp->unpaid by itself
impossibles if you push a boulder through a gap in a wall between two
adjoining shops.

include/extern.h
src/do.c
src/hack.c
src/shk.c

index b2d15cb0de35e2a10cb01763a8c3ac95c16f5400..d3ef197b9bcbfc8a93b11874040044381800f98c 100644 (file)
@@ -2481,6 +2481,7 @@ extern void shopper_financial_report(void);
 extern int inhishop(struct monst *);
 extern struct monst *shop_keeper(char);
 extern boolean tended_shop(struct mkroom *);
+struct bill_x *onbill(struct obj *, struct monst *, boolean);
 extern boolean is_unpaid(struct obj *);
 extern void delete_contents(struct obj *);
 extern void obfree(struct obj *, struct obj *);
index f5abe25371f2ab8293fc06a2c52b1ec9c03852a3..1eb6581e9dafd87ce233bf06555375704eb4274d 100644 (file)
--- a/src/do.c
+++ b/src/do.c
@@ -134,7 +134,7 @@ boulder_hits_pool(
 
         /* boulder is now gone */
         if (pushing)
-            delobj(otmp);
+            useupf(otmp, otmp->quan);
         else
             obfree(otmp, (struct obj *) 0);
         return TRUE;
index 9449529cd08c0c0ca4ba0d978e6fc90b08be7a7c..2a6acc23705e8a2a60b80ce1102299a81489e019 100644 (file)
@@ -154,9 +154,9 @@ moverock(void)
     register coordxy rx, ry, sx, sy;
     struct obj *otmp;
     struct trap *ttmp;
-    struct monst *mtmp;
+    struct monst *mtmp, *shkp;
     const char *what;
-    boolean firstboulder = TRUE;
+    boolean costly, firstboulder = TRUE;
     int res = 0;
 
     sx = u.ux + u.dx, sy = u.uy + u.dy; /* boulder starting position */
@@ -243,6 +243,8 @@ moverock(void)
                 || doorless_door(rx, ry)) && !sobj_at(BOULDER, rx, ry)) {
             ttmp = t_at(rx, ry);
             mtmp = m_at(rx, ry);
+            costly = (!otmp->no_charge && costly_spot(sx, sy)
+                      && shop_keeper(*in_rooms(sx, sy, SHOPBASE)));
 
             /* KMH -- Sokoban doesn't let you push boulders diagonally */
             if (Sokoban && u.dx && u.dy) {
@@ -353,7 +355,7 @@ moverock(void)
                               (ttmp->ttyp == TRAPDOOR) ? "trap door" : "hole",
                               surface(rx, ry));
                     deltrap(ttmp);
-                    delobj(otmp);
+                    useupf(otmp, 1L);
                     bury_objs(rx, ry);
                     levl[rx][ry].wall_info &= ~W_NONDIGGABLE;
                     levl[rx][ry].candig = 1;
@@ -380,6 +382,8 @@ moverock(void)
                     if (ttmp->ttyp == TELEP_TRAP) {
                         (void) rloco(otmp);
                     } else {
+                        if (costly)
+                            addtobill(otmp, FALSE, FALSE, FALSE);
                         obj_extract_self(otmp);
                         add_to_migration(otmp);
                         get_level(&dest, newlev);
@@ -444,6 +448,14 @@ moverock(void)
             } else {
                 newsym(sx, sy);
             }
+            /* maybe adjust bill if boulder was pushed across shop boundary */
+            if (costly && !costly_spot(rx, ry)) {
+                addtobill(otmp, FALSE, FALSE, FALSE);
+            } else if (!costly && costly_spot(rx, ry) && otmp->unpaid
+                       && (shkp = shop_keeper(*in_rooms(rx, ry, SHOPBASE)))
+                       && onbill(otmp, shkp, TRUE)) {
+                subfrombill(otmp, shkp);
+            }
         } else {
  nopushmsg:
             what = the(xname(otmp));
index e78e7a01d7f66382275c6343ee5c6b298905e27f..866e2aebc89b51e2a07eeec7aa065ac3aebb17c2 100644 (file)
--- a/src/shk.c
+++ b/src/shk.c
@@ -29,7 +29,6 @@ static const char the_contents_of[] = "the contents of ";
 static void append_honorific(char *);
 static long addupbill(struct monst *);
 static void pacify_shk(struct monst *, boolean);
-static struct bill_x *onbill(struct obj *, struct monst *, boolean);
 static struct monst *next_shkp(struct monst *, boolean);
 static long shop_debt(struct eshk *);
 static char *shk_owns(char *, struct obj *);
@@ -868,8 +867,8 @@ tended_shop(struct mkroom* sroom)
     return !mtmp ? FALSE : (boolean) inhishop(mtmp);
 }
 
-static struct bill_x *
-onbill(struct obj* obj, struct monst* shkp, boolean silent)
+struct bill_x *
+onbill(struct obj *obj, struct monst *shkp, boolean silent)
 {
     if (shkp) {
         register struct bill_x *bp = ESHK(shkp)->bill_p;