hilite_status attributes

Take a step towards eliminating merging hilite_status rules during
highlighting by creating a single rule instead of multiple ones
when specifying multiple attributes for the same highlight via the
'O' command's menus.

Old:
 (pick_one menu to pick a color) + (pick_one menu to pick an attribute)
| hilite_status:title/always/red&bold
 (pick_one menu to pick a color) + (pick_one menu to pick an attribute)
| hilite_status:title/always/red&blink
New:
 (pick_one menu to pick a color) + (pick_any menu to pick attributes)
| hilite_status:title/always/red&bold+blink

At present, rule selection during highlighting still merges multiple
applicable rules instead of finding the best one first, with the
problems that entails.

Bonus fix:  a hilite_status rule for status conditions which specified
"no attributes" would clear attributes for all previous condition
rules rather than just the one(s) in that "no attributes" rule.
This commit is contained in:
PatR
2018-06-23 17:37:54 -07:00
parent 8c2bd75ce4
commit 699e65fa34
3 changed files with 99 additions and 51 deletions

View File

@@ -46,6 +46,12 @@ wishing for "glob of grey ooze" failed even though grey ooze is recognized
as a variant spelling for gray ooze
spells of healing and extra healing cast at monsters handled monster blindness
inconsistently compared to other healing
when using the 'O' command to create a status highlight that specifies
multiple attributes (blink+inverse, &c), pick all of them in one menu
selection and create a single hilite_status rule instead of having
separate rules for each attribute to be merged when highlighting
highlighting status conditions would fail to use attributes if a rule with
them was followed by another one without (color only or color&normal)
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository

View File

