calculating shop price adjustments (trunk only)

Fix the second of a couple of minor things I noticed when viewing
that guy's ttyrec about a hidden inventory item which turned out to be
scrolls of scare monster on the used-up items section of his shop bill.

     He had a lot of scroll prices which started as $X00 and were changed
to $Y99 due to integer division roundoff when being hit with a 1/3 price
increase for unID'd items followed by 1/2 price increase for low charisma:
  100  ->  133  ->  199
  200  ->  266  ->  399
Forcing things to round up instead of truncate would help in some cases
but yield $Z01 in others.  Rather than doing that, this accumulates the
adjustment factors and then uses them to make one calculation which gives
a better result:
  100  ->  200
  200  ->  400
Other values and/or other adjustments might not work out so well, but I
don't think they'll ever become prices which look worse than before.
For a single increase of 1/3, 100 still yields 133 but 200 now gives 267
(so ends up differing from the combined price for two 100->133 items).
This commit is contained in:
nethack.rankin
2011-07-23 03:57:09 +00:00
parent 236c3524d2
commit c98133ac80
2 changed files with 64 additions and 28 deletions

View File

@@ -373,6 +373,7 @@ for poly'd hero hiding on ceiling, attack by sea monsters won't move them
into hero's position unless it is over water or they're already on land
for poly'd hero hiding on ceiling, attack by long worm might fill hero's
destination with worm's tail, so double check and maybe choose again
when shop prices are adjusted, handle roundoff (integer truncation) better
Platform- and/or Interface-Specific Fixes

View File

@@ -1843,7 +1843,10 @@ get_cost(obj, shkp)
register struct obj *obj;
register struct monst *shkp; /* if angry, impose a surcharge */
{
register long tmp = getprice(obj, FALSE);
long tmp = getprice(obj, FALSE),
/* used to perform a single calculation even when multiple
adjustments (unID'd, dunce/tourist, charisma) are made */
multiplier = 1L, divisor = 1L;
if (!tmp) tmp = 5L;
/* shopkeeper may notice if the player isn't very knowledgeable -
@@ -1891,27 +1894,44 @@ register struct monst *shkp; /* if angry, impose a surcharge */
break;
}
tmp = (long) objects[i].oc_cost;
} else if (!(obj->o_id % 4)) /* arbitrarily impose surcharge */
tmp += tmp / 3L;
} else if (!(obj->o_id % 4)) {
/* unid'd, arbitrarily impose surcharge: tmp *= 4/3 */
multiplier *= 4L;
divisor *= 3L;
}
}
#ifdef TOURIST
if ((Role_if(PM_TOURIST) && u.ulevel < (MAXULEV/2))
|| (uarmu && !uarm && !uarmc)) /* touristy shirt visible */
tmp += tmp / 3L;
else
#endif
if (uarmh && uarmh->otyp == DUNCE_CAP)
tmp += tmp / 3L;
multiplier *= 4L, divisor *= 3L;
#ifdef TOURIST
else if ((Role_if(PM_TOURIST) && u.ulevel < (MAXULEV/2)) ||
(uarmu && !uarm && !uarmc)) /* touristy shirt visible */
multiplier *= 4L, divisor *= 3L;
#endif
if (ACURR(A_CHA) > 18) divisor *= 2L;
else if (ACURR(A_CHA) == 18) multiplier *= 2L, divisor *= 3L;
else if (ACURR(A_CHA) >= 16) multiplier *= 3L, divisor *= 4L;
else if (ACURR(A_CHA) <= 5) multiplier *= 2L;
else if (ACURR(A_CHA) <= 7) multiplier *= 3L, divisor *= 2L;
else if (ACURR(A_CHA) <= 10) multiplier *= 4L, divisor *= 3L;
/* tmp = (tmp * multiplier) / divisor [with roundoff tweak] */
tmp *= multiplier;
if (divisor > 1L) {
/* tmp = (((tmp * 10) / divisor) + 5) / 10 */
tmp *= 10L;
tmp /= divisor;
tmp += 5L;
tmp /= 10L;
}
if (ACURR(A_CHA) > 18) tmp /= 2L;
else if (ACURR(A_CHA) > 17) tmp -= tmp / 3L;
else if (ACURR(A_CHA) > 15) tmp -= tmp / 4L;
else if (ACURR(A_CHA) < 6) tmp *= 2L;
else if (ACURR(A_CHA) < 8) tmp += tmp / 2L;
else if (ACURR(A_CHA) < 11) tmp += tmp / 3L;
if (tmp <= 0L) tmp = 1L;
else if (obj->oartifact) tmp *= 4L;
/* anger surcharge should match rile_shk's */
/* the artifact prices in artilist[] are also used as a score bonus;
inflate their shop price here without affecting score calculation */
if (obj->oartifact) tmp *= 4L;
/* anger surcharge should match rile_shk's, so we do it separately
from the multiplier/divisor calculation */
if (shkp && ESHK(shkp)->surcharge) tmp += (tmp + 2L) / 3L;
return tmp;
}
@@ -2042,18 +2062,18 @@ set_cost(obj, shkp)
register struct obj *obj;
register struct monst *shkp;
{
long tmp = getprice(obj, TRUE) * obj->quan;
long tmp = getprice(obj, TRUE) * obj->quan,
multiplier = 1L, divisor = 1L;
#ifdef TOURIST
if ((Role_if(PM_TOURIST) && u.ulevel < (MAXULEV/2))
|| (uarmu && !uarm && !uarmc)) /* touristy shirt visible */
tmp /= 3L;
else
#endif
if (uarmh && uarmh->otyp == DUNCE_CAP)
tmp /= 3L;
divisor *= 3L;
#ifdef TOURIST
else if ((Role_if(PM_TOURIST) && u.ulevel < (MAXULEV/2)) ||
(uarmu && !uarm && !uarmc)) /* touristy shirt visible */
divisor *= 3L;
#endif
else
tmp /= 2L;
divisor *= 2L;
/* shopkeeper may notice if the player isn't very knowledgeable -
especially when gem prices are concerned */
@@ -2066,8 +2086,23 @@ register struct monst *shkp;
tmp = (tmp + 3) * obj->quan;
}
} else if (tmp > 1L && !rn2(4))
tmp -= tmp / 4L;
multiplier *= 3L, divisor *= 4L;
}
if (tmp >= 1L) {
/* [see get_cost()] */
tmp *= multiplier;
if (divisor > 1L) {
tmp *= 10L;
tmp /= divisor;
tmp += 5L;
tmp /= 10L;
}
/* avoid adjusting nonzero to zero */
if (tmp < 1L) tmp = 1L;
}
/* (no adjustment for angry shk here) */
return tmp;
}