fix #H7103 - shop pricing

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.)
This commit is contained in:
PatR
2018-12-27 14:12:48 -08:00
parent f8b4ad3fdc
commit a6b4322034
4 changed files with 47 additions and 7 deletions
+2
View 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 prevent achievement luckstone from merging with other luckstones if kicked or
dropped by monster (not applicable for dropped by player; achievement dropped by monster (not applicable for dropped by player; achievement
would have been recorded and luckstone reverted to normal if picked up) 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 Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
+2 -1
View 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. */ /* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */ /* 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(check_unpaid, (struct obj *));
E void FDECL(costly_gold, (XCHAR_P, XCHAR_P, long)); E void FDECL(costly_gold, (XCHAR_P, XCHAR_P, long));
E long FDECL(get_cost_of_shop_item, (struct obj *)); 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_door, (XCHAR_P, XCHAR_P));
E boolean FDECL(block_entry, (XCHAR_P, XCHAR_P)); E boolean FDECL(block_entry, (XCHAR_P, XCHAR_P));
E char *FDECL(shk_your, (char *, struct obj *)); E char *FDECL(shk_your, (char *, struct obj *));
+23 -4
View 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) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Derek S. Ray, 2015. */ /*-Copyright (c) Derek S. Ray, 2015. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -6,6 +6,7 @@
#include "hack.h" #include "hack.h"
STATIC_DCL void FDECL(mkbox_cnts, (struct obj *)); 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(maybe_adjust_light, (struct obj *, int));
STATIC_DCL void FDECL(obj_timer_checks, (struct obj *, STATIC_DCL void FDECL(obj_timer_checks, (struct obj *,
XCHAR_P, XCHAR_P, int)); XCHAR_P, XCHAR_P, int));
@@ -436,9 +437,7 @@ long num;
otmp = newobj(); otmp = newobj();
*otmp = *obj; /* copies whole structure */ *otmp = *obj; /* copies whole structure */
otmp->oextra = (struct oextra *) 0; otmp->oextra = (struct oextra *) 0;
otmp->o_id = context.ident++; otmp->o_id = nextoid(obj, otmp);
if (!otmp->o_id)
otmp->o_id = context.ident++; /* ident overflowed */
otmp->timed = 0; /* not timed, yet */ otmp->timed = 0; /* not timed, yet */
otmp->lamplit = 0; /* ditto */ otmp->lamplit = 0; /* ditto */
otmp->owornmask = 0L; /* new object isn't worn */ otmp->owornmask = 0L; /* new object isn't worn */
@@ -466,6 +465,26 @@ long num;
return otmp; 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; /* try to find the stack obj was split from, then merge them back together;
returns the combined object if unsplit is successful, null otherwise */ returns the combined object if unsplit is successful, null otherwise */
struct obj * struct obj *
+20 -2
View File
@@ -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) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */ /*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -1984,6 +1984,24 @@ register struct obj *obj;
return cost; 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 */ /* calculate the value that the shk will charge for [one of] an object */
STATIC_OVL long STATIC_OVL long
get_cost(obj, shkp) get_cost(obj, shkp)
@@ -2043,7 +2061,7 @@ register struct monst *shkp; /* if angry, impose a surcharge */
break; break;
} }
tmp = (long) objects[i].oc_cost; 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 */ /* unid'd, arbitrarily impose surcharge: tmp *= 4/3 */
multiplier *= 4L; multiplier *= 4L;
divisor *= 3L; divisor *= 3L;