Merge branch 'NetHack-3.6.2'

This commit is contained in:
nhmall
2018-09-03 08:58:04 -04:00
11 changed files with 236 additions and 108 deletions

View File

@@ -104,6 +104,13 @@ wizard mode ^I^I didn't make temporary identifications become persistent if
the build configuration makes plain 'char' unsigned the build configuration makes plain 'char' unsigned
wizard mode #wizidentify didn't disclose extra information for unID'd items if wizard mode #wizidentify didn't disclose extra information for unID'd items if
key bindings took away ^I and didn't bind #wizidentify to another key key bindings took away ^I and didn't bind #wizidentify to another key
make transformation message of a deliberate apply of a figurine seem a bit
less definite when blind and place unseen monster marker at the spot
you think it should be
add window port status_update() value BL_RESET to use as a flag to
redraw all status fields, distinguished from BL_FLUSH which now only
specifies that the bot() call has completed so any buffered changes
should now be rendered
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
@@ -112,12 +119,15 @@ fix access violation when --debug:xxxx has no other args after it
setting the inverse attribute for gold had the space before "$:" setting the inverse attribute for gold had the space before "$:"
getting highlighted along with the gold field getting highlighted along with the gold field
sortloot segfaulted when filtering a subset of items (seen with 'A' command) sortloot segfaulted when filtering a subset of items (seen with 'A' command)
tty: turn off an optimization that is the suspected cause of Windows reported
partial status lines following level changes
Platform- and/or Interface-Specific Fixes Platform- and/or Interface-Specific Fixes
----------------------------------------- -----------------------------------------
windows-gui: In nethackw, there could be conflicts between menu accelerators windows-gui: In nethackw, there could be conflicts between menu accelerators
and an extra choice accelerator to fix H7132. and an extra choice accelerator to fix H7132.
windows-gui: recognize new BL_RESET in status_update; behavior currently the same
windows-tty: Specify both width and height when creating font for width testing windows-tty: Specify both width and height when creating font for width testing
windows-tty: To counter lag problems that were occuring with the Win32 console windows-tty: To counter lag problems that were occuring with the Win32 console
port, implement a console back buffer to reduce the number of calls port, implement a console back buffer to reduce the number of calls
@@ -134,6 +144,8 @@ windows-tty: Use nhraykey by default if the players keyboard layout is
windows-tty: We now support changing altkeyhandler in game windows-tty: We now support changing altkeyhandler in game
windows: Added ntassert() mechanism for Windows based port use windows: Added ntassert() mechanism for Windows based port use
tty: significant optimizations for performance and per field rendering tty: significant optimizations for performance and per field rendering
tty: use WC2_FLUSH_STATUS to buffer changes until BL_FLUSH is received
tty: support BL_RESET in status_update to force an update to all status fields
unix: Makefile.src and Makefile.utl inadvertently relied on a 'gnu make' unix: Makefile.src and Makefile.utl inadvertently relied on a 'gnu make'
extension when using $(VERBOSEMAKE) to reduce build-time feedback; extension when using $(VERBOSEMAKE) to reduce build-time feedback;
replace with $(QUIETCC) which operates the same but defaults to replace with $(QUIETCC) which operates the same but defaults to
@@ -154,6 +166,9 @@ sortloot option has been enhanced to improve object ordering; primarily,
within each class or sub-class of objects within each class or sub-class of objects
YAFM when stumbling on an undetected monster while hallucinating YAFM when stumbling on an undetected monster while hallucinating
Make it clear when a leprechaun dodges your attack Make it clear when a leprechaun dodges your attack
wizard mode #wizidentify can now select individual items for permanent
identification and don't display the selection to permanently
identify everything if everything is already fully identified
Code Cleanup and Reorganization Code Cleanup and Reorganization

View File

