Merge branch 'NetHack-3.6'

This commit is contained in:
nhmall
2019-07-02 22:46:53 -04:00
8 changed files with 175 additions and 30 deletions

View File

@@ -1,4 +1,4 @@
.\" $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.305 $ $NHDT-Date: 1557251604 2019/05/07 17:53:24 $
.\" $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.310 $ $NHDT-Date: 1562114349 2019/07/03 00:39:09 $
.\"
.\" This is an excerpt from the 'roff' man page from the 'groff' package.
.\" NetHack's Guidebook.mn currently does *not* adhere to these guidelines.
@@ -4281,7 +4281,24 @@ it also matches when value is below or above the percentage.
Use prefix \(oq<\(cq or \(oq>\(cq to match when strictly below or above.
(The numeric limit is relaxed slightly for those: \f(CR>-1%\fP
and \f(CR<101%\fP are allowed.)
Only valid for \(lqhitpoints\(rq and \(lqpower\(rq fields.
Only four fields support percentage rules.
Percentages for \(lqhitpoints\(rq and \(lqpower\(rq are
straightforward; they're based on the corresponding maximum field.
Percentage highlight rules are also allowed for \(lqexperience level\(rq
and \(lqexperience points\(rq (valid when the
.op showexp
option is enabled).
For those, the percentage is based on the progress from the start of
the current experience level to the start of the next level.
So if level 2 starts at 20 points and level 3 starts at 40 points,
having 30 points is 50% and 35 points is 75%.
100% is unattainable for experience because you'll gain a level and
the calculations will be reset for that new level, but a rule for
\f(CR=100%\fP is allowed and matches the special case of being
exactly 1 experience point short of the next level.
.\" (If you manage to reach level 30, there is no next level and the
.\" percentage will remain at 0% no matter have many additional experience
.\" points you earn.)
.lp "*"
absolute value sets the attribute when the field value matches
that number.

View File

@@ -4769,7 +4769,24 @@ it also matches when value is below or above the percentage.
Use prefix `{\tt <}' or `{\tt >}' to match when strictly below or above.
(The numeric limit is relaxed slightly for those: {\tt >-1\%}
and {\tt <101\%} are allowed.)
Only valid for ``{\it hitpoints\/}'' and ``{\it power\/}'' fields.
Only four fields support percentage rules.
Percentages for ``{\it hitpoints\/}'' and ``{\it power\/}'' are
straightforward; they're based on the corresponding maximum field.
Percentage highlight rules are also allowed for ``{\it experience level\/}''
and ``{\it experience points\/}'' (valid when the
(\it showexp\/}
option is enabled).
For those, the percentage is based on the progress from the start of
the current experience level to the start of the next level.
So if level 2 starts at 20 points and level 3 starts at 40 points,
having 30 points is 50\% and 35 points is 75\%.
100\% is unattainable for experience because you'll gain a level and
the calculations will be reset for that new level, but a rule for
{\tt =100\%} is allowed and matches the special case of being
exactly 1 experience point short of the next level.
% (If you manage to reach level 30, there is no next level and the
% percentage will remain at 0\% no matter have many additional experience
% points you earn.)
%.lp "*"
\item{\bb{}}
absolute value sets the attribute when the field value

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.81 $ $NHDT-Date: 1562056615 2019/07/02 08:36:55 $
$NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.83 $ $NHDT-Date: 1562114348 2019/07/03 00:39:08 $
This fixes36.3 file is here to capture information about updates in the 3.6.x
lineage following the release of 3.6.2 in May 2019. Please note, however,
@@ -206,6 +206,10 @@ if you reach the edge of a level (relatively uncommon) and try to move off,
'attributes' disclosure at end of game includes number of experience points
that were needed to reach the next experience level (new for normal
play and explore mode; previously only shown for wizard mode)
status highlighting using percentage rules now supported for experience level
and experience points; for both, percent is based on Exp progress from
the start of the current Xp level to the start of the next Xp level;
100% isn't possible so used as special case for next_Xp_lvl - 1 Exp_pt
wizard-mode: display effect to show where an unseen wished-for monster landed
curses: enable latent mouse support
curses: give menus and text windows a minimum size of 5x25 since tiny ones can

View File

@@ -126,6 +126,8 @@ struct istat_s {
const char *fldfmt;
long time; /* moves when this field hilite times out */
boolean chg; /* need to recalc time? */
boolean percent_matters;
short percent_value;
unsigned anytype;
anything a;
char *val;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1560161804 2019/06/10 10:16:44 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.714 $ */
/* NetHack 3.6 extern.h $NHDT-Date: 1562114349 2019/07/03 00:39:09 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.715 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
@@ -178,6 +178,7 @@ E long NDECL(botl_score);
E int FDECL(describe_level, (char *));
E void FDECL(status_initialize, (BOOLEAN_P));
E void NDECL(status_finish);
E boolean NDECL(exp_percent_changing);
E int NDECL(stat_cap_indx);
E int NDECL(stat_hunger_indx);
E const char *FDECL(bl_idx_to_fldname, (int));

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 botl.c $NHDT-Date: 1557094795 2019/05/05 22:19:55 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.145 $ */
/* NetHack 3.6 botl.c $NHDT-Date: 1562114350 2019/07/03 00:39:10 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.146 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */
@@ -420,6 +420,7 @@ STATIC_DCL void NDECL(init_blstats);
STATIC_DCL int FDECL(compare_blstats, (struct istat_s *, struct istat_s *));
STATIC_DCL char *FDECL(anything_to_s, (char *, anything *, int));
STATIC_DCL int FDECL(percentage, (struct istat_s *, struct istat_s *));
STATIC_DCL int NDECL(exp_percentage);
#ifdef STATUS_HILITES
STATIC_DCL void FDECL(s_to_anything, (anything *, char *, int));
@@ -466,14 +467,18 @@ STATIC_DCL boolean FDECL(status_hilite_menu_add, (int));
#define INIT_THRESH /*empty*/
#endif
#define INIT_BLSTAT(name, fmtstr, anytyp, wid, fld) \
{ name, fmtstr, 0L, FALSE, anytyp, { (genericptr_t) 0 }, (char *) 0, \
#define INIT_BLSTAT(name, fmtstr, anytyp, wid, fld) \
{ name, fmtstr, 0L, FALSE, FALSE, 0, anytyp, \
{ (genericptr_t) 0 }, (char *) 0, \
wid, -1, fld INIT_THRESH }
#define INIT_BLSTATP(name, fmtstr, anytyp, wid, maxfld, fld) \
{ name, fmtstr, 0L, FALSE, anytyp, { (genericptr_t) 0 }, (char *) 0, \
#define INIT_BLSTATP(name, fmtstr, anytyp, wid, maxfld, fld) \
{ name, fmtstr, 0L, FALSE, TRUE, 0, anytyp, \
{ (genericptr_t) 0 }, (char *) 0, \
wid, maxfld, fld INIT_THRESH }
/* If entries are added to this, botl.h will require updating too */
/* If entries are added to this, botl.h will require updating too.
'max' value of BL_EXP gets special handling since the percentage
involved isn't a direct 100*current/maximum calculation. */
STATIC_VAR struct istat_s initblstats[MAXBLSTATS] = {
INIT_BLSTAT("title", "%s", ANY_STR, MAXVALWIDTH, BL_TITLE),
INIT_BLSTAT("strength", " St:%s", ANY_INT, 10, BL_STR),
@@ -488,7 +493,7 @@ STATIC_VAR struct istat_s initblstats[MAXBLSTATS] = {
INIT_BLSTAT("gold", " %s", ANY_LONG, 30, BL_GOLD),
INIT_BLSTATP("power", " Pw:%s", ANY_INT, 10, BL_ENEMAX, BL_ENE),
INIT_BLSTAT("power-max", "(%s)", ANY_INT, 10, BL_ENEMAX),
INIT_BLSTAT("experience-level", " Xp:%s", ANY_INT, 10, BL_XP),
INIT_BLSTATP("experience-level", " Xp:%s", ANY_INT, 10, BL_EXP, BL_XP),
INIT_BLSTAT("armor-class", " AC:%s", ANY_INT, 10, BL_AC),
INIT_BLSTAT("HD", " HD:%s", ANY_INT, 10, BL_HD),
INIT_BLSTAT("time", " T:%s", ANY_LONG, 20, BL_TIME),
@@ -497,7 +502,7 @@ STATIC_VAR struct istat_s initblstats[MAXBLSTATS] = {
INIT_BLSTATP("hitpoints", " HP:%s", ANY_INT, 10, BL_HPMAX, BL_HP),
INIT_BLSTAT("hitpoints-max", "(%s)", ANY_INT, 10, BL_HPMAX),
INIT_BLSTAT("dungeon-level", "%s", ANY_STR, MAXVALWIDTH, BL_LEVELDESC),
INIT_BLSTAT("experience", "/%s", ANY_LONG, 20, BL_EXP),
INIT_BLSTATP("experience", "/%s", ANY_LONG, 20, BL_EXP, BL_EXP),
INIT_BLSTAT("condition", "%s", ANY_MASK32, 0, BL_CONDITION)
};
@@ -724,8 +729,8 @@ boolean *valsetlist;
int pc, chg, color = NO_COLOR;
unsigned anytype;
boolean updated = FALSE, reset;
struct istat_s *curr = NULL, *prev = NULL;
enum statusfields idxmax;
struct istat_s *curr, *prev;
enum statusfields fldmax;
/*
* Now pass the changed values to window port.
@@ -736,6 +741,31 @@ boolean *valsetlist;
color = NO_COLOR;
chg = g.update_all ? 0 : compare_blstats(prev, curr);
/*
* TODO:
* Dynamically update 'percent_matters' as rules are added or
* removed to track whether any of them are precentage rules.
* Then there'll be no need to assume that non-Null 'thresholds'
* means that percentages need to be kept up to date.
* [Affects exp_percent_changing() too.]
*/
if (((chg || g.update_all || fld == BL_XP)
&& curr->percent_matters && curr->thresholds)
/* when 'hitpointbar' is On, percent matters even if HP
hasn't changed and has no percentage rules (in case HPmax
has changed when HP hasn't, where we ordinarily wouldn't
update HP so would miss an update of the hitpoint bar) */
|| (fld == BL_HP && iflags.wc2_hitpointbar)) {
fldmax = curr->idxmax;
pc = (fldmax == BL_EXP) ? exp_percentage()
: (fldmax >= 0) ? percentage(curr, &g.blstats[idx][fldmax])
: 0; /* bullet proofing; can't get here */
if (pc != prev->percent_value)
chg = 1;
curr->percent_value = pc;
} else {
pc = 0;
}
/* Temporary? hack: moveloop()'s prolog for a new game sets
* g.context.rndencode after the status window has been init'd,
@@ -753,7 +783,7 @@ boolean *valsetlist;
* 25 = the gold amount
*
* Setting 'chg = 2' is enough to render the field properly, but
* not to honor an initial highlight, so force 'update_all = TRUE'.
* not to honor an initial highlight, so force 'g.update_all = TRUE'.
*/
if (fld == BL_GOLD
&& (g.context.rndencode != oldrndencode
@@ -772,19 +802,7 @@ boolean *valsetlist;
}
#endif
/*
* TODO?
* It's possible for HPmax (or ENEmax) to change while current
* HP (or energy) stays the same. [Perhaps current and maximum
* both go up, then before the next status update takes place
* current goes down again.] If that happens with HPmax, we
* ought to force the windowport to treat current HP as changed
* if hitpointbar is On, in order for that to be re-rendered.
*/
if (g.update_all || chg || reset) {
idxmax = curr->idxmax;
pc = (idxmax >= 0) ? percentage(curr, &g.blstats[idx][idxmax]) : 0;
if (!valsetlist[fld])
(void) anything_to_s(curr->val, &curr->a, anytype);
@@ -904,6 +922,7 @@ boolean reassessment; /* TRUE: just recheck fields w/o other initialization */
status_enablefield(fld, fieldname, fieldfmt, fldenabl);
}
g.update_all = TRUE;
g.context.botlx = TRUE;
}
void
@@ -1221,6 +1240,75 @@ struct istat_s *bl, *maxbl;
return result;
}
/* percentage for both xp (level) and exp (points) is the percentage for
(curr_exp - this_level_start) in (next_level_start - this_level_start) */
STATIC_OVL int
exp_percentage()
{
int res = 0;
if (u.ulevel < 30) {
long exp_val, nxt_exp_val, curlvlstart;
curlvlstart = newuexp(u.ulevel - 1);
exp_val = u.uexp - curlvlstart;
nxt_exp_val = newuexp(u.ulevel) - curlvlstart;
if (exp_val == nxt_exp_val - 1L) {
/*
* Full 100% is unattainable since hero gains a level
* and the threshold for next level increases, but treat
* (next_level_start - 1 point) as a special case. It's a
* key value after being level drained so is something that
* some players would like to be able to highlight distinctly.
*/
res = 100;
} else {
struct istat_s curval, maxval;
curval.anytype = maxval.anytype = ANY_LONG;
curval.a = maxval.a = cg.zeroany;
curval.a.a_long = exp_val;
maxval.a.a_long = nxt_exp_val;
/* maximum delta between levels is 10000000; calculation of
100 * (10000000 - N) / 10000000 fits within 32-bit long */
res = percentage(&curval, &maxval);
}
}
return res;
}
/* experience points have changed but experience level hasn't; decide whether
botl update is needed for a different percentage highlight rule for Xp */
boolean
exp_percent_changing()
{
int pc, color_dummy;
anything a;
struct hilite_s *rule;
struct istat_s *curr;
/* if status update is already requested, skip this processing */
if (!g.context.botl) {
/*
* Status update is warranted iff percent integer changes and the new
* percentage results in a different highlighting rule being selected.
*/
curr = &g.blstats[g.now_or_before_idx][BL_XP];
/* TODO: [see eval_notify_windowport_field() about percent_matters
and the check against 'thresholds'] */
if (curr->percent_matters && curr->thresholds
&& (pc = exp_percentage()) != curr->percent_value) {
a = cg.zeroany;
a.a_int = (int) u.ulevel;
rule = get_hilite(g.now_or_before_idx, BL_XP,
(genericptr_t) &a, 0, pc, &color_dummy);
if (rule != curr->hilite_rule)
return TRUE; /* caller should set 'g.context.botl' to True */
}
}
return FALSE;
}
/* callback so that interface can get capacity index rather than trying
to reconstruct that from the encumbrance string or asking the general
core what the value is */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 exper.c $NHDT-Date: 1553296396 2019/03/22 23:13:16 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.32 $ */
/* NetHack 3.6 exper.c $NHDT-Date: 1562114352 2019/07/03 00:39:12 $ $NHDT-Branch: NetHack-3.6 $:$NHDT-Revision: 1.33 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2007. */
/* NetHack may be freely redistributed. See license for details. */
@@ -14,6 +14,8 @@ long
newuexp(lev)
int lev;
{
if (lev < 1) /* for newuexp(u.ulevel - 1) when u.ulevel is 1 */
return 0L;
if (lev < 10)
return (10L * (1L << lev));
if (lev < 20)
@@ -177,6 +179,11 @@ register int exper, rexp;
u.uexp = newexp;
if (flags.showexp)
g.context.botl = TRUE;
/* even when experience points aren't being shown, experience level
might be highlighted with a percentage highlight rule and that
percentage depends upon experience points */
if (!g.context.botl && exp_percent_changing())
g.context.botl = TRUE;
}
/* newrexp will always differ from oldrexp unless they're LONG_MAX */
if (newrexp != oldrexp) {
@@ -303,7 +310,7 @@ boolean incr; /* true iff via incremental experience growth */
}
++u.ulevel;
pline("Welcome %sto experience level %d.",
u.ulevelmax < u.ulevel ? "" : "back ",
(u.ulevelmax < u.ulevel) ? "" : "back ",
u.ulevel);
if (u.ulevelmax < u.ulevel)
u.ulevelmax = u.ulevel;

View File

@@ -313,6 +313,15 @@ const char *str;
#endif
case '\\':
break;
case '\0':
/* String ended with '\\'. This can happen when someone
names an object with a name ending with '\\', drops the
named object on the floor nearby and does a look at all
nearby objects. */
/* brh - should we perhaps not allow things to have names
that contain '\\' */
str = save_str;
break;
}
}
*put++ = *str++;