From 0e464398142417dc91b9f156d9fd74aaf4563fd9 Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 4 Jul 2024 14:19:40 -0700 Subject: [PATCH] fix add_one_tobill() 'fixme' Not exhaustively tested. --- src/mkobj.c | 4 ++-- src/shk.c | 40 ++++++++++++++++++++++++---------------- 2 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/mkobj.c b/src/mkobj.c index 93f762c26..6b0e518d8 100644 --- a/src/mkobj.c +++ b/src/mkobj.c @@ -722,12 +722,12 @@ bill_dummy_object(struct obj *otmp) dummy->timed = 0; copy_oextra(dummy, otmp); if (has_omid(dummy)) - free_omid(dummy); /* only one association with m_id*/ + free_omid(dummy); /* only one association with m_id */ if (Is_candle(dummy)) dummy->lamplit = 0; dummy->owornmask = 0L; /* dummy object is not worn */ addtobill(dummy, FALSE, TRUE, TRUE); - if (cost) + if (cost && dummy->where != OBJ_DELETED) alter_cost(dummy, -cost); /* no_charge is only valid for some locations */ otmp->no_charge = (otmp->where == OBJ_FLOOR diff --git a/src/shk.c b/src/shk.c index bf82f1532..b2380e0f1 100644 --- a/src/shk.c +++ b/src/shk.c @@ -3213,35 +3213,43 @@ unpaid_cost( return amt; } +/* add 'obj' to 'shkp's bill */ staticfn void -add_one_tobill(struct obj *obj, boolean dummy, struct monst *shkp) +add_one_tobill( + struct obj *obj, + boolean dummy, /* True: obj is used up so goes on bill differently */ + struct monst *shkp) { struct eshk *eshkp; struct bill_x *bp; int bct; + boolean unbilled = FALSE; - if (!billable(&shkp, obj, *u.ushops, TRUE)) - return; eshkp = ESHK(shkp); - - if (eshkp->billct == BILLSZ) { - You("got that for free!"); - /* - * FIXME: - * What happens when this is a dummy object? It won't be on any - * object list. - */ - return; - } - /* normally bill_p gets set up whenever you enter the shop, but obj might be going onto the bill because hero just snagged it with a grappling hook from outside without ever having been inside */ if (!eshkp->bill_p) - eshkp->bill_p = &(eshkp->bill[0]); + eshkp->bill_p = &eshkp->bill[0]; + + if (!billable(&shkp, obj, *u.ushops, TRUE)) { + /* shk doesn't want it */ + unbilled = TRUE; + } else if (eshkp->billct == BILLSZ) { + /* shk's bill is completely full */ + You("got that for free!"); + unbilled = TRUE; + } + /* if not on any list (probably from bill_dummy_object() which creates + a new OBJ_FREE object), don't leave unmanaged object hanging around */ + if (unbilled) { + if (obj->where == OBJ_FREE) + dealloc_obj(obj); /* change to obj->where==OBJ_DELETED */ + return; + } bct = eshkp->billct; - bp = &(eshkp->bill_p[bct]); + bp = &eshkp->bill_p[bct]; bp->bo_id = obj->o_id; bp->bquan = obj->quan; if (dummy) { /* a dummy object must be inserted into */