diff --git a/doc/fixes37.0 b/doc/fixes37.0 index fbd016ffa..9e712a198 100644 --- a/doc/fixes37.0 +++ b/doc/fixes37.0 @@ -1,4 +1,4 @@ -NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.362 $ $NHDT-Date: 1606243387 2020/11/24 18:43:07 $ +NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.363 $ $NHDT-Date: 1606343573 2020/11/25 22:32:53 $ General Fixes and Modified Features ----------------------------------- @@ -308,6 +308,9 @@ wand/scroll of create monster or bag of tricks that makes a new monster which wizard mode (only way to get timed flying): if levitation and flying time out on same turn, player was told "You have stopped levitating and are now flying."; status line wasn't updated to remove stale Fly condition +throwing or kicking a shop container (that's light enough to move) made the + hero pay for any gold inside, then didn't refund that amount if the + container landed inside the shop Fixes to 3.7.0-x Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index 4ea7e7575..0147a619d 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.7 extern.h $NHDT-Date: 1606008997 2020/11/22 01:36:37 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.880 $ */ +/* NetHack 3.7 extern.h $NHDT-Date: 1606343573 2020/11/25 22:32:53 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.882 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2406,8 +2406,9 @@ E boolean FDECL(billable, (struct monst **, struct obj *, CHAR_P, BOOLEAN_P)); E void FDECL(addtobill, (struct obj *, BOOLEAN_P, BOOLEAN_P, BOOLEAN_P)); E void FDECL(splitbill, (struct obj *, struct obj *)); E void FDECL(subfrombill, (struct obj *, struct monst *)); -E long FDECL(stolen_value, - (struct obj *, XCHAR_P, XCHAR_P, BOOLEAN_P, BOOLEAN_P)); +E long FDECL(stolen_value, (struct obj *, XCHAR_P, XCHAR_P, + BOOLEAN_P, BOOLEAN_P)); +E void FDECL(donate_gold, (long, struct monst *, BOOLEAN_P)); E void FDECL(sellobj_state, (int)); E void FDECL(sellobj, (struct obj *, XCHAR_P, XCHAR_P)); E int FDECL(doinvbill, (int)); diff --git a/src/dokick.c b/src/dokick.c index 65cb6f4e6..114a217b8 100644 --- a/src/dokick.c +++ b/src/dokick.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dokick.c $NHDT-Date: 1606009001 2020/11/22 01:36:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.159 $ */ +/* NetHack 3.7 dokick.c $NHDT-Date: 1606343576 2020/11/25 22:32:56 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.160 $ */ /* Copyright (c) Izchak Miller, Mike Stephenson, Steve Linhart, 1989. */ /* NetHack may be freely redistributed. See license for details. */ @@ -508,7 +508,8 @@ xchar x, y; } if (!uarmf && g.kickedobj->otyp == CORPSE - && touch_petrifies(&mons[g.kickedobj->corpsenm]) && !Stone_resistance) { + && touch_petrifies(&mons[g.kickedobj->corpsenm]) + && !Stone_resistance) { You("kick %s with your bare %s.", corpse_xname(g.kickedobj, (const char *) 0, CXN_PFX_THE), makeplural(body_part(FOOT))); @@ -705,12 +706,23 @@ xchar x, y; else (void) stolen_value(g.kickedobj, x, y, (boolean) shkp->mpeaceful, FALSE); + costly = FALSE; /* already billed */ } if (flooreffects(g.kickedobj, g.bhitpos.x, g.bhitpos.y, "fall")) return 1; - if (g.kickedobj->unpaid) - subfrombill(g.kickedobj, shkp); + if (costly) { + long gt = 0L; + + /* costly + landed outside shop handled above; must be inside shop */ + if (g.kickedobj->unpaid) + subfrombill(g.kickedobj, shkp); + + /* if billed for contained gold during kick, get a refund now */ + if (Has_contents(g.kickedobj) + && (gt = contained_gold(g.kickedobj, TRUE)) > 0L) + donate_gold(gt, shkp, FALSE); + } place_object(g.kickedobj, g.bhitpos.x, g.bhitpos.y); stackobj(g.kickedobj); newsym(g.kickedobj->ox, g.kickedobj->oy); @@ -1723,7 +1735,8 @@ unsigned long deliverflags; continue; if (otmp->migr_species != NON_PM - && (mtmp->data->mflags2 & DELIVER_PM) == (unsigned) otmp->migr_species) { + && ((mtmp->data->mflags2 & DELIVER_PM) + == (unsigned) otmp->migr_species)) { obj_extract_self(otmp); otmp->owornmask = 0L; otmp->ox = otmp->oy = 0; @@ -1777,7 +1790,8 @@ long num; if (nodrop) Sprintf(eos(xbuf), "."); else - Sprintf(eos(xbuf), " and %s %s.", otense(otmp, "fall"), g.gate_str); + Sprintf(eos(xbuf), " and %s %s.", + otense(otmp, "fall"), g.gate_str); pline("%s%s", obuf, xbuf); } else if (!nodrop) pline("%s %s %s.", obuf, otense(otmp, "fall"), g.gate_str); diff --git a/src/dothrow.c b/src/dothrow.c index 6719dc9d8..f3015bfd1 100644 --- a/src/dothrow.c +++ b/src/dothrow.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 dothrow.c $NHDT-Date: 1596498161 2020/08/03 23:42:41 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.188 $ */ +/* NetHack 3.7 dothrow.c $NHDT-Date: 1606343578 2020/11/25 22:32:58 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.190 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ @@ -935,10 +935,15 @@ boolean broken; /* ushops0: in case we threw while levitating and recoiled out of shop (most likely to the shk's spot in front of door) */ if (*oshops == *u.ushops || *oshops == *u.ushops0) { - if (is_unpaid(obj)) + if (is_unpaid(obj)) { + long gt = Has_contents(obj) ? contained_gold(obj, TRUE) : 0L; + subfrombill(obj, shkp); - else if (x != shkp->mx || y != shkp->my) + if (gt > 0L) + donate_gold(gt, shkp, TRUE); + } else if (x != shkp->mx || y != shkp->my) { sellobj(obj, x, y); + } } } } diff --git a/src/mkobj.c b/src/mkobj.c index 71ef55a88..4c1b810bb 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 mkobj.c $NHDT-Date: 1596498183 2020/08/03 23:43:03 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.186 $ */ +/* NetHack 3.7 mkobj.c $NHDT-Date: 1606343579 2020/11/25 22:32:59 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Derek S. Ray, 2015. */ /* NetHack may be freely redistributed. See license for details. */ @@ -633,9 +633,7 @@ register struct obj *otmp; *dummy = *otmp; dummy->oextra = (struct oextra *) 0; dummy->where = OBJ_FREE; - dummy->o_id = g.context.ident++; - if (!dummy->o_id) - dummy->o_id = g.context.ident++; /* ident overflowed */ + dummy->o_id = nextoid(otmp, dummy); dummy->timed = 0; copy_oextra(dummy, otmp); if (has_omid(dummy)) @@ -647,8 +645,8 @@ register struct obj *otmp; if (cost) alter_cost(dummy, -cost); /* no_charge is only valid for some locations */ - otmp->no_charge = - (otmp->where == OBJ_FLOOR || otmp->where == OBJ_CONTAINED) ? 1 : 0; + otmp->no_charge = (otmp->where == OBJ_FLOOR + || otmp->where == OBJ_CONTAINED) ? 1 : 0; otmp->unpaid = 0; return; } diff --git a/src/shk.c b/src/shk.c index 5ad0fb07a..64afd3207 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.7 shk.c $NHDT-Date: 1606009003 2020/11/22 01:36:43 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.191 $ */ +/* NetHack 3.7 shk.c $NHDT-Date: 1606343581 2020/11/25 22:33:01 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.192 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -3003,6 +3003,44 @@ boolean peaceful, silent; return value; } +/* opposite of costly_gold(); hero has dropped gold in a shop; + called from sellobj(); ought to be called from subfrombill() too */ +void +donate_gold(gltmp, shkp, selling) +long gltmp; +struct monst *shkp; +boolean selling; /* True: dropped in shop; False: kicked and landed in shop */ +{ + struct eshk *eshkp = ESHK(shkp); + + if (eshkp->debit >= gltmp) { + if (eshkp->loan) { /* you carry shop's gold */ + if (eshkp->loan > gltmp) + eshkp->loan -= gltmp; + else + eshkp->loan = 0L; + } + eshkp->debit -= gltmp; + Your("debt is %spaid off.", eshkp->debit ? "partially " : ""); + } else { + long delta = gltmp - eshkp->debit; + + eshkp->credit += delta; + if (eshkp->debit) { + eshkp->debit = 0L; + eshkp->loan = 0L; + Your("debt is paid off."); + } + if (eshkp->credit == delta) + You("have %sestablished %ld %s credit.", + !selling ? "re-" : "", delta, currency(delta)); + else + pline("%ld %s added%s to your credit; total is now %ld %s.", + delta, currency(delta), !selling ? " back" : "", + eshkp->credit, currency(eshkp->credit)); + } +} + void sellobj_state(deliberate) int deliberate; @@ -3088,7 +3126,7 @@ xchar x, y; return; } - if (eshkp->robbed) { /* shkp is not angry? */ + if (eshkp->robbed) { /* bones; shop robbed by previous customer */ if (isgold) offer = obj->quan; else if (cgold) @@ -3106,32 +3144,7 @@ xchar x, y; if (!cgold) gltmp = obj->quan; - if (eshkp->debit >= gltmp) { - if (eshkp->loan) { /* you carry shop's gold */ - if (eshkp->loan >= gltmp) - eshkp->loan -= gltmp; - else - eshkp->loan = 0L; - } - eshkp->debit -= gltmp; - Your("debt is %spaid off.", eshkp->debit ? "partially " : ""); - } else { - long delta = gltmp - eshkp->debit; - - eshkp->credit += delta; - if (eshkp->debit) { - eshkp->debit = 0L; - eshkp->loan = 0L; - Your("debt is paid off."); - } - if (eshkp->credit == delta) - You("have established %ld %s credit.", delta, - currency(delta)); - else - pline("%ld %s added to your credit; total is now %ld %s.", - delta, currency(delta), eshkp->credit, - currency(eshkp->credit)); - } + donate_gold(gltmp, shkp, TRUE); if (!offer || g.sell_how == SELL_DONTSELL) { if (!isgold) {