diff --git a/dat/history b/dat/history index b201c094d..dd6c0304d 100644 --- a/dat/history +++ b/dat/history @@ -219,7 +219,7 @@ On behalf of the NetHack community, thank you very much once again to M. Drew Streib and Pasi Kallinen for providing a public NetHack server at nethack.alt.org. Thanks to Keith Simpson and Andy Thomson for hardfought.org. Thanks to all those unnamed dungeoneers who invest their -time and effort into annual NetHack tournaments such as Junehack +time and effort into annual NetHack tournaments such as Junethack and in days past, devnull.net (gone for now, but not forgotten). - - - - - - - - - - diff --git a/dat/wizhelp b/dat/wizhelp index 667f657d4..519ca1687 100644 --- a/dat/wizhelp +++ b/dat/wizhelp @@ -11,7 +11,6 @@ Debug-Mode Quick Reference: #levelchange == set hero's experience level #lightsources == show mobile light sources -#monpolycontrol == control monster polymorphs #panic == panic test (warning: current game will be terminated) #polyself == polymorph self #seenv == show seen vectors @@ -27,3 +26,7 @@ Debug-Mode Quick Reference: #wizwhere == show dungeon placement of all special levels #wmode == show wall modes +Options: +monpolycontrol == prompt for new form whenever any monster changes shape +sanity_check == evaluate monsters, objects, and map prior to each turn +wizweight == augment object descriptions with their objects' weight diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index 1b669c79f..cf8810c37 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -21,7 +21,7 @@ .ds vr "NetHack 3.6 .ds f0 "\*(vr .ds f1 -.ds f2 "August 30, 2018 +.ds f2 "September 26, 2018 . .\" labeled paragraph start (should be part of tmac.n, but I don't want to .\" make changes to that file) @@ -1121,10 +1121,6 @@ and go directly to removing a saddle. Default key is 'M-l', and 'l' if .op number_pad is on. -.lp #monpolycontrol -Control monster polymorphs. -Autocompletes. -Debug mode only. .lp #monster Use a monster's special ability (when polymorphed into monster form). Autocompletes. Default key is 'M-m'. @@ -1316,14 +1312,10 @@ Show what type of thing a symbol corresponds to. Default key is '/'. Wield a weapon. Default key is 'w'. .lp #wipe Wipe off your face. Autocompletes. Default key is 'M-w'. -.lp #wizdebug_bury +.lp #wizbury Bury objects under and around you. Autocompletes. Debug mode only. -.lp #wizdebug_traveldisplay -Toggle travel display. -Autocompletes. -Debug mode only. .lp #wizdetect Search for hidden things (secret doors or traps or unseen monsters) within a modest radius. @@ -2895,6 +2887,13 @@ Default '.'. Menu character accelerator to select all items on this page of a menu. Implemented by the Amiga, Gem and tty ports. Default ','. +." .lp menu_tab_sep +." Format menu entries using TAB to separate columns (default off). +." Only applicable to some menus, and only useful to some interfaces. +." Debug mode only. +.lp monpolycontrol +Prompt for new form whenever any monster changes shape (default off). +Debug mode only. .lp msghistory The number of top line messages to save (and recall with ^P) (default 20). Cannot be set with the `O' command. @@ -3100,6 +3099,9 @@ used `teleport' only. Whether or not the effect is noticeable will depend upon the window port used or on the type of terminal. Persistent. .lp safe_pet Prevent you from (knowingly) attacking your pets (default on). Persistent. +.lp sanity_check +Evaluate monsters, objects, and map prior to each turn (default off). +Debug mode only. .lp scores Control what parts of the score list you are shown at the end (ex. ``scores:5 top scores/4 around my score/own scores''). Only the first @@ -3172,6 +3174,9 @@ the score list around after game end on a terminal or emulating window. Allow the travel command (default on). Turning this option off will prevent the game from attempting unintended moves if you make inadvertent mouse clicks on the map window. Persistent. +." .lp travel_debug +." Display intended path during each step of travel (default off). +." Debug mode only. .lp verbose Provide more commentary during the game (default on). Persistent. .lp whatis_coord @@ -3227,6 +3232,9 @@ move by skipping the same glyphs. Select which windowing system to use, such as ``tty'' or ``X11'' (default depends on version). Cannot be set with the `O' command. +.lp wizweight +Augment object descriptions with their objects' weight (default off). +Debug mode only. .lp zerocomp When writing out a save file, perform zero-comp compression of the contents. Not all ports support zero-comp compression. It has no effect @@ -4597,7 +4605,7 @@ again to \fBM. Drew Streib\fP and \fBPasi Kallinen\fP for providing a public NetHack server at nethack.alt.org. Thanks to \fBKeith Simpson\fP and \fBAndy Thomson\fP for hardfought.org. Thanks to all those unnamed dungeoneers who invest their time and effort into annual -NetHack tournaments such as Junehack and in days past, +NetHack tournaments such as Junethack and in days past, devnull.net (gone for now, but not forgotten). .pg .ce diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index f12b651a6..29bf17f69 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -45,7 +45,7 @@ %.au \author{Original version - Eric S. Raymond\\ (Edited and expanded for 3.6 by Mike Stephenson and others)} -\date{August 30, 2018} +\date{September 26, 2018} \maketitle @@ -1244,11 +1244,6 @@ Default key is '{\tt M-l}', and '{\tt l}' if {\it number\verb+_+pad\/} is on. Precede with the `{\tt m}' prefix to skip containers at your location and go directly to removing a saddle. %.lp -\item[\tb{\#monpolycontrol}] -Control monster polymorphs. -Autocompletes. -Debug mode only. -%.lp \item[\tb{\#monster}] Use a monster's special ability (when polymorphed into monster form). Autocompletes. Default key is '{\tt M-m}'. @@ -1494,16 +1489,11 @@ Wield a weapon. Default key is '{\tt w}'. \item[\tb{\#wipe}] Wipe off your face. Autocompletes. Default key is '{\tt M-w}'. %.lp -\item[\tb{\#wizdebug\verb+_+bury}] +\item[\tb{\#wizbury}] Bury objects under and around you. Autocompletes. Debug mode only. %.lp -\item[\tb{\#wizdebug\verb+_+traveldisplay}] -Toggle travel display. -Autocompletes. -Debug mode only. -%.lp \item[\tb{\#wizdetect}] Search for hidden things (secret doors or traps or unseen monsters) within a modest radius. @@ -3370,6 +3360,15 @@ Default `.'. Menu character accelerator to select all items on this page of a menu. Implemented by the Amiga, Gem and tty ports. Default `,'. +% %.lp +% \item[\ib{menu\verb+_+tab\verb+_+sep}] +% Format menu entries using TAB to separate columns (default off). +% Only applicable to some menus, and only useful to some interfaces. +% Debug mode only. +%.lp +\item[\ib{monpolycontrol}] +Prompt for new form whenever any monster changes shape (default off). +Debug mode only. %.lp \item[\ib{msghistory}] The number of top line messages to save (and recall with `{\tt \^{}P}') @@ -3608,6 +3607,10 @@ depend upon the window port used or on the type of terminal. Persistent. %.lp \item[\ib{safe\verb+_+pet}] Prevent you from (knowingly) attacking your pets (default on). Persistent. +%+.lp +\item[\ib{sanity\verb+_+check}] ++Evaluate monsters, objects, and map prior to each turn (default off). ++Debug mode only. %.lp \item[\ib{scores}] Control what parts of the score list you are shown at the end (ex.\ @@ -3698,6 +3701,10 @@ the score list around after game end on a terminal or emulating window. Allow the travel command (default on). Turning this option off will prevent the game from attempting unintended moves if you make inadvertent mouse clicks on the map window. Persistent. +% %.lp +% \item[ib{travel\verb+_+debug}] +% Display intended path during each step of travel (default off). +% Debug mode only. %.lp \item[\ib{verbose}] Provide more commentary during the game (default on). Persistent. @@ -3766,6 +3773,10 @@ Select which windowing system to use, such as ``{\tt tty}'' or ``{\tt X11}'' (default depends on version). Cannot be set with the `{\tt O}' command. %.lp +\item[\ib{wizweight}] +Augment object descriptions with their objects' weight (default off). +Debug mode only. +%.lp \item[\ib{zerocomp}] When writing out a save file, perform zero-comp compression of the contents. Not all ports support zero-comp compression. It has no effect diff --git a/doc/Guidebook.txt b/doc/Guidebook.txt index f43daba67..35fc5a50c 100644 --- a/doc/Guidebook.txt +++ b/doc/Guidebook.txt @@ -5731,7 +5731,7 @@ NetHack server at nethack.alt.org. Thanks to Keith Simpson and Andy Thomson for hardfought.org. Thanks to all those unnamed dun- geoneers who invest their time and effort into annual NetHack - tournaments such as Junehack and in days past, devnull.net (gone + tournaments such as Junethack and in days past, devnull.net (gone for now, but not forgotten). diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 67f487211..a56ab4b9f 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -168,6 +168,8 @@ tty: turn off an optimization that is the suspected cause of Windows reported tty: ensure that current status fields are always copied to prior status values so that comparisons are correct tty: fix an out of bounds error in tty_status_update() for BL_HUNGER case +tty: fix leftover display artifact when last field on the row got smaller + and optimize so only the right-most field requires the cleanup code X11: its use of genl_status_update exposed a negative index use that could lead to a segfault @@ -229,6 +231,9 @@ wizard mode #wizidentify can now select individual items for permanent identify everything if everything is already fully identified spiders will occasionally spin webs when moving around make mine town "orctown" variation a multiple level feature of the mines +replace #monpolycontrol command with monpolycontrol boolean option +replace #wizdebug_traveldisplay command with travel_debug boolean option +rename #wizdebug_bury command to #wizbury Code Cleanup and Reorganization diff --git a/include/flag.h b/include/flag.h index f2339f6c0..58cda7838 100644 --- a/include/flag.h +++ b/include/flag.h @@ -240,11 +240,12 @@ struct instance_flags { boolean defer_plname; /* X11 hack: askname() might not set plname */ boolean herecmd_menu; /* use menu when mouseclick on yourself */ boolean invis_goldsym; /* gold symbol is ' '? */ - int parse_config_file_src; /* hack for parse_config_line() */ + int failing_untrap; /* move_into_trap() -> spoteffects() -> dotrap() */ int in_lava_effects; /* hack for Boots_off() */ int last_msg; /* indicator of last message player saw */ - int purge_monsters; /* # of dead monsters still on fmon list */ int override_ID; /* true to force full identification of objects */ + int parse_config_file_src; /* hack for parse_config_line() */ + int purge_monsters; /* # of dead monsters still on fmon list */ int suppress_price; /* controls doname() for unpaid objects */ int terrainmode; /* for getpos()'s autodescribe when #terrain is active */ #define TER_MAP 0x01 @@ -257,6 +258,7 @@ struct instance_flags { boolean getloc_usemenu; boolean getloc_moveskip; coord travelcc; /* coordinates for travel_cache */ + boolean trav_debug; /* display travel path (#if DEBUG only) */ boolean window_inited; /* true if init_nhwindows() completed */ boolean vision_inited; /* true if vision is ready */ boolean sanity_check; /* run sanity checks */ diff --git a/include/wintty.h b/include/wintty.h index a4a6625a5..9a375145e 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -79,6 +79,7 @@ struct tty_status_fields { boolean valid; boolean dirty; boolean redraw; + boolean padright; }; #endif @@ -228,6 +229,8 @@ E short FDECL(set_tty_font_name, (winid, char *)); #endif E char *NDECL(tty_get_color_string); #endif +E void FDECL(tty_status_enablefield, + (int, const char *, const char *, BOOLEAN_P)); E void NDECL(tty_status_init); E void FDECL(tty_status_update, (int, genericptr_t, int, int, int, unsigned long *)); diff --git a/src/cmd.c b/src/cmd.c index f9bed807f..54054f3c3 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -47,7 +47,6 @@ extern const char *enc_stat[]; /* encumbrance status from botl.c */ #ifdef DEBUG extern int NDECL(wiz_debug_cmd_bury); -extern int NDECL(wiz_debug_cmd_traveldisplay); #endif #ifdef DUMB /* stuff commented out in extern.h, but needed here */ @@ -154,7 +153,6 @@ STATIC_PTR int NDECL(wiz_show_seenv); STATIC_PTR int NDECL(wiz_show_vision); STATIC_PTR int NDECL(wiz_smell); STATIC_PTR int NDECL(wiz_intrinsic); -STATIC_PTR int NDECL(wiz_mon_polycontrol); STATIC_PTR int NDECL(wiz_show_wmodes); STATIC_DCL void NDECL(wiz_map_levltyp); STATIC_DCL void NDECL(wiz_levltyp_legend); @@ -399,14 +397,24 @@ doextlist(VOID_ARGS) if (!*searchbuf) { any.a_int = 2; - add_menu(menuwin, NO_GLYPH, &any, 's', 0, ATR_NONE, + /* was 's', but then using ':' handling within the interface + would only examine the two or three meta entries, not the + actual list of extended commands shown via separator lines; + having ':' as an explicit selector overrides the default + menu behavior for it; we retain 's' as a group accelerator */ + add_menu(menuwin, NO_GLYPH, &any, ':', 's', ATR_NONE, "Search extended commands", MENU_UNSELECTED); } else { Strcpy(buf, "Show all, clear search"); if (strlen(buf) + strlen(searchbuf) + strlen(" (\"\")") < QBUFSZ) Sprintf(eos(buf), " (\"%s\")", searchbuf); any.a_int = 3; - add_menu(menuwin, NO_GLYPH, &any, 's', 0, ATR_NONE, + /* specifying ':' as a group accelerator here is mostly a + statement of intent (we'd like to accept it as a synonym but + also want to hide it from general menu use) because it won't + work for interfaces which support ':' to search; use as a + general menu command takes precedence over group accelerator */ + add_menu(menuwin, NO_GLYPH, &any, 's', ':', ATR_NONE, buf, MENU_UNSELECTED); } if (wizard) { @@ -415,7 +423,7 @@ doextlist(VOID_ARGS) onelist ? "Show debugging commands in separate section" : "Show all alphabetically, including debugging commands", MENU_UNSELECTED); - } + } any = zeroany; add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", MENU_UNSELECTED); @@ -434,8 +442,13 @@ doextlist(VOID_ARGS) continue; /* if searching, skip this command if it doesn't match */ if (*searchbuf + /* first try case-insensitive substring match */ && !strstri(efp->ef_txt, searchbuf) - && !strstri(efp->ef_desc, searchbuf)) + && !strstri(efp->ef_desc, searchbuf) + /* wildcard support; most interfaces use case-insensitve + pmatch rather than regexp for menu searching */ + && !pmatchi(searchbuf, efp->ef_txt) + && !pmatchi(searchbuf, efp->ef_desc)) continue; /* skip wizard mode commands if not in wizard mode; when showing two sections, skip wizard mode commands @@ -480,7 +493,7 @@ doextlist(VOID_ARGS) menumode = 1 - menumode; /* toggle 0 -> 1, 1 -> 0 */ redisplay = TRUE; break; - case 2: /* 's' when not searching yet: enable search */ + case 2: /* ':' when not searching yet: enable search */ search = TRUE; break; case 3: /* 's' when already searching: disable search */ @@ -494,7 +507,7 @@ doextlist(VOID_ARGS) onelist = 1 - onelist; /* toggle 0 -> 1, 1 -> 0 */ redisplay = TRUE; break; - } + } free((genericptr_t) selected); } else { search = FALSE; @@ -878,16 +891,6 @@ wiz_level_tele(VOID_ARGS) return 0; } -/* #monpolycontrol command - choose new form for shapechangers, polymorphees */ -STATIC_PTR int -wiz_mon_polycontrol(VOID_ARGS) -{ - iflags.mon_polycontrol = !iflags.mon_polycontrol; - pline("Monster polymorph control is %s.", - iflags.mon_polycontrol ? "on" : "off"); - return 0; -} - /* #levelchange command - adjust hero's experience level */ STATIC_PTR int wiz_level_change(VOID_ARGS) @@ -3062,8 +3065,6 @@ struct ext_func_tab extcmdlist[] = { { '\0', "migratemons", "migrate N random monsters", wiz_migrate_mons, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, #endif - { '\0', "monpolycontrol", "control monster polymorphs", - wiz_mon_polycontrol, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, { M('m'), "monster", "use monster's special ability", domonability, IFBURIED | AUTOCOMPLETE }, { 'N', "name", "name a monster or an object", @@ -3166,10 +3167,8 @@ struct ext_func_tab extcmdlist[] = { { 'w', "wield", "wield (put in use) a weapon", dowield }, { M('w'), "wipe", "wipe off your face", dowipe, AUTOCOMPLETE }, #ifdef DEBUG - { '\0', "wizdebug_bury", "wizard debug: bury objs under and around you", + { '\0', "wizbury", "bury objs under and around you", wiz_debug_cmd_bury, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, - { '\0', "wizdebug_traveldisplay", "wizard debug: toggle travel display", - wiz_debug_cmd_traveldisplay, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, #endif { C('e'), "wizdetect", "reveal hidden things within a small radius", wiz_detect, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, diff --git a/src/hack.c b/src/hack.c index fabd7e17f..1a83ae3d9 100644 --- a/src/hack.c +++ b/src/hack.c @@ -897,17 +897,6 @@ int mode; return TRUE; } -#ifdef DEBUG -static boolean trav_debug = FALSE; - -/* in this case, toggle display of travel debug info */ -int wiz_debug_cmd_traveldisplay() -{ - trav_debug = !trav_debug; - return 0; -} -#endif /* DEBUG */ - /* * Find a path from the destination (u.tx,u.ty) back to (u.ux,u.uy). * A shortest path is returned. If guess is TRUE, consider various @@ -1065,7 +1054,7 @@ int mode; } #ifdef DEBUG - if (trav_debug) { + if (iflags.trav_debug) { /* Use of warning glyph is arbitrary. It stands out. */ tmp_at(DISP_ALL, warning_to_glyph(1)); for (i = 0; i < nn; ++i) { @@ -1121,7 +1110,7 @@ int mode; goto found; } #ifdef DEBUG - if (trav_debug) { + if (iflags.trav_debug) { /* Use of warning glyph is arbitrary. It stands out. */ tmp_at(DISP_ALL, warning_to_glyph(2)); tmp_at(px, py); @@ -2053,6 +2042,7 @@ boolean pick; struct monst *mtmp; struct trap *trap = t_at(u.ux, u.uy); + int trapflag = iflags.failing_untrap ? FORCETRAP : 0; /* prevent recursion from affecting the hero all over again [hero poly'd to iron golem enters water here, drown() inflicts @@ -2118,7 +2108,7 @@ boolean pick; if (!spottrap || spottraptyp != trap->ttyp) { spottrap = trap; spottraptyp = trap->ttyp; - dotrap(trap, 0); /* fall into arrow trap, etc. */ + dotrap(trap, trapflag); /* fall into arrow trap, etc. */ spottrap = (struct trap *) 0; spottraptyp = NO_TRAP; } diff --git a/src/options.c b/src/options.c index 490d68a0a..9829874e8 100644 --- a/src/options.c +++ b/src/options.c @@ -160,6 +160,7 @@ static struct Bool_Opt { #else { "menu_overlay", (boolean *) 0, FALSE, SET_IN_FILE }, #endif + { "monpolycontrol", &iflags.mon_polycontrol, FALSE, SET_IN_WIZGAME }, { "mouse_support", &iflags.wc_mouse_support, TRUE, DISP_IN_GAME }, /*WC*/ #ifdef NEWS { "news", &iflags.news, TRUE, DISP_IN_GAME }, @@ -173,7 +174,7 @@ static struct Bool_Opt { #else { "page_wait", (boolean *) 0, FALSE, SET_IN_FILE }, #endif - /* 3.6.2: move perm_invent from flags to inflags and out of save file */ + /* 3.6.2: move perm_invent from flags to iflags and out of save file */ { "perm_invent", &iflags.perm_invent, FALSE, SET_IN_GAME }, { "pickup_thrown", &flags.pickup_thrown, TRUE, SET_IN_GAME }, { "popup_dialog", &iflags.wc_popup_dialog, FALSE, SET_IN_GAME }, /*WC*/ @@ -221,6 +222,9 @@ static struct Bool_Opt { { "tombstone", &flags.tombstone, TRUE, SET_IN_GAME }, { "toptenwin", &iflags.toptenwin, FALSE, SET_IN_GAME }, { "travel", &flags.travelcmd, TRUE, SET_IN_GAME }, +#ifdef DEBUG + { "travel_debug", &iflags.trav_debug, FALSE, SET_IN_WIZGAME }, /*hack.c*/ +#endif { "use_darkgray", &iflags.wc2_darkgray, TRUE, SET_IN_FILE }, #ifdef WIN32 { "use_inverse", &iflags.wc_inverse, TRUE, SET_IN_GAME }, /*WC*/ diff --git a/src/trap.c b/src/trap.c index b9252d18e..056570906 100644 --- a/src/trap.c +++ b/src/trap.c @@ -886,8 +886,7 @@ unsigned trflags; /* then proceed to normal trap effect */ } else if (already_seen && !forcetrap) { if ((Levitation || (Flying && !plunged)) - && (is_pit(ttype) || ttype == HOLE - || ttype == BEAR_TRAP)) { + && (is_pit(ttype) || ttype == HOLE || ttype == BEAR_TRAP)) { You("%s over %s %s.", Levitation ? "float" : "fly", a_your[trap->madeby_u], defsyms[trap_to_defsym(ttype)].explanation); @@ -1198,16 +1197,23 @@ unsigned trflags; if (ttype == SPIKED_PIT) { oldumort = u.umortality; losehp(Maybe_Half_Phys(rnd(conj_pit ? 4 : adj_pit ? 6 : 10)), + /* note: these don't need locomotion() handling; + if fatal while poly'd and Unchanging, the + death reason will be overridden with + "killed while stuck in creature form" */ plunged - ? "deliberately plunged into a pit of iron spikes" - : conj_pit ? "stepped into a pit of iron spikes" - : adj_pit ? "stumbled into a pit of iron spikes" - : "fell into a pit of iron spikes", + ? "deliberately plunged into a pit of iron spikes" + : conj_pit + ? "stepped into a pit of iron spikes" + : adj_pit + ? "stumbled into a pit of iron spikes" + : "fell into a pit of iron spikes", NO_KILLER_PREFIX); if (!rn2(6)) poisoned("spikes", A_STR, - (conj_pit || adj_pit) ? "stepping on poison spikes" - : "fall onto poison spikes", + (conj_pit || adj_pit) + ? "stepping on poison spikes" + : "fall onto poison spikes", /* if damage triggered life-saving, poison is limited to attrib loss */ (u.umortality > oldumort) ? 0 : 8, FALSE); @@ -3912,7 +3918,14 @@ struct trap *ttmp; there are objects covering this trap */ ttmp->tseen = 0; /* hack for check_here() */ /* trigger the trap */ + iflags.failing_untrap++; /* spoteffects() -> dotrap(,FORCETRAP) */ spoteffects(TRUE); /* pickup() + dotrap() */ + iflags.failing_untrap--; + /* this should no longer be necessary; before the failing_untrap + hack, Flying hero would not trigger an unseen bear trap and + setting it not-yet-seen above resulted in leaving it hidden */ + if ((ttmp = t_at(u.ux, u.uy)) != 0) + ttmp->tseen = 1; exercise(A_WIS, FALSE); } } @@ -3991,16 +4004,6 @@ boolean force_failure; } } else if (under_u) { dotrap(ttmp, 0); - } else if (ttype == BEAR_TRAP && (Levitation || Flying)) { - /* There was a report of oddities of the trap - vanishing from view due to tseen being cleared - (which was deliberate to work around a check_here() - issue). Since you won't actually end up in the trap - during the #untrap operation anyway due to - Levitation and Flying checks further along, - just avoid the whole "vanishing trap" scenario - by failing the #untrap operation right here. */ - You("couldn't reach it from your vantage point."); } else { move_into_trap(ttmp); } diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 34cc45f5d..145a535fe 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -103,7 +103,7 @@ struct window_procs tty_procs = { #endif tty_getmsghistory, tty_putmsghistory, tty_status_init, - genl_status_finish, genl_status_enablefield, + genl_status_finish, tty_status_enablefield, #ifdef STATUS_HILITES tty_status_update, #else @@ -187,6 +187,7 @@ STATIC_DCL int NDECL(condition_size); STATIC_DCL int FDECL(make_things_fit, (BOOLEAN_P)); STATIC_DCL void FDECL(shrink_enc, (int)); STATIC_DCL void FDECL(shrink_dlvl, (int)); +STATIC_DCL void NDECL(do_setlast); #endif /* @@ -3530,7 +3531,8 @@ static const char *encvals[3][6] = { { "", "Burden", "Stress", "Strain", "Overtax", "Overload" }, { "", "Brd", "Strs", "Strn", "Ovtx", "Ovld" } }; -static enum statusfields fieldorder[2][15] = { /* 2: two status lines */ +#define MAX_PER_ROW 15 +static enum statusfields fieldorder[2][MAX_PER_ROW] = { /* 2: two status lines */ { BL_TITLE, BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, BL_ALIGN, BL_SCORE, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH, BL_FLUSH }, @@ -3539,6 +3541,8 @@ static enum statusfields fieldorder[2][15] = { /* 2: two status lines */ BL_CAP, BL_CONDITION, BL_FLUSH } }; +static int last_on_row[2]; +static boolean setlast = FALSE; static boolean windowdata_init = FALSE; static int cond_shrinklvl = 0, cond_width_at_shrink = 0; static int enclev = 0, enc_shrinklvl = 0; @@ -3584,6 +3588,7 @@ tty_status_init() tty_status[NOW][i].valid = FALSE; tty_status[NOW][i].dirty = FALSE; tty_status[NOW][i].redraw = FALSE; + tty_status[NOW][i].padright = FALSE; tty_status[BEFORE][i] = tty_status[NOW][i]; } tty_condition_bits = 0L; @@ -3594,6 +3599,36 @@ tty_status_init() genl_status_init(); } +void +tty_status_enablefield(fieldidx, nm, fmt, enable) +int fieldidx; +const char *nm; +const char *fmt; +boolean enable; +{ + genl_status_enablefield(fieldidx, nm, fmt, enable); + /* force re-evaluation of last field on the row */ + setlast = FALSE; +} + +void +do_setlast() +{ + int i, row, fld; + + setlast = TRUE; + for (row = 0; row < 2; ++row) + for (i = MAX_PER_ROW - 1; i > 0; --i) { + fld = fieldorder[row][i]; + + if (fld == BL_FLUSH || !status_activefields[fld]) + continue; + + last_on_row[row] = fld; + break; + } +} + #ifdef STATUS_HILITES /* @@ -3672,6 +3707,9 @@ unsigned long *colormasks; if ((fldidx >= 0 && fldidx < MAXBLSTATS) && !status_activefields[fldidx]) return; + if (!setlast) + do_setlast(); + #ifndef TEXTCOLOR color = (color & ~0x00FF) | NO_COLOR; #endif @@ -3845,8 +3883,12 @@ int *topsz, *bottomsz; /* On a change to the field length, everything further to the right must be updated as well */ - if (tty_status[NOW][idx].lth != tty_status[BEFORE][idx].lth) + if (tty_status[NOW][idx].lth != tty_status[BEFORE][idx].lth) { update_right = TRUE; + if ((tty_status[NOW][idx].lth < tty_status[BEFORE][idx].lth) && + idx == last_on_row[row]) + tty_status[NOW][idx].padright = TRUE; + } if (!update_right && !forcefields) { /* @@ -4291,17 +4333,26 @@ render_status(VOID_ARGS) term_start_color(coloridx); } tty_putstatusfield(&tty_status[NOW][fldidx], - text, x, y); + text, x, y); if (iflags.hilite_delta) { if (coloridx != NO_COLOR && coloridx != CLR_MAX) term_end_color(); End_Attr(attridx); } + if (tty_status[NOW][fldidx].padright) { + int cnt = tty_status[BEFORE][fldidx].lth + - tty_status[NOW][fldidx].lth; + + x += (tty_status[NOW][fldidx].lth - 1); + while (cnt-- > 0) + tty_putstatusfield(nullfield, " ", x++, y); + } } } - /* reset .redraw and .dirty now that they've been rendered */ + /* reset .redraw, .dirty, .padright now that they've been rendered */ tty_status[NOW][fldidx].dirty = FALSE; tty_status[NOW][fldidx].redraw = FALSE; + tty_status[NOW][fldidx].padright = FALSE; /* * Make a copy of the entire tty_status struct for comparison