diff --git a/doc/fixes36.2 b/doc/fixes36.2 index fc7a7218e..7de916495 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -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 diff --git a/src/botl.c b/src/botl.c index 1548aef70..797e29d0b 100644 --- a/src/botl.c +++ b/src/botl.c @@ -2156,6 +2156,7 @@ const char *str; if (!nmatches) { /* check partial matches to aliases */ int len = (int) strlen(str); + for (i = 0; i < SIZE(condition_aliases); i++) if (!strncmpi(str, condition_aliases[i].id, len)) { mask |= condition_aliases[i].bitmask; @@ -2282,11 +2283,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]); @@ -2335,7 +2336,7 @@ char *buf; int k, first = 0; attbuf[0] = '\0'; - if (attrib & HL_NONE) { + if (attrib == HL_NONE) { Strcpy(buf, "normal"); return buf; } @@ -2383,8 +2384,9 @@ const char *str; tmp = (struct _status_hilite_line_str *) alloc(sizeof *tmp); (void) memset(tmp, 0, sizeof *tmp); + tmp->next = (struct _status_hilite_line_str *) 0; - ++status_hilite_str_id; + tmp->id = ++status_hilite_str_id; tmp->fld = fld; tmp->hl = hl; tmp->mask = mask; @@ -2392,14 +2394,12 @@ const char *str; Strcpy(tmp->str, str); else (void) stripchars(tmp->str, " ", str); - tmp->id = status_hilite_str_id; if ((nxt = status_hilite_str) != 0) { while (nxt->next) nxt = nxt->next; nxt->next = tmp; } else { - tmp->next = (struct _status_hilite_line_str *) 0; status_hilite_str = tmp; } } @@ -2462,8 +2462,10 @@ status_hilite_linestr_gather_conditions() int j; for (j = 0; j < CLR_MAX; j++) - if (cond_hilites[j] & valid_conditions[i].bitmask) + if (cond_hilites[j] & valid_conditions[i].bitmask) { clr = j; + break; + } if (cond_hilites[HL_ATTCLR_DIM] & valid_conditions[i].bitmask) atr |= HL_DIM; if (cond_hilites[HL_ATTCLR_BOLD] & valid_conditions[i].bitmask) @@ -2474,6 +2476,8 @@ status_hilite_linestr_gather_conditions() atr |= HL_ULINE; if (cond_hilites[HL_ATTCLR_INVERSE] & valid_conditions[i].bitmask) atr |= HL_INVERSE; + if (atr != HL_NONE) + atr &= ~HL_NONE; if (clr != NO_COLOR || atr != HL_NONE) { unsigned long ca = clr | (atr << 8); @@ -2507,7 +2511,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 +2613,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); @@ -2849,6 +2850,7 @@ choose_field: attrqry[0] = '\0'; memset((genericptr_t) &hilite, 0, sizeof (struct hilite_s)); + hilite.next = (struct hilite_s *) 0; hilite.set = FALSE; /* mark it "unset" */ hilite.fld = fld; @@ -3154,52 +3156,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); @@ -3264,14 +3248,14 @@ int id; if (hl) { while (hl) { if (hlstr->hl == hl) { - if (hlprev) + if (hlprev) { hlprev->next = hl->next; - else { + } else { blstats[0][fld].thresholds = hl->next; blstats[1][fld].thresholds = blstats[0][fld].thresholds; } - free(hl); + free((genericptr_t) hl); return TRUE; } hlprev = hl; @@ -3340,14 +3324,15 @@ int fld; add_menu(tmpwin, NO_GLYPH, &any, 'Z', 0, ATR_NONE, "Add a new hilite", MENU_UNSELECTED); - Sprintf(buf, "Current %s hilites:", initblstats[fld].fldname); end_menu(tmpwin, buf); if ((res = select_menu(tmpwin, PICK_ANY, &picks)) > 0) { int mode = 0; + for (i = 0; i < res; i++) { int idx = picks[i].item.a_int; + if (idx == -1) { /* delete selected hilites */ if (mode) @@ -3367,6 +3352,7 @@ int fld; /* delete selected hilites */ for (i = 0; i < res; i++) { int idx = picks[i].item.a_int; + if (idx > 0) (void) status_hilite_remove(idx); } diff --git a/src/options.c b/src/options.c index fbe568fb2..b07c7b818 100644 --- a/src/options.c +++ b/src/options.c @@ -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 */