@@ -412,6 +412,10 @@ status_update(int fldindex, genericptr_t ptr, int chg, int percentage, int color
BL_LEVELDESC, BL_EXP, BL_CONDITION BL_LEVELDESC, BL_EXP, BL_CONDITION
-- fldindex could also be BL_FLUSH (-1), which is not really -- fldindex could also be BL_FLUSH (-1), which is not really
a field index, but is a special trigger to tell the a field index, but is a special trigger to tell the
windowport that it should output all changes received
to this point. It marks the end of a bot() cycle.
-- fldindex could also be BL_RESET (-2), which is not really
a field index, but is a special advisory to to tell the
windowport that it should redisplay all its status fields, windowport that it should redisplay all its status fields,
even if no changes have been presented to it. even if no changes have been presented to it.
-- ptr is usually a "char *", unless fldindex is BL_CONDITION. -- ptr is usually a "char *", unless fldindex is BL_CONDITION.

View File

@@ -28,8 +28,10 @@ Astral Plane \GXXXXNNNN:123456 HP:1234(1234) Pw:1234(1234) AC:-127
#endif #endif
enum statusfields { enum statusfields {
BL_CHARACTERISTICS = -2, /* alias for BL_STR..BL_CH */ BL_CHARACTERISTICS = -3, /* alias for BL_STR..BL_CH */
BL_FLUSH = -1, BL_TITLE = 0, BL_RESET = -2, /* Force everything to redisplay */
BL_FLUSH = -1, /* Finished cycling through bot fields */
BL_TITLE = 0,
BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, /* 1..6 */ BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, /* 1..6 */
BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX, /* 7..12 */ BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX, /* 7..12 */
BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, /* 13..18 */ BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, /* 13..18 */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1525012590 2018/04/29 14:36:30 $ $NHDT-Branch: master $:$NHDT-Revision: 1.629 $ */ /* NetHack 3.6 extern.h $NHDT-Date: 1535812936 2018/09/01 14:42:16 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.636 $ */
/* Copyright (c) Steve Creps, 1988. */ /* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */ /* NetHack may be freely redistributed. See license for details. */
@@ -973,6 +973,7 @@ E int FDECL(askchain, (struct obj **, const char *, int, int (*)(OBJ_P),
int (*)(OBJ_P), int, const char *)); int (*)(OBJ_P), int, const char *));
E void FDECL(fully_identify_obj, (struct obj *)); E void FDECL(fully_identify_obj, (struct obj *));
E int FDECL(identify, (struct obj *)); E int FDECL(identify, (struct obj *));
E int FDECL(count_unidentified, (struct obj *));
E void FDECL(identify_pack, (int, BOOLEAN_P)); E void FDECL(identify_pack, (int, BOOLEAN_P));
E void NDECL(learn_unseen_invent); E void NDECL(learn_unseen_invent);
E void FDECL(prinv, (const char *, struct obj *, long)); E void FDECL(prinv, (const char *, struct obj *, long));

View File

@@ -2236,16 +2236,19 @@ struct obj **optr;
/* Passing FALSE arg here will result in messages displayed */ /* Passing FALSE arg here will result in messages displayed */
if (!figurine_location_checks(obj, &cc, FALSE)) if (!figurine_location_checks(obj, &cc, FALSE))
return; return;
You("%s and it transforms.", You("%s and it %stransforms.",
(u.dx || u.dy) ? "set the figurine beside you" (u.dx || u.dy) ? "set the figurine beside you"
: (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz) : (Is_airlevel(&u.uz) || Is_waterlevel(&u.uz)
|| is_pool(cc.x, cc.y)) || is_pool(cc.x, cc.y))
? "release the figurine" ? "release the figurine"
: (u.dz < 0 ? "toss the figurine into the air" : (u.dz < 0 ? "toss the figurine into the air"
: "set the figurine on the ground")); : "set the figurine on the ground"),
Blind ? "supposedly " : "");
(void) make_familiar(obj, cc.x, cc.y, FALSE); (void) make_familiar(obj, cc.x, cc.y, FALSE);
(void) stop_timer(FIG_TRANSFORM, obj_to_any(obj)); (void) stop_timer(FIG_TRANSFORM, obj_to_any(obj));
useup(obj); useup(obj);
if (Blind)
map_invisible(cc.x, cc.y);
*optr = 0; *optr = 0;
} }

View File