@@ -2282,11 +2282,11 @@ int sidx;
else if (a == ATR_BOLD)
cond_hilites[HL_ATTCLR_BOLD] |= conditions_bitmask;
else if (a == ATR_NONE) {
cond_hilites[HL_ATTCLR_DIM] = 0UL;
cond_hilites[HL_ATTCLR_BLINK] = 0UL;
cond_hilites[HL_ATTCLR_ULINE] = 0UL;
cond_hilites[HL_ATTCLR_INVERSE] = 0UL;
cond_hilites[HL_ATTCLR_BOLD] = 0UL;
cond_hilites[HL_ATTCLR_DIM] &= ~conditions_bitmask;
cond_hilites[HL_ATTCLR_BLINK] &= ~conditions_bitmask;
cond_hilites[HL_ATTCLR_ULINE] &= ~conditions_bitmask;
cond_hilites[HL_ATTCLR_INVERSE] &= ~conditions_bitmask;
cond_hilites[HL_ATTCLR_BOLD] &= ~conditions_bitmask;
} else {
int k = match_str2clr(subfields[i]);
@@ -2507,7 +2507,8 @@ status_hilite_linestr_gather_conditions()
char condbuf[BUFSZ];
char *tmpattr;
(void) stripchars(clrbuf, " ", clr2colorname(clr));
(void) strNsubst(strcpy(clrbuf, clr2colorname(clr)),
" ", "-", 0);
tmpattr = hlattr2attrname(atr, attrbuf, BUFSZ);
if (tmpattr)
Sprintf(eos(clrbuf), "&%s", tmpattr);
@@ -2608,14 +2609,10 @@ struct hilite_s *hl;
}
split_clridx(hl->coloridx, &clr, &attr);
if (clr != NO_COLOR)
(void) stripchars(clrbuf, " ", clr2colorname(clr));
(void) strNsubst(strcpy(clrbuf, clr2colorname(clr)), " ", "-", 0);
if (attr != HL_UNDEF) {
tmpattr = hlattr2attrname(attr, attrbuf, BUFSZ);
if (tmpattr)
Sprintf(eos(clrbuf), "%s%s",
(clr != NO_COLOR) ? "&" : "",
tmpattr);
if ((tmpattr = hlattr2attrname(attr, attrbuf, BUFSZ)) != 0)
Sprintf(eos(clrbuf), "&%s", tmpattr);
}
Sprintf(buf, "%s/%s/%s", initblstats[hl->fld].fldname, behavebuf, clrbuf);
@@ -3154,52 +3151,34 @@ choose_color:
else
goto choose_behavior;
}
atr = query_attr(attrqry); /* FIXME: pick multiple attrs */
atr = query_attr(attrqry);
if (atr == -1)
goto choose_color;
if (atr == ATR_DIM)
atr = HL_DIM;
else if (atr == ATR_BLINK)
atr = HL_BLINK;
else if (atr == ATR_ULINE)
atr = HL_ULINE;
else if (atr == ATR_INVERSE)
atr = HL_INVERSE;
else if (atr == ATR_BOLD)
atr = HL_BOLD;
else if (atr == ATR_NONE)
atr = HL_NONE;
else
atr = HL_UNDEF;
if (clr == -1)
clr = NO_COLOR;
if (behavior == BL_TH_CONDITION) {
char clrbuf[BUFSZ];
char attrbuf[BUFSZ];
char *tmpattr;
if (atr == HL_DIM)
if (atr & HL_DIM)
cond_hilites[HL_ATTCLR_DIM] |= cond;
else if (atr == HL_BLINK)
else if (atr & HL_BLINK)
cond_hilites[HL_ATTCLR_BLINK] |= cond;
else if (atr == HL_ULINE)
else if (atr & HL_ULINE)
cond_hilites[HL_ATTCLR_ULINE] |= cond;
else if (atr == HL_INVERSE)
else if (atr & HL_INVERSE)
cond_hilites[HL_ATTCLR_INVERSE] |= cond;
else if (atr == HL_BOLD)
else if (atr & HL_BOLD)
cond_hilites[HL_ATTCLR_BOLD] |= cond;
else if (atr == HL_NONE) {
cond_hilites[HL_ATTCLR_DIM] = 0UL;
cond_hilites[HL_ATTCLR_BLINK] = 0UL;
cond_hilites[HL_ATTCLR_ULINE] = 0UL;
cond_hilites[HL_ATTCLR_INVERSE] = 0UL;
cond_hilites[HL_ATTCLR_BOLD] = 0UL;
cond_hilites[HL_ATTCLR_DIM] &= ~cond;
cond_hilites[HL_ATTCLR_BLINK] &= ~cond;
cond_hilites[HL_ATTCLR_ULINE] &= ~cond;
cond_hilites[HL_ATTCLR_INVERSE] &= ~cond;
cond_hilites[HL_ATTCLR_BOLD] &= ~cond;
}
cond_hilites[clr] |= cond;
(void) stripchars(clrbuf, " ", clr2colorname(clr));
(void) strNsubst(strcpy(clrbuf, clr2colorname(clr)), " ", "-", 0);
tmpattr = hlattr2attrname(atr, attrbuf, BUFSZ);
if (tmpattr)
Sprintf(eos(clrbuf), "&%s", tmpattr);

View File

@@ -1417,19 +1417,31 @@ const char *prompt;
break;
any.a_int = i + 1;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, colornames[i].name,
MENU_UNSELECTED);
(colornames[i].color == NO_COLOR) ? MENU_SELECTED
: MENU_UNSELECTED);
}
end_menu(tmpwin, (prompt && *prompt) ? prompt : "Pick a color");
pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
destroy_nhwindow(tmpwin);
if (pick_cnt > 0) {
i = colornames[picks->item.a_int - 1].color;
i = colornames[picks[0].item.a_int - 1].color;
/* pick_cnt==2: explicitly picked something other than the
preselected entry */
if (pick_cnt == 2 && i == NO_COLOR)
i = colornames[picks[1].item.a_int - 1].color;
free((genericptr_t) picks);
return i;
} else if (pick_cnt == 0) {
/* pick_cnt==0: explicitly picking preselected entry toggled it off */
return NO_COLOR;
}
return -1;
}
/* ask about highlighting attribute; for menu headers and menu
coloring patterns, only one attribute at a time is allowed;
for status highlighting, multiple attributes are allowed [overkill;
life would be much simpler if that were restricted to one also...] */
int
query_attr(prompt)
const char *prompt;
@@ -1438,7 +1450,11 @@ const char *prompt;
anything any;
int i, pick_cnt;
menu_item *picks = (menu_item *) 0;
boolean allow_many = (prompt && !strncmpi(prompt, "Choose", 6));
int default_attr = ATR_NONE;
if (prompt && strstri(prompt, "menu headings"))
default_attr = iflags.menu_headings;
tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin);
any = zeroany;
@@ -1447,16 +1463,61 @@ const char *prompt;
break;
any.a_int = i + 1;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, attrnames[i].attr,
attrnames[i].name, MENU_UNSELECTED);
attrnames[i].name,
(attrnames[i].attr == default_attr) ? MENU_SELECTED
: MENU_UNSELECTED);
}
end_menu(tmpwin, (prompt && *prompt) ? prompt : "Pick an attribute");
pick_cnt = select_menu(tmpwin, PICK_ONE, &picks);
pick_cnt = select_menu(tmpwin, allow_many ? PICK_ANY: PICK_ONE, &picks);
destroy_nhwindow(tmpwin);
if (pick_cnt > 0) {
i = attrnames[picks->item.a_int - 1].attr;
int j, k = 0;
if (allow_many) {
/* PICK_ANY, with one preselected entry which should be
excluded if any other choices were picked */
for (i = 0; i < pick_cnt; ++i) {
j = picks[i].item.a_int - 1;
if (attrnames[j].attr != ATR_NONE || pick_cnt == 1) {
switch (attrnames[j].attr) {
case ATR_DIM:
k |= HL_DIM;
break;
case ATR_BLINK:
k |= HL_BLINK;
break;
case ATR_ULINE:
k |= HL_ULINE;
break;
case ATR_INVERSE:
k |= HL_INVERSE;
break;
case ATR_BOLD:
k |= HL_BOLD;
break;
case ATR_NONE:
k = HL_NONE;
break;
}
}
}
} else {
/* PICK_ONE, but might get 0 or 2 due to preselected entry */
j = picks[0].item.a_int - 1;
/* pick_cnt==2: explicitly picked something other than the
preselected entry */
if (pick_cnt == 2 && attrnames[j].attr == default_attr)
j = picks[1].item.a_int - 1;
k = attrnames[j].attr;
}
free((genericptr_t) picks);
return i;
return k;
} else if (pick_cnt == 0 && !allow_many) {
/* PICK_ONE, preselected entry explicitly chosen */
return default_attr;
}
/* either ESC to explicitly cancel (pick_cnt==-1) or
PICK_ANY with preselected entry toggled off and nothing chosen */
return -1;
}
@@ -4872,6 +4933,7 @@ boolean setinitial, setfromfile;
const char *sattr, *sclr;
menu_item *pick_list = (menu_item *) 0;
struct menucoloring *tmp = menu_colorings;
char clrbuf[QBUFSZ];
tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin);
@@ -4879,11 +4941,12 @@ boolean setinitial, setfromfile;
mc_idx = 0;
while (tmp) {
sattr = attr2attrname(tmp->attr);
sclr = clr2colorname(tmp->color);
sclr = strcpy(clrbuf, clr2colorname(tmp->color));
(void) strNsubst(clrbuf, " ", "-", 0);
any.a_int = ++mc_idx;
/* construct suffix */
Sprintf(buf, "\"\"=%s%s%s", sclr,
(tmp->attr != ATR_NONE) ? " & " : "",
(tmp->attr != ATR_NONE) ? "&" : "",
(tmp->attr != ATR_NONE) ? sattr : "");
/* now main string */
ln = sizeof buf - strlen(buf) - 1; /* length available */