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

@@ -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;
}