@@ -736,7 +736,7 @@ boolean *valsetlist;
if (update_all || chg || reset) { if (update_all || chg || reset) {
idxmax = curr->idxmax; idxmax = curr->idxmax;
pc = (idxmax > BL_FLUSH) ? percentage(curr, &blstats[idx][idxmax]) : 0; pc = (idxmax >= 0) ? percentage(curr, &blstats[idx][idxmax]) : 0;
if (!valsetlist[fld]) if (!valsetlist[fld])
(void) anything_to_s(curr->val, &curr->a, anytype); (void) anything_to_s(curr->val, &curr->a, anytype);
@@ -770,8 +770,7 @@ evaluate_and_notify_windowport(valsetlist, idx, idx_p)
int idx, idx_p; int idx, idx_p;
boolean *valsetlist; boolean *valsetlist;
{ {
int i; int i, updated = 0, notpresent = 0;
boolean updated = FALSE;
/* /*
* Now pass the changed values to window port. * Now pass the changed values to window port.
@@ -781,27 +780,43 @@ boolean *valsetlist;
|| ((i == BL_EXP) && !flags.showexp) || ((i == BL_EXP) && !flags.showexp)
|| ((i == BL_TIME) && !flags.time) || ((i == BL_TIME) && !flags.time)
|| ((i == BL_HD) && !Upolyd) || ((i == BL_HD) && !Upolyd)
|| ((i == BL_XP || i == BL_EXP) && Upolyd)) || ((i == BL_XP || i == BL_EXP) && Upolyd)) {
notpresent++;
continue; continue;
}
if (evaluate_and_notify_windowport_field(i, valsetlist, idx, idx_p)) if (evaluate_and_notify_windowport_field(i, valsetlist, idx, idx_p))
updated = TRUE; updated++;
} }
/* /*
* It is possible to get here, with nothing having been pushed * Notes:
* to the window port, when none of the info has changed. In that * 1. It is possible to get here, with nothing having been pushed
* case, we need to force a call to status_update() when * to the window port, when none of the info has changed.
* context.botlx is set. The tty port in particular has a problem *
* if that isn't done, since it sets context.botlx when a menu or * 2. Some window ports are also known to optimize by only drawing
* text display obliterates the status line. * fields that have changed since the previous update.
*
* In both of those situations, we need to force updates to
* all of the fields when context.botlx is set. The tty port in
* particular has a problem if that isn't done, since the core sets
* context.botlx when a menu or text display obliterates the status
* line.
*
* For those situations, to trigger the full update of every field
* whether changed or not, call status_update() with BL_RESET.
*
* For regular processing and to notify the window port that a
* bot() round has finished and it's time to trigger a flush of
* all buffered changes received thus far but not reflected in
* the display, call status_update() with BL_FLUSH.
* *
* To work around it, we call status_update() with fictitious
* index of BL_FLUSH (-1).
*/ */
if ((context.botlx && !updated) if (context.botlx)
|| (windowprocs.wincap2 & WC2_FLUSH_STATUS) != 0L) status_update(BL_RESET, (genericptr_t) 0, 0, 0,
NO_COLOR, &cond_hilites[0]);
else if ((windowprocs.wincap2 & WC2_FLUSH_STATUS) != 0L)
status_update(BL_FLUSH, (genericptr_t) 0, 0, 0, status_update(BL_FLUSH, (genericptr_t) 0, 0, 0,
NO_COLOR, &cond_hilites[0]); NO_COLOR, &cond_hilites[0]);
context.botl = context.botlx = 0; context.botl = context.botlx = 0;
update_all = FALSE; update_all = FALSE;
} }
@@ -1936,7 +1951,7 @@ boolean from_configfile;
} }
if (percent) { if (percent) {
if (initblstats[fld].idxmax <= BL_FLUSH) { if (initblstats[fld].idxmax < 0) {
config_error_add("Cannot use percent with '%s'", config_error_add("Cannot use percent with '%s'",
initblstats[fld].fldname); initblstats[fld].fldname);
return FALSE; return FALSE;
@@ -2674,7 +2689,7 @@ int fld;
int at; int at;
int onlybeh = BL_TH_NONE, nopts = 0; int onlybeh = BL_TH_NONE, nopts = 0;
if (fld <= BL_FLUSH || fld >= MAXBLSTATS) if (fld < 0 || fld >= MAXBLSTATS)
return BL_TH_NONE; return BL_TH_NONE;
at = initblstats[fld].anytype; at = initblstats[fld].anytype;
@@ -2717,7 +2732,7 @@ int fld;
nopts++; nopts++;
} }
if (initblstats[fld].idxmax > BL_FLUSH) { if (initblstats[fld].idxmax >= 0) {
any = zeroany; any = zeroany;
any.a_int = onlybeh = BL_TH_VAL_PERCENTAGE; any.a_int = onlybeh = BL_TH_VAL_PERCENTAGE;
add_menu(tmpwin, NO_GLYPH, &any, 'p', 0, ATR_NONE, add_menu(tmpwin, NO_GLYPH, &any, 'p', 0, ATR_NONE,
@@ -2849,6 +2864,7 @@ choose_field:
fld = origfld; fld = origfld;
if (fld == BL_FLUSH) { if (fld == BL_FLUSH) {
fld = status_hilite_menu_choose_field(); fld = status_hilite_menu_choose_field();
/* isn't this redundant given what follows? */
if (fld == BL_FLUSH) if (fld == BL_FLUSH)
return FALSE; return FALSE;
} }

View File

@@ -652,7 +652,6 @@ wiz_identify(VOID_ARGS)
it doesn't matter whether the command has been remapped */ it doesn't matter whether the command has been remapped */
if (display_inventory((char *) 0, TRUE) == C('I')) if (display_inventory((char *) 0, TRUE) == C('I'))
identify_pack(0, FALSE); identify_pack(0, FALSE);
/* [TODO? if player picks a specific inventory item, ID it] */
iflags.override_ID = 0; iflags.override_ID = 0;
} else } else
pline("Unavailable command '%s'.", pline("Unavailable command '%s'.",

View File

@@ -2468,16 +2468,14 @@ register boolean newlev;
return; return;
} }
/* the ',' command */ /* returns
1 = cannot pickup, time taken
0 = cannot pickup, no time taken
-1 = do normal pickup
-2 = loot the monster */
int int
dopickup() pickup_checks()
{ {
int count, tmpcount;
struct trap *traphere = t_at(u.ux, u.uy);
/* awful kludge to work around parse()'s pre-decrement */
count = (multi || (save_cm && *save_cm == ',')) ? multi + 1 : 0;
multi = 0; /* always reset */
/* uswallow case added by GAN 01/29/87 */ /* uswallow case added by GAN 01/29/87 */
if (u.uswallow) { if (u.uswallow) {
if (!u.ustuck->minvent) { if (!u.ustuck->minvent) {
@@ -2489,8 +2487,7 @@ dopickup()
Blind ? "feel" : "see"); Blind ? "feel" : "see");
return 1; return 1;
} else { } else {
tmpcount = -count; return -2; /* loot the monster inventory */
return loot_mon(u.ustuck, &tmpcount, (boolean *) 0);
} }
} }
if (is_pool(u.ux, u.uy)) { if (is_pool(u.ux, u.uy)) {
@@ -2532,6 +2529,7 @@ dopickup()
return 0; return 0;
} }
if (!can_reach_floor(TRUE)) { if (!can_reach_floor(TRUE)) {
struct trap *traphere = t_at(u.ux, u.uy);
if (traphere && uteetering_at_seen_pit(traphere)) if (traphere && uteetering_at_seen_pit(traphere))
You("cannot reach the bottom of the pit."); You("cannot reach the bottom of the pit.");
else if (u.usteed && P_SKILL(P_RIDING) < P_BASIC) else if (u.usteed && P_SKILL(P_RIDING) < P_BASIC)
@@ -2542,6 +2540,25 @@ dopickup()
You("cannot reach the %s.", surface(u.ux, u.uy)); You("cannot reach the %s.", surface(u.ux, u.uy));
return 0; return 0;
} }
return -1; /* can do normal pickup */
}
/* the ',' command */
int
dopickup(VOID_ARGS)
{
int count, tmpcount, ret;
/* awful kludge to work around parse()'s pre-decrement */
count = (multi || (save_cm && *save_cm == cmd_from_func(dopickup))) ? multi + 1 : 0;
multi = 0; /* always reset */
if ((ret = pickup_checks() >= 0))
return ret;
else if (ret == -2) {
tmpcount = -count;
return loot_mon(u.ustuck, &tmpcount, (boolean *) 0);
} /* else ret == -1 */
return pickup(-count); return pickup(-count);
} }

View File

@@ -2279,6 +2279,19 @@ int id_limit;
} }
} }
} }
/* count the unidentified items */
int
count_unidentified(objchn)
struct obj *objchn;
{
int unid_cnt = 0;
struct obj *obj;
for (obj = objchn; obj; obj = obj->nobj)
if (not_fully_identified(obj))
++unid_cnt;
return unid_cnt;
}
/* dialog with user to identify a given number of items; 0 means all */ /* dialog with user to identify a given number of items; 0 means all */
void void
@@ -2286,28 +2299,21 @@ identify_pack(id_limit, learning_id)
int id_limit; int id_limit;
boolean learning_id; /* true if we just read unknown identify scroll */ boolean learning_id; /* true if we just read unknown identify scroll */
{ {
struct obj *obj, *the_obj; struct obj *obj;
int n, unid_cnt; int n, unid_cnt = count_unidentified(invent);
unid_cnt = 0;
the_obj = 0; /* if unid_cnt ends up 1, this will be it */
for (obj = invent; obj; obj = obj->nobj)
if (not_fully_identified(obj))
++unid_cnt, the_obj = obj;
if (!unid_cnt) { if (!unid_cnt) {
You("have already identified all %sof your possessions.", You("have already identified all %sof your possessions.",
learning_id ? "the rest " : ""); learning_id ? "the rest " : "");
} else if (!id_limit || id_limit >= unid_cnt) { } else if (!id_limit || id_limit >= unid_cnt) {
/* identify everything */ /* identify everything */
if (unid_cnt == 1) { /* TODO: use fully_identify_obj and cornline/menu/whatever here */
(void) identify(the_obj); for (obj = invent; obj; obj = obj->nobj) {
} else { if (not_fully_identified(obj)) {
/* TODO: use fully_identify_obj and cornline/menu/whatever here (void) identify(obj);
*/ if (unid_cnt == 1)
for (obj = invent; obj; obj = obj->nobj) break;
if (not_fully_identified(obj)) }
(void) identify(obj);
} }
} else { } else {
/* identify up to `id_limit' items */ /* identify up to `id_limit' items */
@@ -2491,7 +2497,7 @@ boolean want_reply;
long *out_cnt; long *out_cnt;
{ {
static const char not_carrying_anything[] = "Not carrying anything"; static const char not_carrying_anything[] = "Not carrying anything";
struct obj *otmp; struct obj *otmp, wizid_fakeobj;
char ilet, ret; char ilet, ret;
char *invlet = flags.inv_order; char *invlet = flags.inv_order;
int n, classcount; int n, classcount;
@@ -2500,6 +2506,7 @@ long *out_cnt;
menu_item *selected; menu_item *selected;
unsigned sortflags; unsigned sortflags;
Loot *sortedinvent, *srtinv; Loot *sortedinvent, *srtinv;
boolean wizid = FALSE;
if (lets && !*lets) if (lets && !*lets)
lets = 0; /* simplify tests: (lets) instead of (lets && *lets) */ lets = 0; /* simplify tests: (lets) instead of (lets && *lets) */
@@ -2582,22 +2589,33 @@ long *out_cnt;
start_menu(win); start_menu(win);
any = zeroany; any = zeroany;
if (wizard && iflags.override_ID) { if (wizard && iflags.override_ID) {
int unid_cnt;
char prompt[QBUFSZ]; char prompt[QBUFSZ];
/* C('I') == ^I == default keystroke for wiz_identify; unid_cnt = count_unidentified(invent);
it is guaranteed not to be in use as an inventory letter add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE,
(wiz_identify might be remapped to an ordinary letter, "Debug Identify",
making iflags.override_ID ambiguous as a return value) */ MENU_UNSELECTED);
any.a_char = C('I'); if (!unid_cnt) {
/* wiz_identify stuffed the wiz_identify command character (^I) add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE,
into iflags.override_ID for our use as an accelerator; "(all items are permanently identified already)",
it could be ambiguous as a selector but the only time it MENU_UNSELECTED);
is wanted is in case where no item is being selected */ } else {
Sprintf(prompt, "Debug Identify (%s to permanently identify)", any.a_obj = &wizid_fakeobj;
visctrl(iflags.override_ID)); /* wiz_identify stuffed the wiz_identify command character (^I)
add_menu(win, NO_GLYPH, &any, '_', iflags.override_ID, ATR_NONE, into iflags.override_ID for our use as an accelerator;
prompt, MENU_UNSELECTED); it could be ambiguous as a selector but the only time it
} else if (xtra_choice) { is wanted is in case where no item is being selected */
Sprintf(prompt,
"Select %sthe %d bolded item%s to permanently identify (%s for all)",
(unid_cnt == 1) ? "": "any of ", unid_cnt,
(unid_cnt > 1) ? "s" : "",
visctrl(iflags.override_ID));
add_menu(win, NO_GLYPH, &any, '_', iflags.override_ID, ATR_NONE,
prompt, MENU_UNSELECTED);
wizid = TRUE;
}
} else if (xtra_choice) {
/* wizard override ID and xtra_choice are mutually exclusive */ /* wizard override ID and xtra_choice are mutually exclusive */
if (flags.sortpack) if (flags.sortpack)
add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings, add_menu(win, NO_GLYPH, &any, 0, 0, iflags.menu_headings,
@@ -2621,8 +2639,13 @@ nextclass:
MENU_UNSELECTED); MENU_UNSELECTED);
classcount++; classcount++;
} }
any.a_char = ilet; if (wizid)
add_menu(win, obj_to_glyph(otmp), &any, ilet, 0, ATR_NONE, any.a_obj = otmp;
else
any.a_char = ilet;
add_menu(win, obj_to_glyph(otmp), &any, ilet, 0,
(wizid && not_fully_identified(otmp)) ?
ATR_BOLD : ATR_NONE,
doname(otmp), MENU_UNSELECTED); doname(otmp), MENU_UNSELECTED);
} }
} }
@@ -2655,11 +2678,31 @@ nextclass:
} }
end_menu(win, query && *query ? query : (char *) 0); end_menu(win, query && *query ? query : (char *) 0);
n = select_menu(win, want_reply ? PICK_ONE : PICK_NONE, &selected); n = select_menu(win, wizid ? PICK_ANY :
want_reply ? PICK_ONE : PICK_NONE, &selected);
if (n > 0) { if (n > 0) {
ret = selected[0].item.a_char; if (wizid) {
if (out_cnt) int i = n;
*out_cnt = selected[0].count;
ret = '\0';
while (--i >= 0) {
otmp = selected[i].item.a_obj;
if (otmp == &wizid_fakeobj) {
/* C('I') == ^I == default keystroke for wiz_identify;
it is guaranteed not to be in use as an inventory letter
(wiz_identify might be remapped to an ordinary letter,
making iflags.override_ID ambiguous as a return value) */
ret = C('I');
} else {
if (not_fully_identified(otmp))
(void) identify(otmp);
}
}
} else {
ret = selected[0].item.a_char;
if (out_cnt)
*out_cnt = selected[0].count;
}
free((genericptr_t) selected); free((genericptr_t) selected);
} else } else
ret = !n ? '\0' : '\033'; /* cancelled */ ret = !n ? '\0' : '\033'; /* cancelled */

