Merge branch 'NetHack-3.6.2'

This commit is contained in:
nhmall
2019-04-02 12:25:16 -04:00
33 changed files with 1126 additions and 660 deletions

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 allmain.c $NHDT-Date: 1553363414 2019/03/23 17:50:14 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.95 $ */
/* NetHack 3.6 allmain.c $NHDT-Date: 1554045808 2019/03/31 15:23:28 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.96 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -183,7 +183,7 @@ boolean resuming;
if (u.ublesscnt)
u.ublesscnt--;
if (flags.time && !g.context.run)
g.context.botl = TRUE;
iflags.time_botl = TRUE;
/* One possible result of prayer is healing. Whether or
* not you get healed depends on your current hit points.
@@ -209,8 +209,10 @@ boolean resuming;
: g.moves % 10)) {
if (Upolyd && u.mh > 1) {
u.mh--;
g.context.botl = TRUE;
} else if (!Upolyd && u.uhp > 1) {
u.uhp--;
g.context.botl = TRUE;
} else {
You("pass out from exertion!");
exercise(A_CON, FALSE);
@@ -236,6 +238,7 @@ boolean resuming;
if (!u.uinvulnerable) {
if (Teleportation && !rn2(85)) {
xchar old_ux = u.ux, old_uy = u.uy;
tele();
if (u.ux != old_ux || u.uy != old_uy) {
if (!next_to_u()) {
@@ -361,6 +364,9 @@ boolean resuming;
if (g.context.botl || g.context.botlx) {
bot();
curs_on_u();
} else if (iflags.time_botl) {
timebot();
curs_on_u();
}
g.context.move = 1;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 botl.c $NHDT-Date: 1553387148 2019/03/24 00:25:48 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.137 $ */
/* NetHack 3.6 botl.c $NHDT-Date: 1554045809 2019/03/31 15:23:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.140 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */
@@ -16,6 +16,7 @@ const char *const enc_stat[] = { "", "Burdened", "Stressed",
STATIC_DCL const char *NDECL(rank);
#ifdef STATUS_HILITES
STATIC_DCL void NDECL(bot_via_windowport);
STATIC_DCL void NDECL(stat_update_time);
#endif
static char *
@@ -243,7 +244,21 @@ bot()
putmixed(WIN_STATUS, 0, do_statusline2());
#endif
}
g.context.botl = g.context.botlx = 0;
g.context.botl = g.context.botlx = iflags.time_botl = FALSE;
}
void
timebot()
{
if (flags.time) {
#ifdef STATUS_HILITES
stat_update_time();
#else
/* old status display updates everything */
bot();
#endif
}
iflags.time_botl = FALSE;
}
/* convert experience level (1..30) to rank index (0..8) */
@@ -405,21 +420,19 @@ STATIC_DCL void NDECL(init_blstats);
STATIC_DCL char *FDECL(anything_to_s, (char *, anything *, int));
STATIC_OVL int FDECL(percentage, (struct istat_s *, struct istat_s *));
STATIC_OVL int FDECL(compare_blstats, (struct istat_s *, struct istat_s *));
STATIC_DCL boolean FDECL(evaluate_and_notify_windowport_field,
(int, boolean *, int, int));
STATIC_DCL void FDECL(evaluate_and_notify_windowport, (boolean *, int, int));
STATIC_DCL boolean FDECL(eval_notify_windowport_field, (int, boolean *, int));
STATIC_DCL void FDECL(evaluate_and_notify_windowport, (boolean *, int));
#ifdef STATUS_HILITES
STATIC_DCL boolean FDECL(hilite_reset_needed, (struct istat_s *, long));
STATIC_DCL void FDECL(s_to_anything, (anything *, char *, int));
STATIC_DCL boolean FDECL(is_ltgt_percentnumber, (const char *));
STATIC_DCL boolean FDECL(has_ltgt_percentnumber, (const char *));
STATIC_DCL boolean FDECL(parse_status_hl2, (char (*)[QBUFSZ],BOOLEAN_P));
STATIC_DCL boolean FDECL(parse_status_hl2, (char (*)[QBUFSZ], BOOLEAN_P));
STATIC_DCL boolean FDECL(parse_condition, (char (*)[QBUFSZ], int));
STATIC_DCL boolean FDECL(noneoftheabove, (const char *));
STATIC_DCL void FDECL(merge_bestcolor, (int *, int));
STATIC_DCL void FDECL(get_hilite_color, (int, int, genericptr_t, int,
int, int *));
STATIC_DCL struct hilite_s *FDECL(get_hilite, (int, int, genericptr_t,
int, int, int *));
STATIC_DCL unsigned long FDECL(match_str2conditionbitmask, (const char *));
STATIC_DCL unsigned long FDECL(str2conditionbitmask, (char *));
STATIC_DCL void FDECL(split_clridx, (int, int *, int *));
@@ -437,18 +450,25 @@ STATIC_DCL int FDECL(status_hilite_menu_choose_updownboth, (int, const char *,
BOOLEAN_P, BOOLEAN_P));
STATIC_DCL boolean FDECL(status_hilite_menu_add, (int));
#define has_hilite(i) (g.blstats[0][(i)].thresholds)
/* TH_UPDOWN encompasses specific 'up' and 'down' also general 'changed' */
#define Is_Temp_Hilite(rule) ((rule) && (rule)->behavior == BL_TH_UPDOWN)
/* pointers to current hilite rule and list of this field's defined rules */
#define INIT_THRESH , (struct hilite_s *) 0, (struct hilite_s *) 0
#else /* !STATUS_HILITES */
#define INIT_THRESH /*empty*/
#endif
#define INIT_BLSTAT(name, fmtstr, anytyp, wid, fld) \
{ name, fmtstr, 0L, FALSE, anytyp, { (genericptr_t) 0 }, (char *) 0, \
wid, -1, fld }
wid, -1, fld INIT_THRESH }
#define INIT_BLSTATP(name, fmtstr, anytyp, wid, maxfld, fld) \
{ name, fmtstr, 0L, FALSE, anytyp, { (genericptr_t) 0 }, (char *) 0, \
wid, maxfld, fld }
wid, maxfld, fld INIT_THRESH }
/* If entries are added to this, botl.h will require updating too */
STATIC_DCL struct istat_s initblstats[MAXBLSTATS] = {
INIT_BLSTAT("title", "%s", ANY_STR, 80, BL_TITLE),
INIT_BLSTAT("title", "%s", ANY_STR, MAXVALWIDTH, BL_TITLE),
INIT_BLSTAT("strength", " St:%s", ANY_INT, 10, BL_STR),
INIT_BLSTAT("dexterity", " Dx:%s", ANY_INT, 10, BL_DX),
INIT_BLSTAT("constitution", " Co:%s", ANY_INT, 10, BL_CO),
@@ -469,13 +489,14 @@ STATIC_DCL struct istat_s initblstats[MAXBLSTATS] = {
INIT_BLSTAT("hunger", " %s", ANY_INT, 40, BL_HUNGER),
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, 80, BL_LEVELDESC),
INIT_BLSTAT("dungeon-level", "%s", ANY_STR, MAXVALWIDTH, BL_LEVELDESC),
INIT_BLSTAT("experience", "/%s", ANY_LONG, 20, BL_EXP),
INIT_BLSTAT("condition", "%s", ANY_MASK32, 0, BL_CONDITION)
};
#undef INIT_BLSTATP
#undef INIT_BLSTAT
#undef INIT_THRESH
/* we don't put this next declaration in #ifdef STATUS_HILITES.
* In the absence of STATUS_HILITES, each array
@@ -489,15 +510,17 @@ void
bot_via_windowport()
{
char buf[BUFSZ];
const char *titl;
register char *nb;
static int i, idx = 0, idx_p, cap;
int i, idx, cap;
long money;
if (!g.blinit)
panic("bot before init.");
idx_p = idx;
idx = 1 - idx; /* 0 -> 1, 1 -> 0 */
/* toggle from previous iteration */
idx = 1 - g.now_or_before_idx; /* 0 -> 1, 1 -> 0 */
g.now_or_before_idx = idx;
/* clear the "value set" indicators */
(void) memset((genericptr_t) g.valset, 0, MAXBLSTATS * sizeof (boolean));
@@ -513,15 +536,23 @@ bot_via_windowport()
*/
Strcpy(nb = buf, g.plname);
nb[0] = highc(nb[0]);
nb[10] = '\0';
titl = !Upolyd ? rank() : mons[u.umonnum].mname;
i = (int) (strlen(buf) + sizeof " the " + strlen(titl) - sizeof "");
/* if "Name the Rank/monster" is too long, we truncate the name
but always keep at least 10 characters of it; when hitpintbar is
enabled, anything beyond 30 (long monster name) will be truncated */
if (i > 30) {
i = 30 - (int) (sizeof " the " + strlen(titl) - sizeof "");
nb[max(i, 10)] = '\0';
}
Strcpy(nb = eos(nb), " the ");
if (Upolyd) {
for (i = 0, nb = strcpy(eos(nb), mons[u.umonnum].mname); nb[i]; i++)
Strcpy(nb = eos(nb), titl);
if (Upolyd) { /* when poly'd, capitalize monster name */
for (i = 0; nb[i]; i++)
if (i == 0 || nb[i - 1] == ' ')
nb[i] = highc(nb[i]);
} else
Strcpy(nb = eos(nb), rank());
Sprintf(g.blstats[idx][BL_TITLE].val, "%-29s", buf);
}
Sprintf(g.blstats[idx][BL_TITLE].val, "%-30s", buf);
g.valset[BL_TITLE] = TRUE; /* indicate val already set */
/* Strength */
@@ -653,12 +684,30 @@ bot_via_windowport()
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_FLY;
if (u.usteed)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_RIDE;
evaluate_and_notify_windowport(g.valset, idx, idx_p);
evaluate_and_notify_windowport(g.valset, idx);
}
/* update just the status lines' 'time' field */
STATIC_OVL void
stat_update_time()
{
int idx = g.now_or_before_idx; /* no 0/1 toggle */
int fld = BL_TIME;
/* Time (moves) */
g.blstats[idx][fld].a.a_long = g.moves;
g.valset[fld] = FALSE;
eval_notify_windowport_field(fld, g.valset, idx);
if ((windowprocs.wincap2 & WC2_FLUSH_STATUS) != 0L)
status_update(BL_FLUSH, (genericptr_t) 0, 0, 0,
NO_COLOR, (unsigned long *) 0);
return;
}
STATIC_OVL boolean
evaluate_and_notify_windowport_field(fld, valsetlist, idx, idx_p)
int fld, idx, idx_p;
eval_notify_windowport_field(fld, valsetlist, idx)
int fld, idx;
boolean *valsetlist;
{
static int oldrndencode = 0;
@@ -674,7 +723,7 @@ boolean *valsetlist;
*/
anytype = g.blstats[idx][fld].anytype;
curr = &g.blstats[idx][fld];
prev = &g.blstats[idx_p][fld];
prev = &g.blstats[1 - idx][fld];
color = NO_COLOR;
chg = g.update_all ? 0 : compare_blstats(prev, curr);
@@ -707,7 +756,7 @@ boolean *valsetlist;
reset = FALSE;
#ifdef STATUS_HILITES
if (!g.update_all && !chg) {
if (!g.update_all && !chg && curr->time) {
reset = hilite_reset_needed(prev, g.bl_hilite_moves);
if (reset)
curr->time = prev->time = 0L;
@@ -723,9 +772,11 @@ boolean *valsetlist;
if (anytype != ANY_MASK32) {
#ifdef STATUS_HILITES
if ((chg || *curr->val)) {
get_hilite_color(idx, fld, (genericptr_t) &curr->a,
chg, pc, &color);
if (chg || *curr->val) {
curr->hilite_rule = get_hilite(idx, fld,
(genericptr_t) &curr->a,
chg, pc, &color);
prev->hilite_rule = curr->hilite_rule;
if (chg == 2) {
color = NO_COLOR;
chg = 0;
@@ -733,11 +784,11 @@ boolean *valsetlist;
}
#endif /* STATUS_HILITES */
status_update(fld, (genericptr_t) curr->val,
chg, pc, color, &g.cond_hilites[0]);
chg, pc, color, (unsigned long *) 0);
} else {
/* Color for conditions is done through g.cond_hilites[] */
status_update(fld, (genericptr_t) &curr->a.a_ulong, chg, pc,
color, &g.cond_hilites[0]);
status_update(fld, (genericptr_t) &curr->a.a_ulong,
chg, pc, color, g.cond_hilites);
}
curr->chg = prev->chg = TRUE;
updated = TRUE;
@@ -746,8 +797,8 @@ boolean *valsetlist;
}
static void
evaluate_and_notify_windowport(valsetlist, idx, idx_p)
int idx, idx_p;
evaluate_and_notify_windowport(valsetlist, idx)
int idx;
boolean *valsetlist;
{
int i, updated = 0, notpresent = 0;
@@ -764,7 +815,7 @@ boolean *valsetlist;
notpresent++;
continue;
}
if (evaluate_and_notify_windowport_field(i, valsetlist, idx, idx_p))
if (eval_notify_windowport_field(i, valsetlist, idx))
updated++;
}
/*
@@ -792,13 +843,13 @@ boolean *valsetlist;
*/
if (g.context.botlx && (windowprocs.wincap2 & WC2_RESET_STATUS) != 0L)
status_update(BL_RESET, (genericptr_t) 0, 0, 0,
NO_COLOR, &g.cond_hilites[0]);
NO_COLOR, (unsigned long *) 0);
else if ((updated || g.context.botlx) &&
(windowprocs.wincap2 & WC2_FLUSH_STATUS) != 0L)
status_update(BL_FLUSH, (genericptr_t) 0, 0, 0,
NO_COLOR, &g.cond_hilites[0]);
NO_COLOR, (unsigned long *) 0);
g.context.botl = g.context.botlx = 0;
g.context.botl = g.context.botlx = iflags.time_botl = FALSE;
g.update_all = FALSE;
}
@@ -806,11 +857,12 @@ void
status_eval_next_unhilite()
{
int i;
struct istat_s *curr = NULL;
struct istat_s *curr;
long next_unhilite, this_unhilite;
g.bl_hilite_moves = g.moves;
/* figure out when the next unhilight needs to be performed */
g.bl_hilite_moves = g.moves; /* simpllfied; used to try to encode fractional
* amounts for multiple moves within same turn */
/* figure out whether an unhilight needs to be performed now */
next_unhilite = 0L;
for (i = 0; i < MAXBLSTATS; ++i) {
curr = &g.blstats[0][i]; /* g.blstats[0][*].time == g.blstats[1][*].time */
@@ -819,10 +871,17 @@ status_eval_next_unhilite()
struct istat_s *prev = &g.blstats[1][i];
#ifdef STATUS_HILITES
curr->time = prev->time = (g.bl_hilite_moves + iflags.hilite_delta);
if (Is_Temp_Hilite(curr->hilite_rule))
curr->time = prev->time = (g.bl_hilite_moves
+ iflags.hilite_delta);
else
curr->time = prev->time = 0L;
#endif
curr->chg = prev->chg = FALSE;
g.context.botl = TRUE;
}
if (g.context.botl)
continue; /* just process other g.blstats[][].time and .chg */
this_unhilite = curr->time;
if (this_unhilite > 0L
@@ -830,21 +889,22 @@ status_eval_next_unhilite()
#ifdef STATUS_HILITES
&& hilite_reset_needed(curr, this_unhilite + 1L)
#endif
)
) {
next_unhilite = this_unhilite;
if (next_unhilite < g.bl_hilite_moves)
g.context.botl = TRUE;
}
}
if (next_unhilite > 0L && next_unhilite < g.bl_hilite_moves)
g.context.botl = TRUE;
}
void
status_initialize(reassessment)
boolean
reassessment; /* TRUE = just reassess fields w/o other initialization*/
boolean reassessment; /* TRUE: just recheck fields w/o other initialization */
{
enum statusfields fld;
boolean fldenabl;
int i;
const char *fieldfmt = (const char *) 0;
const char *fieldname = (const char *) 0;
const char *fieldfmt, *fieldname;
if (!reassessment) {
if (g.blinit)
@@ -852,22 +912,22 @@ boolean
init_blstats();
(*windowprocs.win_status_init)();
g.blinit = TRUE;
} else if (!g.blinit) {
panic("status 'reassess' before init");
}
for (i = 0; i < MAXBLSTATS; ++i) {
enum statusfields fld = initblstats[i].fld;
boolean fldenabled = (fld == BL_SCORE) ? flags.showscore
: (fld == BL_XP) ? (boolean) !Upolyd
: (fld == BL_HD) ? (boolean) Upolyd
: (fld == BL_TIME) ? flags.time
: (fld == BL_EXP) ? (boolean) (flags.showexp && !Upolyd)
: TRUE;
fld = initblstats[i].fld;
fldenabl = (fld == BL_SCORE) ? flags.showscore
: (fld == BL_TIME) ? flags.time
: (fld == BL_EXP) ? (boolean) (flags.showexp && !Upolyd)
: (fld == BL_XP) ? (boolean) !Upolyd
: (fld == BL_HD) ? (boolean) Upolyd
: TRUE;
fieldname = initblstats[i].fldname;
if (fld == BL_TITLE && iflags.wc2_hitpointbar)
fieldfmt = "%-30s";
else
fieldfmt = initblstats[i].fldfmt;
status_enablefield(fld, fieldname, fieldfmt, fldenabled);
fieldfmt = (fld == BL_TITLE && iflags.wc2_hitpointbar) ? "%-30.30s"
: initblstats[i].fldfmt;
status_enablefield(fld, fieldname, fieldfmt, fldenabl);
}
g.update_all = TRUE;
}
@@ -888,14 +948,17 @@ status_finish()
if (g.blstats[1][i].val)
free((genericptr_t) g.blstats[1][i].val), g.blstats[1][i].val = 0;
#ifdef STATUS_HILITES
/* pointer to an entry in thresholds list; Null it out since
that list is about to go away */
g.blstats[0][i].hilite_rule = g.blstats[1][i].hilite_rule = 0;
if (g.blstats[0][i].thresholds) {
struct hilite_s *temp, *next = 0;
struct hilite_s *temp, *next;
for (temp = g.blstats[0][i].thresholds; temp; temp = next) {
next = temp->next;
free((genericptr_t) temp);
g.blstats[0][i].thresholds = g.blstats[1][i].thresholds = 0;
}
g.blstats[0][i].thresholds = g.blstats[1][i].thresholds = 0;
}
#endif /* STATUS_HILITES */
}
@@ -911,9 +974,7 @@ init_blstats()
impossible("init_blstats called more than once.");
return;
}
initalready = TRUE;
for (i = BEFORE; i <= NOW; ++i) {
for (i = 0; i <= 1; ++i) {
for (j = 0; j < MAXBLSTATS; ++j) {
#ifdef STATUS_HILITES
struct hilite_s *keep_hilite_chain = g.blstats[i][j].thresholds;
@@ -931,6 +992,7 @@ init_blstats()
#endif
}
}
initalready = TRUE;
}
/*
@@ -1192,7 +1254,7 @@ struct istat_s *bl, *maxbl;
/* Core status hiliting support */
/****************************************************************************/
static const struct fieldid_t {
static struct fieldid_t {
const char *fieldname;
enum statusfields fldid;
} fieldids_alias[] = {
@@ -1279,26 +1341,19 @@ hilite_reset_needed(bl_p, augmented_time)
struct istat_s *bl_p;
long augmented_time;
{
struct hilite_s *tl = bl_p->thresholds;
/*
* This 'multi' handling may need some tuning...
*/
if (g.multi)
return FALSE;
if (!Is_Temp_Hilite(bl_p->hilite_rule))
return FALSE;
if (bl_p->time == 0 || bl_p->time >= augmented_time)
return FALSE;
while (tl) {
/* only this style times out (includes general 'changed'
as well as specific 'up' and 'down') */
if (tl->behavior == BL_TH_UPDOWN)
return TRUE;
tl = tl->next;
}
return FALSE;
return TRUE;
}
/* called by options handling when 'statushilites' boolean is toggled */
@@ -1329,33 +1384,13 @@ const char *hl_text;
return FALSE;
}
STATIC_OVL void
merge_bestcolor(bestcolor, newcolor)
int *bestcolor;
int newcolor;
{
int natr = HL_UNDEF, nclr = NO_COLOR;
split_clridx(newcolor, &nclr, &natr);
if (nclr != NO_COLOR)
*bestcolor = (*bestcolor & 0xff00) | nclr;
if (natr != HL_UNDEF) {
if (natr == HL_NONE)
*bestcolor = *bestcolor & 0x00ff; /* reset all attributes */
else
*bestcolor |= (natr << 8); /* merge attributes */
}
}
/*
* get_hilite_color
* get_hilite
*
* Figures out, based on the value and the direction it is moving,
* the color that the field should be displayed in.
* Returns, based on the value and the direction it is moving,
* the highlight rule that applies to the specified field.
*
* Provide get_hilite_color() with the following to work with:
* Provide get_hilite() with the following to work with:
* actual value vp
* useful for BL_TH_VAL_ABSOLUTE
* indicator of down, up, or the same (-1, 1, 0) chg
@@ -1364,28 +1399,22 @@ int newcolor;
* useful for BL_TH_VAL_PERCENTAGE
*
* Get back:
* color based on user thresholds set in config file.
* The rightmost 8 bits contain a color index.
* The 8 bits to the left of that contain
* the attribute bits.
* color = 0x00FF
* attrib= 0xFF00
* pointer to rule that applies; Null if no rule does.
*/
STATIC_OVL void
get_hilite_color(idx, fldidx, vp, chg, pc, colorptr)
STATIC_OVL struct hilite_s *
get_hilite(idx, fldidx, vp, chg, pc, colorptr)
int idx, fldidx, chg, pc;
genericptr_t vp;
int *colorptr;
{
int bestcolor = NO_COLOR;
struct hilite_s *hl;
struct hilite_s *hl, *rule = 0;
anything *value = (anything *) vp;
char *txtstr;
if (!colorptr || fldidx < 0 || fldidx >= MAXBLSTATS)
return;
if (fldidx < 0 || fldidx >= MAXBLSTATS)
return (struct hilite_s *) 0;
if (g.blstats[idx][fldidx].thresholds) {
if (has_hilite(fldidx)) {
int dt;
/* there are hilites set here */
int max_pc = -1, min_pc = 101;
@@ -1399,7 +1428,7 @@ int *colorptr;
perc_or_abs = FALSE;
/* min_/max_ are used to track best fit */
for (hl = g.blstats[idx][fldidx].thresholds; hl; hl = hl->next) {
for (hl = g.blstats[0][fldidx].thresholds; hl; hl = hl->next) {
dt = initblstats[fldidx].anytype; /* only needed for 'absolute' */
/* if we've already matched a temporary highlight, it takes
precedence over all persistent ones; we still process
@@ -1414,7 +1443,7 @@ int *colorptr;
switch (hl->behavior) {
case BL_TH_VAL_PERCENTAGE: /* percent values are always ANY_INT */
if (hl->rel == EQ_VALUE && pc == hl->value.a_int) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_pc = max_pc = hl->value.a_int;
exactmatch = perc_or_abs = TRUE;
} else if (exactmatch) {
@@ -1422,25 +1451,25 @@ int *colorptr;
} else if (hl->rel == LT_VALUE
&& (pc < hl->value.a_int)
&& (hl->value.a_int <= min_pc)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_pc = hl->value.a_int;
perc_or_abs = TRUE;
} else if (hl->rel == LE_VALUE
&& (pc <= hl->value.a_int)
&& (hl->value.a_int <= min_pc)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_pc = hl->value.a_int;
perc_or_abs = TRUE;
} else if (hl->rel == GT_VALUE
&& (pc > hl->value.a_int)
&& (hl->value.a_int >= max_pc)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
max_pc = hl->value.a_int;
perc_or_abs = TRUE;
} else if (hl->rel == GE_VALUE
&& (pc >= hl->value.a_int)
&& (hl->value.a_int >= max_pc)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
max_pc = hl->value.a_int;
perc_or_abs = TRUE;
}
@@ -1449,13 +1478,13 @@ int *colorptr;
/* specific 'up' or 'down' takes precedence over general
'changed' regardless of their order in the rule set */
if (chg < 0 && hl->rel == LT_VALUE) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
updown = TRUE;
} else if (chg > 0 && hl->rel == GT_VALUE) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
updown = TRUE;
} else if (chg != 0 && hl->rel == EQ_VALUE && !updown) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
changed = TRUE;
}
break;
@@ -1468,7 +1497,7 @@ int *colorptr;
if (dt == ANY_INT) {
if (hl->rel == EQ_VALUE
&& hl->value.a_int == value->a_int) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_ival = max_ival = hl->value.a_int;
exactmatch = perc_or_abs = TRUE;
} else if (exactmatch) {
@@ -1476,32 +1505,32 @@ int *colorptr;
} else if (hl->rel == LT_VALUE
&& (value->a_int < hl->value.a_int)
&& (hl->value.a_int <= min_ival)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_ival = hl->value.a_int;
perc_or_abs = TRUE;
} else if (hl->rel == LE_VALUE
&& (value->a_int <= hl->value.a_int)
&& (hl->value.a_int <= min_ival)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_ival = hl->value.a_int;
perc_or_abs = TRUE;
} else if (hl->rel == GT_VALUE
&& (value->a_int > hl->value.a_int)
&& (hl->value.a_int >= max_ival)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
max_ival = hl->value.a_int;
perc_or_abs = TRUE;
} else if (hl->rel == GE_VALUE
&& (value->a_int >= hl->value.a_int)
&& (hl->value.a_int >= max_ival)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
max_ival = hl->value.a_int;
perc_or_abs = TRUE;
}
} else { /* ANY_LONG */
if (hl->rel == EQ_VALUE
&& hl->value.a_long == value->a_long) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_lval = max_lval = hl->value.a_long;
exactmatch = perc_or_abs = TRUE;
} else if (exactmatch) {
@@ -1509,25 +1538,25 @@ int *colorptr;
} else if (hl->rel == LT_VALUE
&& (value->a_long < hl->value.a_long)
&& (hl->value.a_long <= min_lval)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_lval = hl->value.a_long;
perc_or_abs = TRUE;
} else if (hl->rel == LE_VALUE
&& (value->a_long <= hl->value.a_long)
&& (hl->value.a_long <= min_lval)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_lval = hl->value.a_long;
perc_or_abs = TRUE;
} else if (hl->rel == GT_VALUE
&& (value->a_long > hl->value.a_long)
&& (hl->value.a_long >= max_lval)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
max_lval = hl->value.a_long;
perc_or_abs = TRUE;
} else if (hl->rel == GE_VALUE
&& (value->a_long >= hl->value.a_long)
&& (hl->value.a_long >= max_lval)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
max_lval = hl->value.a_long;
perc_or_abs = TRUE;
}
@@ -1540,18 +1569,18 @@ int *colorptr;
txtstr += (strlen(g.plname) + sizeof " the " - sizeof "");
if (hl->rel == TXT_VALUE && hl->textmatch[0]) {
if (fuzzymatch(hl->textmatch, txtstr, "\" -_", TRUE)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
exactmatch = TRUE;
} else if (exactmatch) {
; /* already found best fit, skip "noneoftheabove" */
} else if (fldidx == BL_TITLE
&& Upolyd && noneoftheabove(hl->textmatch)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
}
}
break;
case BL_TH_ALWAYS_HILITE:
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
break;
case BL_TH_NONE:
break;
@@ -1560,8 +1589,8 @@ int *colorptr;
}
}
}
*colorptr = bestcolor;
return;
*colorptr = rule ? rule->coloridx : NO_COLOR;
return rule;
}
STATIC_OVL void
@@ -2071,9 +2100,9 @@ boolean from_configfile;
hilite.anytype = dt;
if (hilite.behavior == BL_TH_TEXTMATCH && txt
&& strlen(txt) < QBUFSZ - 1) {
Strcpy(hilite.textmatch, txt);
if (hilite.behavior == BL_TH_TEXTMATCH && txt) {
(void) strncpy(hilite.textmatch, txt, sizeof hilite.textmatch);
hilite.textmatch[sizeof hilite.textmatch - 1] = '\0';
(void) trimspaces(hilite.textmatch);
}
@@ -2259,6 +2288,15 @@ int sidx;
/*3.6.1:
OPTION=hilite_status: condition/stone+slime+foodPois/red&inverse */
/*
* TODO?
* It would be simpler to treat each condition (also hunger state
* and encumbrance level) as if it were a separate field. That
* way they could have either or both 'changed' temporary rule and
* 'always' persistent rule and wouldn't need convoluted access to
* the intended color and attributes.
*/
sidx++;
while(s[sidx]) {
int sf = 0; /* subfield count */
@@ -2362,17 +2400,15 @@ clear_status_hilites()
int i;
for (i = 0; i < MAXBLSTATS; ++i) {
if (g.blstats[0][i].thresholds) {
struct hilite_s *temp = g.blstats[0][i].thresholds,
*next = (struct hilite_s *)0;
while (temp) {
next = temp->next;
free(temp);
g.blstats[0][i].thresholds = (struct hilite_s *)0;
g.blstats[1][i].thresholds = g.blstats[0][i].thresholds;
temp = next;
}
struct hilite_s *temp, *next;
for (temp = g.blstats[0][i].thresholds; temp; temp = next) {
next = temp->next;
free(temp);
}
g.blstats[0][i].thresholds = g.blstats[1][i].thresholds = 0;
/* pointer into thresholds list, now stale */
g.blstats[0][i].hilite_rule = g.blstats[1][i].hilite_rule = 0;
}
}
@@ -3152,7 +3188,7 @@ choose_value:
Strcpy(hilite.textmatch, hutxt[rv]);
} else if (fld == BL_TITLE) {
const char *rolelist[3 * 9 + 1];
char mbuf[QBUFSZ], fbuf[QBUFSZ], obuf[QBUFSZ];
char mbuf[MAXVALWIDTH], fbuf[MAXVALWIDTH], obuf[MAXVALWIDTH];
int i, j, rv;
for (i = j = 0; i < 9; i++) {
@@ -3199,7 +3235,7 @@ choose_value:
goto choose_behavior;
hilite.rel = TXT_VALUE;
if (strlen(inbuf) < QBUFSZ - 1)
if (strlen(inbuf) < sizeof hilite.textmatch)
Strcpy(hilite.textmatch, inbuf);
else
return FALSE;
@@ -3309,25 +3345,25 @@ int id;
return TRUE;
} else {
int fld = hlstr->fld;
struct hilite_s *hl = g.blstats[0][fld].thresholds;
struct hilite_s *hlprev = (struct hilite_s *) 0;
struct hilite_s *hl, *hlprev = (struct hilite_s *) 0;
if (hl) {
while (hl) {
if (hlstr->hl == hl) {
if (hlprev) {
hlprev->next = hl->next;
} else {
g.blstats[0][fld].thresholds = hl->next;
g.blstats[1][fld].thresholds =
g.blstats[0][fld].thresholds;
}
free((genericptr_t) hl);
return TRUE;
for (hl = g.blstats[0][fld].thresholds; hl; hl = hl->next) {
if (hlstr->hl == hl) {
if (hlprev) {
hlprev->next = hl->next;
} else {
g.blstats[0][fld].thresholds = hl->next;
g.blstats[1][fld].thresholds = g.blstats[0][fld].thresholds;
}
hlprev = hl;
hl = hl->next;
if (g.blstats[0][fld].hilite_rule == hl) {
g.blstats[0][fld].hilite_rule
= g.blstats[1][fld].hilite_rule = (struct hilite_s *) 0;
g.blstats[0][fld].time = g.blstats[1][fld].time = 0L;
}
free((genericptr_t) hl);
return TRUE;
}
hlprev = hl;
}
}
return FALSE;

View File

@@ -220,6 +220,7 @@ const struct instance_globals g_init = {
UNDEFINED_VALUES, /* valset */
0, /* bl_hilite_moves */
UNDEFINED_VALUES, /* cond_hilites */
0, /* now_or_before_idx */
/* cmd.c */
UNDEFINED_VALUES, /* Cmd */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 display.c $NHDT-Date: 1551138503 2019/02/25 23:48:23 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.97 $ */
/* NetHack 3.6 display.c $NHDT-Date: 1554045810 2019/03/31 15:23:30 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.99 $ */
/* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
/* and Dave Cohrs, 1990. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1213,8 +1213,7 @@ int mode;
}
}
/* =========================================================================
*/
/* ======================================================================== */
/*
* Loop through all of the monsters and update them. Called when:
@@ -1380,10 +1379,39 @@ docrt()
g.context.botlx = 1; /* force a redraw of the bottom line */
}
/* =========================================================================
*/
/* Glyph Buffering (3rd screen) ============================================
*/
/* for panning beyond a clipped region; resend the current map data to
the interface rather than use docrt()'s regeneration of that data */
void
redraw_map()
{
int x, y, glyph;
/*
* Not sure whether this is actually necessary; save and restore did
* used to get much too involved with each dungeon level as it was
* read and written.
*
* !u.ux: display isn't ready yet; (restoring || !on_level()): was part
* of cliparound() but interface shouldn't access this much internals
*/
if (!u.ux || g.restoring || !on_level(&u.uz0, &u.uz))
return;
/*
* This yields sensible clipping when #terrain+getpos is in
* progress and the screen displays something other than what
* the map would currently be showing.
*/
for (y = 0; y < ROWNO; ++y)
for (x = 1; x < COLNO; ++x) {
glyph = glyph_at(x, y); /* not levl[x][y].glyph */
print_glyph(WIN_MAP, x, y, glyph, get_bk_glyph(x, y));
}
flush_screen(1);
}
/* ======================================================================== */
/* Glyph Buffering (3rd screen) =========================================== */
/* FIXME: This is a dirty hack, because newsym() doesn't distinguish
* between object piles and single objects, it doesn't mark the location
@@ -1527,7 +1555,7 @@ int start, stop, y;
for (x = start; x <= stop; x++)
if (g.gbuf[y][x].glyph != cmap_to_glyph(S_stone))
print_glyph(WIN_MAP, x, y, g.gbuf[y][x].glyph, get_bk_glyph(x,y));
print_glyph(WIN_MAP, x, y, g.gbuf[y][x].glyph, get_bk_glyph(x, y));
}
void
@@ -1588,10 +1616,11 @@ int cursor_on_u;
flushing = 0;
if (g.context.botl || g.context.botlx)
bot();
else if (iflags.time_botl)
timebot();
}
/* =========================================================================
*/
/* ======================================================================== */
/*
* back_to_glyph()
@@ -1795,16 +1824,19 @@ xchar x, y;
/*
* This will be used to get the glyph for the background so that
* it can potentially be merged into graphical window ports
* to improve the appearance of stuff on dark room
* squares and the plane of air etc.
* it can potentially be merged into graphical window ports to
* improve the appearance of stuff on dark room squares and the
* plane of air etc.
*
* Until that is working correctly in the branch, however, for now
* we just return NO_GLYPH as an indicator to ignore it.
*
* [This should be using background as recorded for #overview rather
* than current data from the map.]
*/
STATIC_OVL int
get_bk_glyph(x,y)
get_bk_glyph(x, y)
xchar x, y;
{
int idx, bkglyph = NO_GLYPH;

View File

@@ -51,9 +51,9 @@ boolean FDECL((*gp_getvalidf), (int, int));
}
static const char *const gloc_descr[NUM_GLOCS][4] = {
{ "any monsters", "monster", "next monster", "monsters" },
{ "any items", "item", "next object", "objects" },
{ "any doors", "door", "next door or doorway", "doors or doorways" },
{ "any monsters", "monster", "next/previous monster", "monsters" },
{ "any items", "item", "next/previous object", "objects" },
{ "any doors", "door", "next/previous door or doorway", "doors or doorways" },
{ "any unexplored areas", "unexplored area", "unexplored location",
"unexplored locations" },
{ "anything interesting", "interesting thing", "anything interesting",
@@ -77,7 +77,7 @@ int gloc;
{
char sbuf[BUFSZ];
Sprintf(sbuf, "Use '%s' or '%s' to %s%s%s.",
Sprintf(sbuf, "Use '%s'/'%s' to %s%s%s.",
k1, k2,
iflags.getloc_usemenu ? "get a menu of "
: "move the cursor to ",

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 end.c $NHDT-Date: 1553652951 2019/03/27 02:15:51 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.166 $ */
/* NetHack 3.6 end.c $NHDT-Date: 1554045810 2019/03/31 15:23:30 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.167 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1025,7 +1025,7 @@ int how;
#endif
) {
/* skip status update if panicking or disconnected */
g.context.botl = g.context.botlx = FALSE;
g.context.botl = g.context.botlx = iflags.time_botl = FALSE;
} else {
/* otherwise force full status update */
g.context.botlx = TRUE;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 options.c $NHDT-Date: 1553480404 2019/03/25 02:20:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.360 $ */
/* NetHack 3.6 options.c $NHDT-Date: 1554155747 2019/04/01 21:55:47 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.362 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2008. */
/* NetHack may be freely redistributed. See license for details. */
@@ -114,7 +114,7 @@ static const struct Bool_Opt {
{ "confirm", &flags.confirm, TRUE, SET_IN_GAME },
{ "dark_room", &flags.dark_room, TRUE, SET_IN_GAME },
{ "eight_bit_tty", &iflags.wc_eight_bit_input, FALSE, SET_IN_GAME }, /*WC*/
#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) || defined(X11_GRAPHICS)
{ "extmenu", &iflags.extmenu, FALSE, SET_IN_GAME },
#else
{ "extmenu", (boolean *) 0, FALSE, SET_IN_FILE },
@@ -385,20 +385,23 @@ static struct Comp_Opt {
#ifdef MSDOS
{ "soundcard", "type of sound card to use", 20, SET_IN_FILE },
#endif
#ifdef STATUS_HILITES
{ "statushilites",
#ifdef STATUS_HILITES
"0=no status highlighting, N=show highlights for N turns",
20, SET_IN_GAME },
20, SET_IN_GAME
#else
{ "statushilites", "highlight control", 20, SET_IN_FILE },
"highlight control", 20, SET_IN_FILE
#endif
#ifdef CURSES_GRAPHICS
},
{ "statuslines",
#ifdef CURSES_GRAPHICS
"2 or 3 lines for horizonal (bottom or top) status display",
20, SET_IN_GAME }, /*WC2*/
20, SET_IN_GAME
#else
{ "statuslines", "2 or 3 lines for status display", 20, SET_IN_FILE },
"2 or 3 lines for status display",
20, SET_IN_FILE
#endif
}, /*WC2*/
{ "symset", "load a set of display symbols from the symbols file", 70,
SET_IN_GAME },
{ "roguesymset",
@@ -3693,6 +3696,7 @@ boolean tinitial, tfrom_file;
}
return retval;
}
#endif /* CURSES_GRAPHICS */
/* WINCAP2
* statuslines:n */
@@ -3718,7 +3722,6 @@ boolean tinitial, tfrom_file;
}
return retval;
}
#endif /* CURSES_GRAPHICS */
/* menustyle:traditional or combination or full or partial */
fullname = "menustyle";
@@ -5725,8 +5728,9 @@ char *buf;
iflags.hilite_delta, iflags.hilite_delta);
#endif
} else if (!strcmp(optname,"statuslines")) {
Strcpy(buf, (WINDOWPORT("curses")
&& iflags.wc2_statuslines < 3) ? "2" : "3");
if (wc2_supported(optname))
Strcpy(buf, (iflags.wc2_statuslines < 3) ? "2" : "3");
/* else default to "unknown" */
} else if (!strcmp(optname, "suppress_alert")) {
if (flags.suppress_alert == 0L)
Strcpy(buf, none);

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1550524566 2019/02/18 21:16:06 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.110 $ */
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1553787633 2019/03/28 15:40:33 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.111 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */
@@ -4691,13 +4691,16 @@ struct sp_coder *coder;
{
static const char nhFunc[] = "spo_drawbridge";
xchar x, y;
int dopen;
struct opvar *dir, *db_open, *dcoord;
if (!OV_pop_i(dir) || !OV_pop_i(db_open) || !OV_pop_c(dcoord))
return;
get_location_coord(&x, &y, DRY | WET | HOT, coder->croom, OV_i(dcoord));
if (!create_drawbridge(x, y, OV_i(dir), OV_i(db_open)))
if ((dopen = OV_i(db_open)) == -1)
dopen = !rn2(2);
if (!create_drawbridge(x, y, OV_i(dir), dopen ? TRUE : FALSE))
impossible("Cannot create drawbridge.");
g.SpLev_Map[x][y] = 1;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 teleport.c $NHDT-Date: 1550524567 2019/02/18 21:16:07 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.85 $ */
/* NetHack 3.6 teleport.c $NHDT-Date: 1553885439 2019/03/29 18:50:39 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.86 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
@@ -475,7 +475,7 @@ struct obj *scroll;
Strcpy(whobuf, "you");
if (u.usteed)
Sprintf(eos(whobuf), " and %s", mon_nam(u.usteed));
pline("To what position do %s want to be teleported?", whobuf);
pline("Where do %s want to be teleported?", whobuf);
cc.x = u.ux;
cc.y = u.uy;
if (getpos(&cc, TRUE, "the desired position") < 0)