diff --git a/include/extern.h b/include/extern.h index b2d15cb0d..d3ef197b9 100644 --- a/include/extern.h +++ b/include/extern.h @@ -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 *); diff --git a/src/do.c b/src/do.c index f5abe2537..1eb6581e9 100644 --- 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; diff --git a/src/hack.c b/src/hack.c index 9449529cd..2a6acc237 100644 --- a/src/hack.c +++ b/src/hack.c @@ -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)); diff --git a/src/shk.c b/src/shk.c index e78e7a01d..866e2aebc 100644 --- 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;