View File

@@ -66,7 +66,7 @@ struct window_procs tty_procs = {
| WC2_SELECTSAVED | WC2_SELECTSAVED
#endif #endif
#if defined(STATUS_HILITES) #if defined(STATUS_HILITES)
| WC2_HILITE_STATUS | WC2_HITPOINTBAR | WC2_HILITE_STATUS | WC2_HITPOINTBAR | WC2_FLUSH_STATUS
#endif #endif
| WC2_DARKGRAY), | WC2_DARKGRAY),
tty_init_nhwindows, tty_player_selection, tty_askname, tty_get_nh_event, tty_init_nhwindows, tty_player_selection, tty_askname, tty_get_nh_event,
@@ -3543,6 +3543,8 @@ static int cond_shrinklvl = 0, cond_width_at_shrink = 0;
static int enclev = 0, enc_shrinklvl = 0; static int enclev = 0, enc_shrinklvl = 0;
/* static int dl_shrinklvl = 0; */ /* static int dl_shrinklvl = 0; */
static boolean truncation_expected = FALSE; static boolean truncation_expected = FALSE;
#define FORCE_RESET TRUE
#define NO_RESET FALSE
/* This controls whether to skip fields that aren't /* This controls whether to skip fields that aren't
* flagged as requiring updating during the current * flagged as requiring updating during the current
@@ -3552,11 +3554,13 @@ static boolean truncation_expected = FALSE;
* for all platforms eventually and the conditional * for all platforms eventually and the conditional
* setting below can be removed. * setting below can be removed.
*/ */
#if defined(UNIX) static int do_field_opt =
static int do_field_opt = 0; #if defined(DISABLE_TTY_FIELD_OPT)
0;
#else #else
static int do_field_opt = 1; 1;
#endif #endif
#endif /* STATUS_HILITES */ #endif /* STATUS_HILITES */
/* /*
@@ -3571,7 +3575,7 @@ tty_status_init()
int i; int i;
for (i = 0; i < MAXBLSTATS; ++i) { for (i = 0; i < MAXBLSTATS; ++i) {
tty_status[NOW][i].idx = -1; tty_status[NOW][i].idx = BL_FLUSH;
tty_status[NOW][i].color = NO_COLOR; /* no color */ tty_status[NOW][i].color = NO_COLOR; /* no color */
tty_status[NOW][i].attr = ATR_NONE; tty_status[NOW][i].attr = ATR_NONE;
tty_status[NOW][i].x = 0; tty_status[NOW][i].x = 0;
@@ -3602,7 +3606,11 @@ tty_status_init()
* BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, BL_HPMAX, * BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, BL_HPMAX,
* BL_LEVELDESC, BL_EXP, BL_CONDITION * BL_LEVELDESC, BL_EXP, BL_CONDITION
* -- fldindex could also be BL_FLUSH (-1), which is not really * -- fldindex could also be BL_FLUSH (-1), which is not really
* a field index, but is a special trigger to tell the * a field index, but is a special trigger to tell the
* windowport that it should output all changes received
* to this point. It marks the end of a bot() cycle.
* -- fldindex could also be BL_RESET (-3), which is not really
* a field index, but is a special advisory to to tell the
* windowport that it should redisplay all its status fields, * windowport that it should redisplay all its status fields,
* even if no changes have been presented to it. * even if no changes have been presented to it.
* -- ptr is usually a "char *", unless fldindex is BL_CONDITION. * -- ptr is usually a "char *", unless fldindex is BL_CONDITION.
@@ -3655,9 +3663,9 @@ unsigned long *colormasks;
char *text = (char *) ptr; char *text = (char *) ptr;
char *lastchar = (char *) 0; char *lastchar = (char *) 0;
char *fval = (char *) 0; char *fval = (char *) 0;
boolean force_update = FALSE; boolean reset_state = NO_RESET;
if (fldidx != BL_FLUSH && !status_activefields[fldidx]) if ((fldidx >= 0 && fldidx < MAXBLSTATS) && !status_activefields[fldidx])
return; return;
#ifndef TEXTCOLOR #ifndef TEXTCOLOR
@@ -3665,9 +3673,13 @@ unsigned long *colormasks;
#endif #endif
switch (fldidx) { switch (fldidx) {
case BL_RESET:
reset_state = FORCE_RESET;
/* FALLTHRU */
case BL_FLUSH: case BL_FLUSH:
force_update = TRUE; if (make_things_fit(reset_state) || truncation_expected)
break; render_status();
return;
case BL_CONDITION: case BL_CONDITION:
tty_status[NOW][fldidx].idx = fldidx; tty_status[NOW][fldidx].idx = fldidx;
tty_condition_bits = *condptr; tty_condition_bits = *condptr;
@@ -3691,7 +3703,8 @@ unsigned long *colormasks;
/* The core botl engine sends a single blank to the window port /* The core botl engine sends a single blank to the window port
for carrying-capacity when its unused. Let's suppress that */ for carrying-capacity when its unused. Let's suppress that */
if (tty_status[NOW][fldidx].lth == 1 && status_vals[fldidx][0] == ' ') { if (fldidx >= 0 && fldidx < MAXBLSTATS &&
tty_status[NOW][fldidx].lth == 1 && status_vals[fldidx][0] == ' ') {
status_vals[fldidx][0] = '\0'; status_vals[fldidx][0] = '\0';
tty_status[NOW][fldidx].lth = 0; tty_status[NOW][fldidx].lth = 0;
} }
@@ -3704,6 +3717,10 @@ unsigned long *colormasks;
hpbar_percent = percent; hpbar_percent = percent;
hpbar_color = (color & 0x00FF); hpbar_color = (color & 0x00FF);
} }
if (iflags.wc2_hitpointbar && (tty_procs.wincap2 & WC2_FLUSH_STATUS) != 0L) {
tty_status[NOW][BL_TITLE].color = hpbar_color;
tty_status[NOW][BL_TITLE].dirty = TRUE;
}
break; break;
case BL_LEVELDESC: case BL_LEVELDESC:
case BL_HUNGER: case BL_HUNGER:
@@ -3737,8 +3754,7 @@ unsigned long *colormasks;
} }
break; break;
} }
if (make_things_fit(force_update) || truncation_expected) /* 3.6.2 we only render on BL_FLUSH (or BL_RESET) */
render_status();
return; return;
} }
@@ -3802,7 +3818,7 @@ boolean forcefields;
int *topsz, *bottomsz; int *topsz, *bottomsz;
{ {
int c, i, row, col, trackx, idx; int c, i, row, col, trackx, idx;
boolean valid = TRUE, matchprev = FALSE, update_right; boolean valid = TRUE, matchprev = FALSE, update_right, disregard;
if (!windowdata_init && !check_windowdata()) if (!windowdata_init && !check_windowdata())
return FALSE; return FALSE;
@@ -3830,25 +3846,32 @@ int *topsz, *bottomsz;
* Check values against those already on the dislay. * Check values against those already on the dislay.
* - Is the additional processing time for this worth it? * - Is the additional processing time for this worth it?
*/ */
matchprev = FALSE; if (do_field_opt) {
if (do_field_opt && tty_status[NOW][idx].dirty) { matchprev = FALSE;
/* compare values */ disregard = (tty_status[NOW][idx].lth == 0);
const char *ob, *nb; /* old byte, new byte */ if (do_field_opt && !disregard
&& tty_status[NOW][idx].dirty) {
/* compare values */
const char *ob, *nb; /* old byte, new byte */
c = col - 1; c = col - 1;
ob = &wins[WIN_STATUS]->data[row][c]; ob = &wins[WIN_STATUS]->data[row][c];
nb = status_vals[idx]; nb = status_vals[idx];
while (*nb && c < wins[WIN_STATUS]->cols) { while (*nb && c < wins[WIN_STATUS]->cols) {
if (*nb != *ob) if (*nb != *ob)
break; break;
nb++; nb++;
ob++; ob++;
c++; c++;
}
if (!*nb && c > col - 1)
matchprev = TRUE;
} }
if (!*nb && c > col - 1) } else {
matchprev = TRUE; matchprev = FALSE;
} }
} }
/* /*
* With STATUS_HILITES, it is possible that the color * With STATUS_HILITES, it is possible that the color
* needs to change even if the text is the same, so * needs to change even if the text is the same, so
@@ -3858,7 +3881,8 @@ int *topsz, *bottomsz;
* After the field has been updated, render_status() * After the field has been updated, render_status()
* will also clear .redraw and .dirty. * will also clear .redraw and .dirty.
*/ */
if (forcefields || update_right || !matchprev if (forcefields || update_right
|| (!matchprev && tty_status[NOW][idx].dirty && !disregard)
|| tty_status[NOW][idx].color != tty_status[BEFORE][idx].color || tty_status[NOW][idx].color != tty_status[BEFORE][idx].color
|| tty_status[NOW][idx].attr != tty_status[BEFORE][idx].attr) || tty_status[NOW][idx].attr != tty_status[BEFORE][idx].attr)
tty_status[NOW][idx].redraw = TRUE; tty_status[NOW][idx].redraw = TRUE;

