Merge branch 'NetHack-3.6'
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
134
src/botl.c
134
src/botl.c
@@ -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 */
|
||||
|
||||
11
src/exper.c
11
src/exper.c
@@ -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;
|
||||
|
||||
@@ -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++;
|
||||
|
||||
Reference in New Issue
Block a user