]> granicus.if.org Git - nethack/commitdiff
fix #H7103 - shop pricing
authorPatR <rankin@nethack.org>
Thu, 27 Dec 2018 22:12:48 +0000 (14:12 -0800)
committerPatR <rankin@nethack.org>
Thu, 27 Dec 2018 22:12:48 +0000 (14:12 -0800)
Player came across a stack of 2 gray stones in a shop and kicked one.
That one ended up with a different (in his case, lower) price once it
was separate.  This behavior only applies to non-glass gems which add
a price variation derived from internal ID (obj->o_id) number.  Make
splitting stacks always yield the same price per item in the new stack
as was being charged in the old stack by choosing a similar o_id.  Do
it for all splits (that can vary price by ID, so just non-glass gems),
not just ones performed inside shops.

He picked up the lower priced one and dropped it back on the original
higher priced one; the combined stack took on the lower price.  That
will no longer happen if they come from splitting a stack, but this
fix doesn't address merging with different prices when they start out
as separate stacks.  (Unpaid items won't merge in inventory if prices
are different, but shop-owned items will merge on floor.)

doc/fixes36.2
include/extern.h
src/mkobj.c
src/shk.c

index 34da7b77b962187aa705886619371fe46d3ebe72..ffc70c885d212dd2ca4fd4fad6455478fc5b93f0 100644 (file)
@@ -312,6 +312,8 @@ looking into an applied container with ':' showed prices of unpaid items but
 prevent achievement luckstone from merging with other luckstones if kicked or
        dropped by monster (not applicable for dropped by player; achievement
        would have been recorded and luckstone reverted to normal if picked up)
+when splitting a stack of gems where internal ID is used to make adjustment to
+       shop prices, pick an ID for new stack that yields same prices as old
 
 
 Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
index 7a239f127fefbc3bddd67489f7891b7a4f9c09df..28f671b1d30f1dc06fbd7a8e94c39378b60ed9d9 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 extern.h        $NHDT-Date: 1545597403 2018/12/23 20:36:43 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.676 $ */
+/* NetHack 3.6 extern.h        $NHDT-Date: 1545948751 2018/12/27 22:12:31 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.677 $ */
 /* Copyright (c) Steve Creps, 1988.                              */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -2248,6 +2248,7 @@ E void FDECL(check_unpaid_usage, (struct obj *, BOOLEAN_P));
 E void FDECL(check_unpaid, (struct obj *));
 E void FDECL(costly_gold, (XCHAR_P, XCHAR_P, long));
 E long FDECL(get_cost_of_shop_item, (struct obj *));
+E int FDECL(oid_price_adjustment, (struct obj *, unsigned));
 E boolean FDECL(block_door, (XCHAR_P, XCHAR_P));
 E boolean FDECL(block_entry, (XCHAR_P, XCHAR_P));
 E char *FDECL(shk_your, (char *, struct obj *));
index 50140fe1fb23ed7efb5a509b2f72ae03c7346706..c1bce84a83254e36d01314bdb53bf857fed80e8e 100644 (file)
@@ -1,4 +1,4 @@
-/* NetHack 3.6 mkobj.c $NHDT-Date: 1545597425 2018/12/23 20:37:05 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.137 $ */
+/* NetHack 3.6 mkobj.c $NHDT-Date: 1545948759 2018/12/27 22:12:39 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.138 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Derek S. Ray, 2015. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -6,6 +6,7 @@
 #include "hack.h"
 
 STATIC_DCL void FDECL(mkbox_cnts, (struct obj *));
+STATIC_DCL unsigned FDECL(nextoid, (struct obj *, struct obj *));
 STATIC_DCL void FDECL(maybe_adjust_light, (struct obj *, int));
 STATIC_DCL void FDECL(obj_timer_checks, (struct obj *,
                                          XCHAR_P, XCHAR_P, int));
@@ -436,9 +437,7 @@ long num;
     otmp = newobj();
     *otmp = *obj; /* copies whole structure */
     otmp->oextra = (struct oextra *) 0;
-    otmp->o_id = context.ident++;
-    if (!otmp->o_id)
-        otmp->o_id = context.ident++; /* ident overflowed */
+    otmp->o_id = nextoid(obj, otmp);
     otmp->timed = 0;                  /* not timed, yet */
     otmp->lamplit = 0;                /* ditto */
     otmp->owornmask = 0L;             /* new object isn't worn */
@@ -466,6 +465,26 @@ long num;
     return otmp;
 }
 
+/* when splitting a stack that has o_id-based shop prices (non-glass gems),
+   pick an o_id value for the new stack that will maintain the same price */
+STATIC_OVL unsigned
+nextoid(oldobj, newobj)
+struct obj *oldobj, *newobj;
+{
+    int olddif, newdif, trylimit = 256; /* limit of 4 suffices at present */
+    unsigned oid = context.ident - 1; /* loop increment will reverse -1 */
+
+    olddif = oid_price_adjustment(oldobj, oldobj->o_id);
+    do {
+        ++oid;
+        if (!oid) /* avoid using 0 (in case value wrapped) */
+            ++oid;
+        newdif = oid_price_adjustment(newobj, oid);
+    } while (newdif != olddif && --trylimit >= 0);
+    context.ident = oid + 1; /* ready for next new object */
+    return oid;
+}
+
 /* try to find the stack obj was split from, then merge them back together;
    returns the combined object if unsplit is successful, null otherwise */
 struct obj *
index 40c58adb552e5b1351d7bbce3ff70f2c0121a2c8..746afb522525832d6a7985bf687247eef897d98b 100644 (file)
--- a/src/shk.c
+++ b/src/shk.c
@@ -1,4 +1,4 @@
-/* NetHack 3.6 shk.c   $NHDT-Date: 1545786461 2018/12/26 01:07:41 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.147 $ */
+/* NetHack 3.6 shk.c   $NHDT-Date: 1545948761 2018/12/27 22:12:41 $  $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.148 $ */
 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
 /*-Copyright (c) Robert Patrick Rankin, 2012. */
 /* NetHack may be freely redistributed.  See license for details. */
@@ -1984,6 +1984,24 @@ register struct obj *obj;
     return cost;
 }
 
+/* decide whether to apply a surcharge (or hypothetically, a discount) to obj
+   if it had ID number 'oid'; returns 1: increase, 0: normal, -1: decrease */
+int
+oid_price_adjustment(obj, oid)
+struct obj *obj;
+unsigned oid;
+{
+    int res = 0, otyp = obj->otyp;
+
+    /* currently only used for non-glass gems */
+    if (obj->oclass == GEM_CLASS && otyp != ROCK
+        && !(obj->dknown && objects[otyp].oc_name_known)
+        && objects[otyp].oc_material != GLASS) {
+        res = ((oid % 4) == 0); /* id%4 ==0 -> +1, ==1..3 -> 0 */
+    }
+    return res;
+}
+
 /* calculate the value that the shk will charge for [one of] an object */
 STATIC_OVL long
 get_cost(obj, shkp)
@@ -2043,7 +2061,7 @@ register struct monst *shkp; /* if angry, impose a surcharge */
                 break;
             }
             tmp = (long) objects[i].oc_cost;
-        } else if (!(obj->o_id % 4)) {
+        } else if (oid_price_adjustment(obj, obj->o_id) > 0) {
             /* unid'd, arbitrarily impose surcharge: tmp *= 4/3 */
             multiplier *= 4L;
             divisor *= 3L;