View File

@@ -2857,10 +2857,14 @@ status_update(int fldindex, genericptr_t ptr, int chg, int percent, int color, u
BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX, BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX,
BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, BL_HPMAX, BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, BL_HPMAX,
BL_LEVELDESC, BL_EXP, BL_CONDITION BL_LEVELDESC, BL_EXP, BL_CONDITION
-- fldindex could also be BL_FLUSH (-1), which is not really -- fldindex could also be BL_FLUSH, which is not really
a field index, but is a special trigger to tell the a field index, but is a special trigger to tell the
windowport that it should redisplay all its status fields, windowport that it should output all changes received
even if no changes have been presented to it. to this point. It marks the end of a bot() cycle.
-- fldindex could also be BL_RESET, which is not really
a field index, but is a special advisory to to tell the
windowport that it should redisplay all its status fields,
even if no changes have been presented to it.
-- ptr is usually a "char *", unless fldindex is BL_CONDITION. -- ptr is usually a "char *", unless fldindex is BL_CONDITION.
If fldindex is BL_CONDITION, then ptr is a long value with If fldindex is BL_CONDITION, then ptr is a long value with
any or none of the following bits set (from botl.h): any or none of the following bits set (from botl.h):
@@ -2898,7 +2902,7 @@ mswin_status_update(int idx, genericptr_t ptr, int chg, int percent, int color,
logDebug("mswin_status_update(%d, %p, %d, %d, %x, %p)\n", idx, ptr, chg, percent, color, colormasks); logDebug("mswin_status_update(%d, %p, %d, %d, %x, %p)\n", idx, ptr, chg, percent, color, colormasks);
if (idx != BL_FLUSH) { if (idx != BL_FLUSH && idx != BL_RESET) {
if (!_status_activefields[idx]) if (!_status_activefields[idx])
return; return;
_status_percents[idx] = percent; _status_percents[idx] = percent;