fix #K3016 - kicking a bag of gold in a shop
Kicking a container that had gold in it took the gold amount away from hero's credit or added to hero's debt, then didn't give a refund if the container and its gold landed within the shop. Throwing behaved likewise, just less verbosely. The problem is caused by addtobill() treating gold specially and then subfrombill() not being able to perform a reverse operation. Actually, it may be possible for subfrombill() to do that, but verifying all its uses is too much work. This moves the gold handling for drop+selling into its own routine and adds calls to that for the throwing and kicking refunds. The other calls to subfrombill() outside of shk.c appear to be ok as-is. (The calls inside that file are the ones that still need evaluation if the gold handling is to move to there.) bill_dummy_object() now uses the same o_id assignment for its dummy object as split_object() does for its new partial stack. I don't know whether the old code led to any price glitches.
This commit is contained in:
69
src/shk.c
69
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) {
|
||||
|
||||
Reference in New Issue
Block a user