-/* NetHack 3.6 attrib.c $NHDT-Date: 1494034337 2017/05/06 01:32:17 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.62 $ */
+/* NetHack 3.6 attrib.c $NHDT-Date: 1553363417 2019/03/23 17:50:17 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.65 $ */
/* Copyright 1988, 1989, 1990, 1992, M. Stephenson */
/* NetHack may be freely redistributed. See license for details. */
int ndx, incr;
int msgflg; /* positive => no message, zero => message, and */
{ /* negative => conditional (msg if change made) */
- int old_acurr, old_abase;
+ int old_acurr, old_abase, old_amax, decr;
boolean abonflg;
const char *attrstr;
old_acurr = ACURR(ndx);
old_abase = ABASE(ndx);
+ old_amax = AMAX(ndx);
+ ABASE(ndx) += incr; /* when incr is negative, this reduces ABASE() */
if (incr > 0) {
- ABASE(ndx) += incr;
if (ABASE(ndx) > AMAX(ndx)) {
- incr = ABASE(ndx) - AMAX(ndx);
- AMAX(ndx) += incr;
+ AMAX(ndx) = ABASE(ndx);
if (AMAX(ndx) > ATTRMAX(ndx))
- AMAX(ndx) = ATTRMAX(ndx);
- ABASE(ndx) = AMAX(ndx);
+ ABASE(ndx) = AMAX(ndx) = ATTRMAX(ndx);
}
attrstr = plusattr[ndx];
abonflg = (ABON(ndx) < 0);
- } else {
- ABASE(ndx) += incr;
+ } else { /* incr is negative */
if (ABASE(ndx) < ATTRMIN(ndx)) {
- incr = ABASE(ndx) - ATTRMIN(ndx);
+ /*
+ * If base value has dropped so low that it is trying to be
+ * taken below the minimum, reduce max value (peak reached)
+ * instead. That means that restore ability and repeated
+ * applications of unicorn horn will not be able to recover
+ * all the lost value. Starting will 3.6.2, we only take away
+ * some (average half, possibly zero) of the excess from max
+ * instead of all of it, but without intervening recovery, it
+ * can still eventually drop to the minimum allowed. After
+ * that, it can't be recovered, only improved with new gains.
+ *
+ * This used to assign a new negative value to incr and then
+ * add it, but that could affect messages below, possibly
+ * making a large decrease be described as a small one.
+ *
+ * decr = rn2(-(ABASE - ATTRMIN) + 1);
+ */
+ decr = rn2(ATTRMIN(ndx) - ABASE(ndx) + 1);
ABASE(ndx) = ATTRMIN(ndx);
- AMAX(ndx) += incr;
+ AMAX(ndx) -= decr;
if (AMAX(ndx) < ATTRMIN(ndx))
AMAX(ndx) = ATTRMIN(ndx);
}
}
if (ACURR(ndx) == old_acurr) {
if (msgflg == 0 && flags.verbose) {
- if (ABASE(ndx) == old_abase)
+ if (ABASE(ndx) == old_abase && AMAX(ndx) == old_amax) {
#if 0 /*JP*/
pline("You're %s as %s as you can get.",
abonflg ? "currently" : "already", attrstr);
You("%s\8f\\95ª\82É%s\81D",
abonflg ? "\8d¡\82Ì\82Æ\82±\82ë" : "\8aù\82É", attrstr);
#endif
- else /* current stayed the same but base value changed */
+ } else {
+ /* current stayed the same but base value changed, or
+ base is at minimum and reduction caused max to drop */
#if 0 /*JP*/
Your("innate %s has %s.", attrname[ndx],
(incr > 0) ? "improved" : "declined");
Your("\96{\8e¿\93I\82È%s\82ª%s\82µ\82½\81D", attrname[ndx],
(incr > 0) ? "\8cü\8fã" : "\92á\89º");
#endif
+ }
}
return FALSE;
}
You_feel("%s%s!", (incr > 1 || incr < -1) ? "very " : "", attrstr);
*/
You("%s%s\82È\82Á\82½\82æ\82¤\82È\8bC\82ª\82µ\82½\81I", (incr > 1 || incr < -1) ? "\82Æ\82Ä\82à" : "", jconj_adj(attrstr));
- context.botl = 1;
- if (moves > 1 && (ndx == A_STR || ndx == A_CON))
+ context.botl = TRUE;
+ if (program_state.in_moveloop && (ndx == A_STR || ndx == A_CON))
(void) encumber_msg();
return TRUE;
}
if (ATEMP(i) != equilibrium && ATIME(i) != 0) {
if (!(--(ATIME(i)))) { /* countdown for change */
ATEMP(i) += (ATEMP(i) > 0) ? -1 : 1;
- context.botl = 1;
+ context.botl = TRUE;
if (ATEMP(i)) /* reset timer */
ATIME(i) = 100 / ACURR(A_CON);
}
exertext[i][(mod_val > 0) ? 0 : 1]);
#endif
}
- nextattrib:
+ nextattrib:
/* this used to be ``AEXE(i) /= 2'' but that would produce
platform-dependent rounding/truncation for negative vals */
AEXE(i) = (abs(ax) / 2) * mod_val;
{
aligntyp oldalign = u.ualign.type;
- u.ublessed = 0; /* lose divine protection */
- context.botl = 1; /* status line needs updating */
+ u.ublessed = 0; /* lose divine protection */
+ /* You/Your/pline message with call flush_screen(), triggering bot(),
+ so the actual data change needs to come before the message */
+ context.botl = TRUE; /* status line needs updating */
if (reason == 0) {
/* conversion via altar */
u.ualignbase[A_CURRENT] = (aligntyp) newalign;
: "\8dÄ\82Ñ\91Ì\82Æ\88ê\92v\82·\82é\82æ\82¤\82É\82È\82Á\82½");
#endif
}
-
if (u.ualign.type != oldalign) {
u.ualign.record = 0; /* slate is wiped clean */
retouch_equipment(0);