From 0e583161094b417eb64e5c3b02fb91f854fe7ebb Mon Sep 17 00:00:00 2001 From: PatR Date: Fri, 21 Dec 2018 01:14:45 -0800 Subject: [PATCH] fix #H2680 - IDing unpaid gem should adjust price Another one from 6.5 years ago, identifying a type of gem should give a new price for any unpaid gems of that type and adjust shopping bill accordingly. Report was for rubbing with touchstone and learning worthless glass with price not changing until the learned 'gem' was dropped. Fix works for that and also other forms of identification (and for amnesia, raising prices of forgotten gems); no dropping is required for the price to change. Theoretically could apply to any type of item, but prices of gems are by far the most sensitive to whether or not they're identified. --- doc/fixes36.2 | 2 ++ include/extern.h | 3 ++- src/o_init.c | 10 ++++++++-- src/shk.c | 41 ++++++++++++++++++++++++++++++++++++++++- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index b080b417d..e9484a622 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -295,6 +295,8 @@ if hero kicks some embedded gold out of a wall while following vault gaurd the gold" unless he's on brink of going ballistic for '/?' information lookup, "item named The Artifact" failed to find info about "Artifact" due to presence of "The" +identifying or forgetting gem types now adjusts prices for gems already on + shopping bill Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository diff --git a/include/extern.h b/include/extern.h index bd0255c2a..78c7647da 100644 --- a/include/extern.h +++ b/include/extern.h @@ -1,4 +1,4 @@ -/* NetHack 3.6 extern.h $NHDT-Date: 1545182146 2018/12/19 01:15:46 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.674 $ */ +/* NetHack 3.6 extern.h $NHDT-Date: 1545383614 2018/12/21 09:13:34 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.675 $ */ /* Copyright (c) Steve Creps, 1988. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2220,6 +2220,7 @@ E long FDECL(contained_cost, (struct obj *, struct monst *, long, BOOLEAN_P, BOOLEAN_P)); E long FDECL(contained_gold, (struct obj *)); E void FDECL(picked_container, (struct obj *)); +E void FDECL(gem_learned, (int)); E void FDECL(alter_cost, (struct obj *, long)); E long FDECL(unpaid_cost, (struct obj *, BOOLEAN_P)); E boolean FDECL(billable, (struct monst **, struct obj *, CHAR_P, BOOLEAN_P)); diff --git a/src/o_init.c b/src/o_init.c index b4fc440ee..b2d28f50e 100644 --- a/src/o_init.c +++ b/src/o_init.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 o_init.c $NHDT-Date: 1528332336 2018/06/07 00:45:36 $ $NHDT-Branch: NetHack-3.6.2 $:$NHDT-Revision: 1.24 $ */ +/* NetHack 3.6 o_init.c $NHDT-Date: 1545383615 2018/12/21 09:13:35 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.25 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2011. */ /* NetHack may be freely redistributed. See license for details. */ @@ -362,8 +362,11 @@ boolean credit_hero; exercise(A_WIS, TRUE); } /* moves==1L => initial inventory, gameover => final disclosure */ - if (moves > 1L && !program_state.gameover) + if (moves > 1L && !program_state.gameover) { + if (objects[oindx].oc_class == GEM_CLASS) + gem_learned(oindx); /* could affect price of unpaid gems */ update_inventory(); + } } } @@ -390,6 +393,9 @@ register int oindx; disco[dindx - 1] = 0; else impossible("named object not in disco"); + + if (objects[oindx].oc_class == GEM_CLASS) + gem_learned(oindx); /* ok, it's actually been unlearned */ update_inventory(); } } diff --git a/src/shk.c b/src/shk.c index 1a50616e9..315de4c1d 100644 --- a/src/shk.c +++ b/src/shk.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 shk.c $NHDT-Date: 1545036290 2018/12/17 08:44:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.143 $ */ +/* NetHack 3.6 shk.c $NHDT-Date: 1545383616 2018/12/21 09:13:36 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.144 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */ /* NetHack may be freely redistributed. See license for details. */ @@ -2278,6 +2278,45 @@ register struct monst *shkp; return tmp; } +/* unlike alter_cost() which operates on a specific item, identifying or + forgetting a gem causes all unpaid gems of its type to change value */ +void +gem_learned(oindx) +int oindx; +{ + struct obj *obj; + struct monst *shkp; + struct bill_x *bp; + int ct; + + /* + * Unfortunately, shop bill doesn't have object type included, + * just obj->oid for each unpaid stack, so we have to go through + * every bill and every item on that bill and match up against + * every unpaid stack on the level.... + * + * Fortunately, there's no need to catch up when changing dungeon + * levels even if we ID'd or forget some gems while gone from a + * level. There won't be any shop bills when arriving; they were + * either paid before leaving or got treated as robbery and it's + * too late to adjust pricing. + */ + for (shkp = next_shkp(fmon, TRUE); shkp; + shkp = next_shkp(shkp->nmon, TRUE)) { + ct = ESHK(shkp)->billct; + bp = ESHK(shkp)->bill; + while (--ct >= 0) { + obj = find_oid(bp->bo_id); + if (!obj) /* shouldn't happen */ + continue; + if ((oindx != STRANGE_OBJECT) ? (obj->otyp == oindx) + : (obj->oclass == GEM_CLASS)) + bp->price = get_cost(obj, shkp); + ++bp; + } + } +} + /* called when an item's value has been enhanced; if it happens to be on any shop bill, update that bill to reflect the new higher price [if the new price drops for some reason, keep the old one in place] */