diff --git a/doc/fixes3-7-0.txt b/doc/fixes3-7-0.txt index 5d61dc8ce..8f2eea45a 100644 --- a/doc/fixes3-7-0.txt +++ b/doc/fixes3-7-0.txt @@ -2611,11 +2611,6 @@ tiles: male and female variations in monsters.txt; tested only with tile2bmp tty: use bright colors directly on supporting terminals tty: if a message is marked urgent, override message suppression initiated by user having typed ESC at previous --More-- prompt -tty+DECgraphics: when ready to print a normal character after having printed - a line-drawing character, don't switch back to normal character set - unless current char is one that gets rendered differently as a line - drawing char (mainly lowercase letters) so that we might be able to - avoid the need to switch to line drawing for next char that uses that Unix: can define NOSUSPEND in config.h or src/Makefile's CFLAGS to prevent unixconf.h from enabling SUSPEND without need to modify unixconf.h Unix: support --nethackrc=filename on the command line; same effect as @@ -2628,6 +2623,9 @@ X11: echo getline prompt and response (wishes, applying names) to message window and dumplog message history X11: fix map expose area, no longer leaving black bars on the map tty and curses: support italic as text attribute +tty and curses: when hitpointbar is displayed, make it blink if current HP is + below the "critical HP" threshold (where prayer treats being injured + as major trouble) NetHack Community Patches (or Variation) Included diff --git a/include/extern.h b/include/extern.h index dc2a42737..18cfc4e6b 100644 --- a/include/extern.h +++ b/include/extern.h @@ -268,6 +268,7 @@ extern boolean exp_percent_changing(void); extern int stat_cap_indx(void); extern int stat_hunger_indx(void); extern const char *bl_idx_to_fldname(int); +extern void repad_with_dashes(char *); extern void condopt(int, boolean *, boolean); extern int parse_cond_option(boolean, char *); extern boolean cond_menu(void); diff --git a/src/botl.c b/src/botl.c index 07579358a..c415c554b 100644 --- a/src/botl.c +++ b/src/botl.c @@ -1902,6 +1902,19 @@ bl_idx_to_fldname(int idx) return (const char *) 0; } +/* used when rendering hitpointbar; inoutbuf[] has been padded with + trailing spaces; replace pairs of spaces with pairs of space+dash */ +void +repad_with_dashes(char *inoutbuf) +{ + char *p = eos(inoutbuf); + + while (p >= inoutbuf + 2 && p[-1] == ' ' && p[-2] == ' ') { + p[-1] = '-'; + p -= 2; + } +} + #ifdef STATUS_HILITES /****************************************************************************/ diff --git a/win/curses/cursstat.c b/win/curses/cursstat.c index c7258d6b9..d99e473b2 100644 --- a/win/curses/cursstat.c +++ b/win/curses/cursstat.c @@ -27,7 +27,7 @@ static char *status_vals_long[MAXBLSTATS]; static unsigned long *curses_colormasks; static long curses_condition_bits; static int curses_status_colors[MAXBLSTATS]; -static int hpbar_percent, hpbar_color; +static int hpbar_percent, hpbar_crit_hp, hpbar_color; static int vert_status_dirty; static void draw_status(void); @@ -57,7 +57,7 @@ curses_status_init(void) *status_vals_long[i] = '\0'; } curses_condition_bits = 0L; - hpbar_percent = 0, hpbar_color = NO_COLOR; + hpbar_percent = hpbar_crit_hp = 0, hpbar_color = NO_COLOR; vert_status_dirty = 1; /* let genl_status_init do most of the initialization */ @@ -180,8 +180,8 @@ curses_status_update( } else { Sprintf(status_vals[fldidx], (fldidx == BL_TITLE && iflags.wc2_hitpointbar) - ? "%-30s" : status_fieldfmt[fldidx] - ? status_fieldfmt[fldidx] : "%s", + ? "%-30.30s" : status_fieldfmt[fldidx] + ? status_fieldfmt[fldidx] : "%s", text); /* strip trailing spaces; core ought to do this for us */ if (fldidx == BL_HUNGER || fldidx == BL_LEVELDESC) @@ -195,7 +195,9 @@ curses_status_update( curses_status_colors[fldidx] = color_and_attr; if (iflags.wc2_hitpointbar && fldidx == BL_HP) { hpbar_percent = percent; - hpbar_color = color_and_attr; + hpbar_crit_hp = critically_low_hp(TRUE) ? 1 : 0; + hpbar_color = ((color_and_attr & 0x00ff) | (HL_INVERSE << 8) + | (hpbar_crit_hp ? (HL_BLINK << 8) : 0)); } } } else { /* BL_FLUSH */ @@ -950,8 +952,9 @@ draw_vertical(boolean border) /* hitpointbar using hp percent calculation */ static void -curs_HPbar(char *text, /* pre-padded with trailing spaces if short */ - int bar_len) /* width of space within the brackets */ +curs_HPbar( + char *text, /* pre-padded with trailing spaces if short */ + int bar_len) /* width of space within the brackets */ { #ifdef STATUS_HILITES int coloridx = 0; @@ -967,6 +970,8 @@ curs_HPbar(char *text, /* pre-padded with trailing spaces if short */ bar_len = k; (void) strncpy(bar, text, bar_len); bar[bar_len] = '\0'; + if (hpbar_crit_hp) + repad_with_dashes(bar); bar_pos = (bar_len * hpbar_percent) / 100; if (bar_pos < 1 && hpbar_percent > 0) @@ -980,6 +985,8 @@ curs_HPbar(char *text, /* pre-padded with trailing spaces if short */ } waddch(win, '['); + if (hpbar_crit_hp) + wattron(win, A_BLINK); if (*bar) { /* True unless dead (0 HP => bar_pos == 0) */ /* fixed attribute, not nhattr2curses((hpbar_color >> 8) & 0x00FF) */ wattron(win, A_REVERSE); /* do this even if hilite_delta is 0 */ @@ -1008,6 +1015,8 @@ curs_HPbar(char *text, /* pre-padded with trailing spaces if short */ *bar2 = savedch; waddstr(win, bar2); } + if (hpbar_crit_hp) + wattroff(win, A_BLINK); waddch(win, ']'); } diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 92bef9dfc..0ef7eb44d 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -4200,7 +4200,7 @@ static int condattr(long, unsigned long *); static unsigned long *tty_colormasks; static long tty_condition_bits; static struct tty_status_fields tty_status[2][MAXBLSTATS]; /* 2: NOW,BEFORE */ -static int hpbar_percent, hpbar_color; +static int hpbar_percent, hpbar_crit_hp; extern const struct conditions_t conditions[CONDITION_COUNT]; static const char *const encvals[3][6] = { @@ -4288,7 +4288,7 @@ tty_status_init(void) tty_status[BEFORE][i] = tty_status[NOW][i]; } tty_condition_bits = 0L; - hpbar_percent = 0, hpbar_color = NO_COLOR; + hpbar_percent = hpbar_crit_hp = 0; #endif /* STATUS_HILITES */ /* let genl_status_init do most of the initialization */ @@ -4468,8 +4468,10 @@ tty_status_update( if (iflags.wc2_hitpointbar) { /* Special additional processing for hitpointbar */ hpbar_percent = percent; - hpbar_color = (color & 0x00FF); - tty_status[NOW][BL_TITLE].color = hpbar_color; + hpbar_crit_hp = critically_low_hp(TRUE) ? 1 : 0; + tty_status[NOW][BL_TITLE].color = (color & 0x00FF); + attrmask = HL_INVERSE | (hpbar_crit_hp ? HL_BLINK : 0); + tty_status[NOW][BL_TITLE].attr = term_attr_fixup(attrmask); tty_status[NOW][BL_TITLE].dirty = TRUE; } break; @@ -5050,7 +5052,7 @@ render_status(void) */ /* hitpointbar using hp percent calculation */ int bar_len, bar_pos = 0; - char bar[MAXCO], *bar2 = (char *) 0, savedch = '\0'; + char bar[30 + 1], *bar2 = (char *) 0, savedch = '\0'; boolean twoparts = (hpbar_percent < 100); /* force exactly 30 characters, padded with spaces @@ -5058,10 +5060,14 @@ render_status(void) if (strlen(text) != 30) { Sprintf(bar, "%-30.30s", text); Strcpy(status_vals[BL_TITLE], bar); - } else + } else { Strcpy(bar, text); + } + if (hpbar_crit_hp) + repad_with_dashes(bar); bar_len = (int) strlen(bar); /* always 30 */ tlth = bar_len + 2; + attrmask = 0; /* for the second part only case: dead */ /* when at full HP, the whole title will be highlighted; when injured or dead, there will be a second portion which is not highlighted */ @@ -5078,19 +5084,25 @@ render_status(void) } tty_putstatusfield("[", x++, y); if (*bar) { /* always True, unless twoparts+dead (0 HP) */ - term_start_attr(ATR_INVERSE); - if (iflags.hilite_delta && hpbar_color != NO_COLOR) - term_start_color(hpbar_color); + coloridx = tty_status[NOW][BL_TITLE].color; + attrmask = tty_status[NOW][BL_TITLE].attr; + Begin_Attr(attrmask); + if (iflags.hilite_delta && coloridx != NO_COLOR) + term_start_color(coloridx); tty_putstatusfield(bar, x, y); x += (int) strlen(bar); - if (iflags.hilite_delta && hpbar_color != NO_COLOR) + if (iflags.hilite_delta && coloridx != NO_COLOR) term_end_color(); - term_end_attr(ATR_INVERSE); + End_Attr(attrmask); } - if (twoparts) { /* no highlighting for second part */ + if (twoparts) { + if ((attrmask & HL_BLINK) != 0) + term_start_attr(ATR_BLINK); *bar2 = savedch; tty_putstatusfield(bar2, x, y); x += (int) strlen(bar2); + if ((attrmask & HL_BLINK) != 0) + term_end_attr(ATR_BLINK); } tty_putstatusfield("]", x++, y); } else {