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