Merge branch 'NetHack-3.6.2-beta01' into NetHack-3.6.2

This commit is contained in:
nhmall
2019-04-02 01:45:00 -04:00
26 changed files with 986 additions and 631 deletions

View File

@@ -1,4 +1,4 @@
# NetHack 3.6 Valkyrie.des $NHDT-Date: 1432512783 2015/05/25 00:13:03 $ $NHDT-Branch: master $:$NHDT-Revision: 1.13 $
# NetHack 3.6 Valkyrie.des $NHDT-Date: 1553807172 2019/03/28 21:06:12 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.15 $
# Copyright (c) 1989 by Jean-Christophe Collet
# Copyright (c) 1991-2 by M. Stephenson
# NetHack may be freely redistributed. See license for details.
@@ -216,9 +216,14 @@ REGION:(00,00,34,16),lit,"ordinary"
STAIR:(45,10),up
# Non diggable walls
NON_DIGGABLE:(00,00,34,16)
# Drawbridges
# Drawbridges; northern one opens from the south (portcullis) to further
# north (lowered span), southern one from the north to further south
DRAWBRIDGE:(17,02),south,random
DRAWBRIDGE:(17,14),north,open
IF [75%] {
DRAWBRIDGE:(17,14),north,open
} ELSE {
DRAWBRIDGE:(17,14),north,random
}
# Objects
OBJECT:('(',"crystal ball"),(17,08),blessed,5,name:"The Orb of Fate"
OBJECT:random,random

View File

@@ -1,6 +1,6 @@
Boolean options not under specific compile flags (with default values in []):
(You can learn which options exist in your version by checking your current
option setting, which is reached via the 'O' cmd.)
option setting, which is reached via the 'O' command.)
acoustics can your character hear anything [TRUE]
autodescribe describe the terrain under cursor [FALSE]
@@ -17,7 +17,8 @@ cmdassist give help for errors on direction & other commands [TRUE]
confirm ask before hitting tame or peaceful monsters [TRUE]
dark_room show floor not in sight in different color [TRUE]
eight_bit_tty send 8-bit characters straight to terminal [FALSE]
extmenu use a menu for selecting extended commands (#) [FALSE]
extmenu tty: use a menu for selecting extended commands (#)[FALSE]
X11: menu has all commands (T) or traditional subset (F)
fixinv try to retain the same letter for the same object [TRUE]
force_invmenu commands asking for inventory item show a menu [FALSE]
goldX when filtering objects by bless/curse state, [FALSE]

View File

@@ -1,4 +1,4 @@
.\" $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.301 $ $NHDT-Date: 1553480404 2019/03/25 02:20:04 $
.\" $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.303 $ $NHDT-Date: 1554134322 2019/04/01 15:58:42 $
.\"
.\" This is an excerpt from the 'roff' man page from the 'groff' package.
.\" NetHack's Guidebook.mn currently does *not* adhere to these guidelines.
@@ -2972,8 +2972,12 @@ Changes the extended commands interface to pop-up a menu of available
commands.
It is keystroke compatible with the traditional interface except that it
does not require that you hit \fIEnter\fP.
It is implemented only by the tty port
(default off), when the game has been compiled to support tty graphics.
It is implemented for the tty interface (default off).
.lp ""
For the X11 interface, which always uses a menu for choosing an extended
command, it controls whether the menu shows all available commands (on)
or just the subset of commands which have traditionally been considered
extended ones (off).
.lp female
An obsolete synonym for \(lqgender:female\(rq.
Cannot be set with the \(oqO\(cq command.
@@ -3657,7 +3661,7 @@ up (default yes).
.lp statuslines
Number of lines for traditional below-the-map status display.
Acceptable values are 2 and 3 (default is 2).
Curses interface only.
Curses and tty interfaces only.
.lp "term_cols\ \ \fIand\fP"
.lp term_rows
Curses interface only.

View File

@@ -3266,8 +3266,13 @@ Cannot be set with the `{\tt O}' command.
\item[\ib{extmenu}]
Changes the extended commands interface to pop-up a menu of available commands.
It is keystroke compatible with the traditional interface except that it does
not require that you hit Enter. It is implemented only by the tty port
(default off), when the game has been compiled to support tty graphics.
not require that you hit Enter.
It is implemented for the tty interface (default off).
.lp ""
For the X11 interface, which always uses a menu for choosing an extended
command, it controls whether the menu shows all available commands (on)
or just the subset of commands which have traditionally been considered
extended ones (off).
%.lp
\item[\ib{female}]
An obsolete synonym for ``{\tt gender:female}''. Cannot be set with the
@@ -4057,7 +4062,7 @@ it starts up (default yes).
\item[\ib{statuslines}]
Number of lines for traditional below-the-map status display.
Acceptable values are 2 and 3 (default is 2).
Curses interface only.
Curses and tty interfaces only.
%.lp
\item[\ib{term\verb+_+cols}\ \ {\it and}]"
%.lp

View File

@@ -1,4 +1,4 @@
$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.285 $ $NHDT-Date: 1553653612 2019/03/27 02:26:52 $
$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.296 $ $NHDT-Date: 1554136021 2019/04/01 16:27:01 $
This fixes36.2 file is here to capture information about updates in the 3.6.x
lineage following the release of 3.6.1 in April 2018. Please note, however,
@@ -398,6 +398,14 @@ avoid spurious status refresh when hero gains experience while 'showexp' and
'showscore' options are off
using Cleaver to attack a worm tail segment but kill adjacent head first would
result in an impossible warning from cutworm
Valkyrie quest was supposed to have a 50:50 chance that northern drawbridge
would be raised, but both were always lowered; chances now are: both
lowered: 3/8, S down+N up: 3/8, N down+S up: 1/8, both raised: 1/8
shorten the getpos prompt for teleport destination so that it won't yield a
--More-- prompt for the help hint (--More-- still possible when riding)
once a status highlight for a temporary rule ('up', 'down', 'changed') timed
out, further spurious status updates (evaluating all fields) would
occur every 'statushilites' turns even if no fields had changed
Fixes to Post-3.6.1 Problems that Were Exposed Via git Repository
@@ -478,9 +486,22 @@ tty: fix leftover display artifact when the last field on the row got placed
to the left of where it was previously due to it, or one of the fields
to its left, getting shorter
tty: support hitpointbar even when statushilites is set to 0
tty: when status condition names were abbreviated due to lack of room, they
were inconsistent about re-expanding when more room became available
tty: when encumbrance state was abbreviated due to lack of room, there was no
separation from preceding status field and the value would not update
when the state changed (except for removal on change to unencumbered)
tty: when clipping was used to show a subset of the map on a small display,
panning into a new subset while using the cursor to pick a location
would ask the core to generate a new view of the map rather than use
whatever was currently shown, bringing back suppressed monsters/
objects/traps for #terrain and new hallucinatory monsters for farlook
X11: its use of genl_status_update exposed a negative index use that could
lead to a segfault
X11: rollback disabling of keystroke input for PICK_NONE menus (for scrolling)
X11: make use of the 'extmenu' option: On to choose among all commands, Off
to choose among the traditional extended command subset
X11: support menu scrolling via (^ < > |) in the extended commands menu
curses: catch up with tty to not put dolook/whatis autodescribe feedback into
^P message recall (multi-digit count feedback was already handled)
curses: if the interface code ran out of memory, it would crash rather than
@@ -508,6 +529,12 @@ curses: the memory deallocation was releasing previous messages when curses
curses: popup window to show ^P output was removed from screen but never
deleted; further ^P's repeated that cycle; likewise for help which
displays an external text file
curses: preserve ^P message history across save/restore
curses: highlighting of status conditions was broken by the fix for timing out
of temporary highlights setting off unnecessary status updates
curses: if player pressed ESC at More>> prompt to suppress remaining messages
for the current move and then hero got another move on the same turn,
messages and most prompts would stay suppressed during that extra move
vms: add compile of isaac64.c to Makefile.src and vmsbuild.com
vms+curses: add compile support but it is known to fail to build
@@ -588,7 +615,7 @@ windows-tty: add support for mouse_support:0 (disabled), mouse_support:1
X11: implement menucolors and allow menus to obey some attributes
X11: make key translations work with menus on Linux
X11: allow mouse wheel scrolling to work in menus by default
X11: handle paged menu control keys
X11: handle menu scrolling via first-/previous-/next-/last-page keys (^ < > |)
X11: remember perm_invent window geometry
X11: handle X errors via panic
X11: don't reuse perm_invent window for picking an object
@@ -646,10 +673,13 @@ in wizard mode, ^T can be preceded by 'm' prefix in order to test teleporting
include isaac64 for pseudo random number generation
core prng and display prng use different contexts
when healing magic other than unicorn horn cures blindness, cure deafness too
do less status updating when the 'time' option is on
curses: status display substantially revamped for both horizontal (via
'align_status:bottom' or 'top') and vertical (via 'align_status:left'
or 'right'); 3-line horizontal layout (via 'statuslines:3') added
curses: support msg_window:full; default is still msg_window:reversed
tty: support statuslines:3 and dynamically switching between 2 and 3 with 'O'
(requires a display with at least 25 lines or that CLIPPING be enabled)
NetHack Community Patches (or Variation) Included

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 extern.h $NHDT-Date: 1552945074 2019/03/18 21:37:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.695 $ */
/* NetHack 3.6 extern.h $NHDT-Date: 1554045807 2019/03/31 15:23:27 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.697 $ */
/* Copyright (c) Steve Creps, 1988. */
/* NetHack may be freely redistributed. See license for details. */
@@ -159,6 +159,7 @@ E long NDECL(botl_score);
E int FDECL(describe_level, (char *));
E const char *FDECL(rank_of, (int, SHORT_P, BOOLEAN_P));
E void NDECL(bot);
E void NDECL(timebot);
E void FDECL(status_initialize, (BOOLEAN_P));
E void NDECL(status_finish);
E void FDECL(status_notify_windowport, (BOOLEAN_P));
@@ -351,6 +352,7 @@ E void NDECL(see_traps);
E void NDECL(curs_on_u);
E int NDECL(doredraw);
E void NDECL(docrt);
E void NDECL(redraw_map);
E void FDECL(show_glyph, (int, int, int));
E void NDECL(clear_glyph_buffer);
E void FDECL(row_refresh, (int, int, int));

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 flag.h $NHDT-Date: 1553204011 2019/03/21 21:33:31 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.148 $ */
/* NetHack 3.6 flag.h $NHDT-Date: 1554155745 2019/04/01 21:55:45 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.150 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */
@@ -322,10 +322,8 @@ struct instance_flags {
#endif
#endif
uchar bouldersym; /* symbol for boulder display */
#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
char prevmsg_window; /* type of old message window to use */
boolean extmenu; /* extended commands use menu interface */
#endif
#ifdef MFLOPPY
boolean checkspace; /* check disk space before writing files */
/* (in iflags to allow restore after moving
@@ -364,9 +362,10 @@ struct instance_flags {
#ifdef TTY_TILES_ESCCODES
boolean vt_tiledata; /* output console codes for tile support in TTY */
#endif
boolean clicklook; /* allow right-clicking for look */
boolean cmdassist; /* provide detailed assistance for some comnds */
boolean time_botl; /* context.botl for 'time' (moves) only */
boolean wizweight; /* display weight of everything in wizard mode */
boolean cmdassist; /* provide detailed assistance for some commands */
boolean clicklook; /* allow right-clicking for look */
/*
* Window capability support.
*/

View File

@@ -222,6 +222,8 @@ extern void curses_init_mesg_history(void);
extern void curses_teardown_messages(void);
extern void curses_prev_mesg(void);
extern void curses_count_window(const char *count_text);
char *curses_getmsghistory(BOOLEAN_P);
void curses_putmsghistory(const char *, BOOLEAN_P);
#endif /* WINCURS_H */

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 wintty.h $NHDT-Date: 1549327485 2019/02/05 00:44:45 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.32 $ */
/* NetHack 3.6 wintty.h $NHDT-Date: 1553858470 2019/03/29 11:21:10 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.33 $ */
/* Copyright (c) David Cohrs, 1991,1992 */
/* NetHack may be freely redistributed. See license for details. */
@@ -79,7 +79,7 @@ struct tty_status_fields {
boolean valid;
boolean dirty;
boolean redraw;
boolean last_on_row;
boolean _not_used; /* was 'last_in_row' */
};
#endif
@@ -151,6 +151,7 @@ E void NDECL(cl_eos);
* a color or whatever. wintty.c should concern itself with WHERE to put
* stuff in a window.
*/
E int FDECL(term_attr_fixup, (int));
E void FDECL(term_start_attr, (int attr));
E void FDECL(term_end_attr, (int attr));
E void NDECL(term_start_raw_bold);
@@ -182,6 +183,7 @@ E void FDECL(win_tty_init, (int));
/* external declarations */
E void FDECL(tty_init_nhwindows, (int *, char **));
E void FDECL(tty_preference_update, (const char *));
E void NDECL(tty_player_selection);
E void NDECL(tty_askname);
E void NDECL(tty_get_nh_event);

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 allmain.c $NHDT-Date: 1553363414 2019/03/23 17:50:14 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.95 $ */
/* NetHack 3.6 allmain.c $NHDT-Date: 1554045808 2019/03/31 15:23:28 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.96 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -181,7 +181,7 @@ boolean resuming;
if (u.ublesscnt)
u.ublesscnt--;
if (flags.time && !context.run)
context.botl = TRUE;
iflags.time_botl = TRUE;
/* One possible result of prayer is healing. Whether or
* not you get healed depends on your current hit points.
@@ -207,8 +207,10 @@ boolean resuming;
: moves % 10)) {
if (Upolyd && u.mh > 1) {
u.mh--;
context.botl = TRUE;
} else if (!Upolyd && u.uhp > 1) {
u.uhp--;
context.botl = TRUE;
} else {
You("pass out from exertion!");
exercise(A_CON, FALSE);
@@ -234,6 +236,7 @@ boolean resuming;
if (!u.uinvulnerable) {
if (Teleportation && !rn2(85)) {
xchar old_ux = u.ux, old_uy = u.uy;
tele();
if (u.ux != old_ux || u.uy != old_uy) {
if (!next_to_u()) {
@@ -356,6 +359,9 @@ boolean resuming;
if (context.botl || context.botlx) {
bot();
curs_on_u();
} else if (iflags.time_botl) {
timebot();
curs_on_u();
}
context.move = 1;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 botl.c $NHDT-Date: 1553387148 2019/03/24 00:25:48 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.137 $ */
/* NetHack 3.6 botl.c $NHDT-Date: 1554045809 2019/03/31 15:23:29 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.140 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2006. */
/* NetHack may be freely redistributed. See license for details. */
@@ -17,6 +17,7 @@ STATIC_OVL NEARDATA int mrank_sz = 0; /* loaded by max_rank_sz (from u_init) */
STATIC_DCL const char *NDECL(rank);
#ifdef STATUS_HILITES
STATIC_DCL void NDECL(bot_via_windowport);
STATIC_DCL void NDECL(stat_update_time);
#endif
static char *
@@ -244,7 +245,21 @@ bot()
putmixed(WIN_STATUS, 0, do_statusline2());
#endif
}
context.botl = context.botlx = 0;
context.botl = context.botlx = iflags.time_botl = FALSE;
}
void
timebot()
{
if (flags.time) {
#ifdef STATUS_HILITES
stat_update_time();
#else
/* old status display updates everything */
bot();
#endif
}
iflags.time_botl = FALSE;
}
/* convert experience level (1..30) to rank index (0..8) */
@@ -399,6 +414,8 @@ char *buf;
/* structure that tracks the status details in the core */
#define MAXVALWIDTH 80 /* actually less, but was using 80 to allocate title
* and leveldesc then using QBUFSZ everywhere else */
#ifdef STATUS_HILITES
struct hilite_s {
enum statusfields fld;
@@ -406,7 +423,7 @@ struct hilite_s {
unsigned anytype;
anything value;
int behavior;
char textmatch[QBUFSZ];
char textmatch[MAXVALWIDTH];
enum relationships rel;
int coloridx;
struct hilite_s *next;
@@ -425,30 +442,29 @@ struct istat_s {
enum statusfields idxmax;
enum statusfields fld;
#ifdef STATUS_HILITES
struct hilite_s *hilite_rule; /* the entry, if any, in 'thresholds'
* list that currently applies */
struct hilite_s *thresholds;
#endif
};
STATIC_DCL void NDECL(init_blstats);
STATIC_DCL char *FDECL(anything_to_s, (char *, anything *, int));
STATIC_OVL int FDECL(percentage, (struct istat_s *, struct istat_s *));
STATIC_OVL int FDECL(compare_blstats, (struct istat_s *, struct istat_s *));
STATIC_DCL boolean FDECL(evaluate_and_notify_windowport_field,
(int, boolean *, int, int));
STATIC_DCL void FDECL(evaluate_and_notify_windowport, (boolean *, int, int));
STATIC_DCL boolean FDECL(eval_notify_windowport_field, (int, boolean *, int));
STATIC_DCL void FDECL(evaluate_and_notify_windowport, (boolean *, int));
#ifdef STATUS_HILITES
STATIC_DCL boolean FDECL(hilite_reset_needed, (struct istat_s *, long));
STATIC_DCL void FDECL(s_to_anything, (anything *, char *, int));
STATIC_DCL boolean FDECL(is_ltgt_percentnumber, (const char *));
STATIC_DCL boolean FDECL(has_ltgt_percentnumber, (const char *));
STATIC_DCL boolean FDECL(parse_status_hl2, (char (*)[QBUFSZ],BOOLEAN_P));
STATIC_DCL boolean FDECL(parse_status_hl2, (char (*)[QBUFSZ], BOOLEAN_P));
STATIC_DCL boolean FDECL(parse_condition, (char (*)[QBUFSZ], int));
STATIC_DCL boolean FDECL(noneoftheabove, (const char *));
STATIC_DCL void FDECL(merge_bestcolor, (int *, int));
STATIC_DCL void FDECL(get_hilite_color, (int, int, genericptr_t, int,
int, int *));
STATIC_DCL struct hilite_s *FDECL(get_hilite, (int, int, genericptr_t,
int, int, int *));
STATIC_DCL unsigned long FDECL(match_str2conditionbitmask, (const char *));
STATIC_DCL unsigned long FDECL(str2conditionbitmask, (char *));
STATIC_DCL void FDECL(split_clridx, (int, int *, int *));
@@ -466,18 +482,25 @@ STATIC_DCL int FDECL(status_hilite_menu_choose_updownboth, (int, const char *,
BOOLEAN_P, BOOLEAN_P));
STATIC_DCL boolean FDECL(status_hilite_menu_add, (int));
#define has_hilite(i) (blstats[0][(i)].thresholds)
/* TH_UPDOWN encompasses specific 'up' and 'down' also general 'changed' */
#define Is_Temp_Hilite(rule) ((rule) && (rule)->behavior == BL_TH_UPDOWN)
/* pointers to current hilite rule and list of this field's defined rules */
#define INIT_THRESH , (struct hilite_s *) 0, (struct hilite_s *) 0
#else /* !STATUS_HILITES */
#define INIT_THRESH /*empty*/
#endif
#define INIT_BLSTAT(name, fmtstr, anytyp, wid, fld) \
{ name, fmtstr, 0L, FALSE, anytyp, { (genericptr_t) 0 }, (char *) 0, \
wid, -1, fld }
wid, -1, fld INIT_THRESH }
#define INIT_BLSTATP(name, fmtstr, anytyp, wid, maxfld, fld) \
{ name, fmtstr, 0L, FALSE, anytyp, { (genericptr_t) 0 }, (char *) 0, \
wid, maxfld, fld }
wid, maxfld, fld INIT_THRESH }
/* If entries are added to this, botl.h will require updating too */
STATIC_DCL struct istat_s initblstats[MAXBLSTATS] = {
INIT_BLSTAT("title", "%s", ANY_STR, 80, BL_TITLE),
INIT_BLSTAT("title", "%s", ANY_STR, MAXVALWIDTH, BL_TITLE),
INIT_BLSTAT("strength", " St:%s", ANY_INT, 10, BL_STR),
INIT_BLSTAT("dexterity", " Dx:%s", ANY_INT, 10, BL_DX),
INIT_BLSTAT("constitution", " Co:%s", ANY_INT, 10, BL_CO),
@@ -498,18 +521,18 @@ STATIC_DCL struct istat_s initblstats[MAXBLSTATS] = {
INIT_BLSTAT("hunger", " %s", ANY_INT, 40, BL_HUNGER),
INIT_BLSTATP("hitpoints", " HP:%s", ANY_INT, 10, BL_HPMAX, BL_HP),
INIT_BLSTAT("hitpoints-max", "(%s)", ANY_INT, 10, BL_HPMAX),
INIT_BLSTAT("dungeon-level", "%s", ANY_STR, 80, BL_LEVELDESC),
INIT_BLSTAT("dungeon-level", "%s", ANY_STR, MAXVALWIDTH, BL_LEVELDESC),
INIT_BLSTAT("experience", "/%s", ANY_LONG, 20, BL_EXP),
INIT_BLSTAT("condition", "%s", ANY_MASK32, 0, BL_CONDITION)
};
#undef INIT_BLSTATP
#undef INIT_BLSTAT
#undef INIT_THRESH
struct istat_s blstats[2][MAXBLSTATS];
static boolean blinit = FALSE, update_all = FALSE;
static boolean valset[MAXBLSTATS];
unsigned long blcolormasks[CLR_MAX];
static long bl_hilite_moves = 0L;
/* we don't put this next declaration in #ifdef STATUS_HILITES.
@@ -519,21 +542,24 @@ static long bl_hilite_moves = 0L;
* the final argument of status_update, with or
* without STATUS_HILITES.
*/
unsigned long cond_hilites[BL_ATTCLR_MAX];
static unsigned long cond_hilites[BL_ATTCLR_MAX];
static int now_or_before_idx = 0; /* 0..1 for array[2][] first index */
void
bot_via_windowport()
{
char buf[BUFSZ];
const char *titl;
register char *nb;
static int i, idx = 0, idx_p, cap;
int i, idx, cap;
long money;
if (!blinit)
panic("bot before init.");
idx_p = idx;
idx = 1 - idx; /* 0 -> 1, 1 -> 0 */
/* toggle from previous iteration */
idx = 1 - now_or_before_idx; /* 0 -> 1, 1 -> 0 */
now_or_before_idx = idx;
/* clear the "value set" indicators */
(void) memset((genericptr_t) valset, 0, MAXBLSTATS * sizeof (boolean));
@@ -549,15 +575,23 @@ bot_via_windowport()
*/
Strcpy(nb = buf, plname);
nb[0] = highc(nb[0]);
nb[10] = '\0';
titl = !Upolyd ? rank() : mons[u.umonnum].mname;
i = (int) (strlen(buf) + sizeof " the " + strlen(titl) - sizeof "");
/* if "Name the Rank/monster" is too long, we truncate the name
but always keep at least 10 characters of it; when hitpintbar is
enabled, anything beyond 30 (long monster name) will be truncated */
if (i > 30) {
i = 30 - (int) (sizeof " the " + strlen(titl) - sizeof "");
nb[max(i, 10)] = '\0';
}
Strcpy(nb = eos(nb), " the ");
if (Upolyd) {
for (i = 0, nb = strcpy(eos(nb), mons[u.umonnum].mname); nb[i]; i++)
Strcpy(nb = eos(nb), titl);
if (Upolyd) { /* when poly'd, capitalize monster name */
for (i = 0; nb[i]; i++)
if (i == 0 || nb[i - 1] == ' ')
nb[i] = highc(nb[i]);
} else
Strcpy(nb = eos(nb), rank());
Sprintf(blstats[idx][BL_TITLE].val, "%-29s", buf);
}
Sprintf(blstats[idx][BL_TITLE].val, "%-30s", buf);
valset[BL_TITLE] = TRUE; /* indicate val already set */
/* Strength */
@@ -689,12 +723,30 @@ bot_via_windowport()
blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_FLY;
if (u.usteed)
blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_RIDE;
evaluate_and_notify_windowport(valset, idx, idx_p);
evaluate_and_notify_windowport(valset, idx);
}
/* update just the status lines' 'time' field */
STATIC_OVL void
stat_update_time()
{
int idx = now_or_before_idx; /* no 0/1 toggle */
int fld = BL_TIME;
/* Time (moves) */
blstats[idx][fld].a.a_long = moves;
valset[fld] = FALSE;
eval_notify_windowport_field(fld, valset, idx);
if ((windowprocs.wincap2 & WC2_FLUSH_STATUS) != 0L)
status_update(BL_FLUSH, (genericptr_t) 0, 0, 0,
NO_COLOR, (unsigned long *) 0);
return;
}
STATIC_OVL boolean
evaluate_and_notify_windowport_field(fld, valsetlist, idx, idx_p)
int fld, idx, idx_p;
eval_notify_windowport_field(fld, valsetlist, idx)
int fld, idx;
boolean *valsetlist;
{
static int oldrndencode = 0;
@@ -710,7 +762,7 @@ boolean *valsetlist;
*/
anytype = blstats[idx][fld].anytype;
curr = &blstats[idx][fld];
prev = &blstats[idx_p][fld];
prev = &blstats[1 - idx][fld];
color = NO_COLOR;
chg = update_all ? 0 : compare_blstats(prev, curr);
@@ -743,7 +795,7 @@ boolean *valsetlist;
reset = FALSE;
#ifdef STATUS_HILITES
if (!update_all && !chg) {
if (!update_all && !chg && curr->time) {
reset = hilite_reset_needed(prev, bl_hilite_moves);
if (reset)
curr->time = prev->time = 0L;
@@ -759,9 +811,11 @@ boolean *valsetlist;
if (anytype != ANY_MASK32) {
#ifdef STATUS_HILITES
if ((chg || *curr->val)) {
get_hilite_color(idx, fld, (genericptr_t) &curr->a,
chg, pc, &color);
if (chg || *curr->val) {
curr->hilite_rule = get_hilite(idx, fld,
(genericptr_t) &curr->a,
chg, pc, &color);
prev->hilite_rule = curr->hilite_rule;
if (chg == 2) {
color = NO_COLOR;
chg = 0;
@@ -769,11 +823,11 @@ boolean *valsetlist;
}
#endif /* STATUS_HILITES */
status_update(fld, (genericptr_t) curr->val,
chg, pc, color, &cond_hilites[0]);
chg, pc, color, (unsigned long *) 0);
} else {
/* Color for conditions is done through cond_hilites[] */
status_update(fld, (genericptr_t) &curr->a.a_ulong, chg, pc,
color, &cond_hilites[0]);
status_update(fld, (genericptr_t) &curr->a.a_ulong,
chg, pc, color, cond_hilites);
}
curr->chg = prev->chg = TRUE;
updated = TRUE;
@@ -782,8 +836,8 @@ boolean *valsetlist;
}
static void
evaluate_and_notify_windowport(valsetlist, idx, idx_p)
int idx, idx_p;
evaluate_and_notify_windowport(valsetlist, idx)
int idx;
boolean *valsetlist;
{
int i, updated = 0, notpresent = 0;
@@ -800,7 +854,7 @@ boolean *valsetlist;
notpresent++;
continue;
}
if (evaluate_and_notify_windowport_field(i, valsetlist, idx, idx_p))
if (eval_notify_windowport_field(i, valsetlist, idx))
updated++;
}
/*
@@ -828,13 +882,13 @@ boolean *valsetlist;
*/
if (context.botlx && (windowprocs.wincap2 & WC2_RESET_STATUS) != 0L)
status_update(BL_RESET, (genericptr_t) 0, 0, 0,
NO_COLOR, &cond_hilites[0]);
NO_COLOR, (unsigned long *) 0);
else if ((updated || context.botlx) &&
(windowprocs.wincap2 & WC2_FLUSH_STATUS) != 0L)
status_update(BL_FLUSH, (genericptr_t) 0, 0, 0,
NO_COLOR, &cond_hilites[0]);
NO_COLOR, (unsigned long *) 0);
context.botl = context.botlx = 0;
context.botl = context.botlx = iflags.time_botl = FALSE;
update_all = FALSE;
}
@@ -842,11 +896,12 @@ void
status_eval_next_unhilite()
{
int i;
struct istat_s *curr = NULL;
struct istat_s *curr;
long next_unhilite, this_unhilite;
bl_hilite_moves = moves;
/* figure out when the next unhilight needs to be performed */
bl_hilite_moves = moves; /* simpllfied; used to try to encode fractional
* amounts for multiple moves within same turn */
/* figure out whether an unhilight needs to be performed now */
next_unhilite = 0L;
for (i = 0; i < MAXBLSTATS; ++i) {
curr = &blstats[0][i]; /* blstats[0][*].time == blstats[1][*].time */
@@ -855,10 +910,17 @@ status_eval_next_unhilite()
struct istat_s *prev = &blstats[1][i];
#ifdef STATUS_HILITES
curr->time = prev->time = (bl_hilite_moves + iflags.hilite_delta);
if (Is_Temp_Hilite(curr->hilite_rule))
curr->time = prev->time = (bl_hilite_moves
+ iflags.hilite_delta);
else
curr->time = prev->time = 0L;
#endif
curr->chg = prev->chg = FALSE;
context.botl = TRUE;
}
if (context.botl)
continue; /* just process other blstats[][].time and .chg */
this_unhilite = curr->time;
if (this_unhilite > 0L
@@ -866,21 +928,22 @@ status_eval_next_unhilite()
#ifdef STATUS_HILITES
&& hilite_reset_needed(curr, this_unhilite + 1L)
#endif
)
) {
next_unhilite = this_unhilite;
if (next_unhilite < bl_hilite_moves)
context.botl = TRUE;
}
}
if (next_unhilite > 0L && next_unhilite < bl_hilite_moves)
context.botl = TRUE;
}
void
status_initialize(reassessment)
boolean
reassessment; /* TRUE = just reassess fields w/o other initialization*/
boolean reassessment; /* TRUE: just recheck fields w/o other initialization */
{
enum statusfields fld;
boolean fldenabl;
int i;
const char *fieldfmt = (const char *) 0;
const char *fieldname = (const char *) 0;
const char *fieldfmt, *fieldname;
if (!reassessment) {
if (blinit)
@@ -888,22 +951,22 @@ boolean
init_blstats();
(*windowprocs.win_status_init)();
blinit = TRUE;
} else if (!blinit) {
panic("status 'reassess' before init");
}
for (i = 0; i < MAXBLSTATS; ++i) {
enum statusfields fld = initblstats[i].fld;
boolean fldenabled = (fld == BL_SCORE) ? flags.showscore
: (fld == BL_XP) ? (boolean) !Upolyd
: (fld == BL_HD) ? (boolean) Upolyd
: (fld == BL_TIME) ? flags.time
: (fld == BL_EXP) ? (boolean) (flags.showexp && !Upolyd)
: TRUE;
fld = initblstats[i].fld;
fldenabl = (fld == BL_SCORE) ? flags.showscore
: (fld == BL_TIME) ? flags.time
: (fld == BL_EXP) ? (boolean) (flags.showexp && !Upolyd)
: (fld == BL_XP) ? (boolean) !Upolyd
: (fld == BL_HD) ? (boolean) Upolyd
: TRUE;
fieldname = initblstats[i].fldname;
if (fld == BL_TITLE && iflags.wc2_hitpointbar)
fieldfmt = "%-30s";
else
fieldfmt = initblstats[i].fldfmt;
status_enablefield(fld, fieldname, fieldfmt, fldenabled);
fieldfmt = (fld == BL_TITLE && iflags.wc2_hitpointbar) ? "%-30.30s"
: initblstats[i].fldfmt;
status_enablefield(fld, fieldname, fieldfmt, fldenabl);
}
update_all = TRUE;
}
@@ -924,14 +987,17 @@ status_finish()
if (blstats[1][i].val)
free((genericptr_t) blstats[1][i].val), blstats[1][i].val = 0;
#ifdef STATUS_HILITES
/* pointer to an entry in thresholds list; Null it out since
that list is about to go away */
blstats[0][i].hilite_rule = blstats[1][i].hilite_rule = 0;
if (blstats[0][i].thresholds) {
struct hilite_s *temp, *next = 0;
struct hilite_s *temp, *next;
for (temp = blstats[0][i].thresholds; temp; temp = next) {
next = temp->next;
free((genericptr_t) temp);
blstats[0][i].thresholds = blstats[1][i].thresholds = 0;
}
blstats[0][i].thresholds = blstats[1][i].thresholds = 0;
}
#endif /* STATUS_HILITES */
}
@@ -947,9 +1013,7 @@ init_blstats()
impossible("init_blstats called more than once.");
return;
}
initalready = TRUE;
for (i = BEFORE; i <= NOW; ++i) {
for (i = 0; i <= 1; ++i) {
for (j = 0; j < MAXBLSTATS; ++j) {
#ifdef STATUS_HILITES
struct hilite_s *keep_hilite_chain = blstats[i][j].thresholds;
@@ -967,6 +1031,7 @@ init_blstats()
#endif
}
}
initalready = TRUE;
}
/*
@@ -1317,26 +1382,19 @@ hilite_reset_needed(bl_p, augmented_time)
struct istat_s *bl_p;
long augmented_time;
{
struct hilite_s *tl = bl_p->thresholds;
/*
* This 'multi' handling may need some tuning...
*/
if (multi)
return FALSE;
if (!Is_Temp_Hilite(bl_p->hilite_rule))
return FALSE;
if (bl_p->time == 0 || bl_p->time >= augmented_time)
return FALSE;
while (tl) {
/* only this style times out (includes general 'changed'
as well as specific 'up' and 'down') */
if (tl->behavior == BL_TH_UPDOWN)
return TRUE;
tl = tl->next;
}
return FALSE;
return TRUE;
}
/* called by options handling when 'statushilites' boolean is toggled */
@@ -1367,33 +1425,13 @@ const char *hl_text;
return FALSE;
}
STATIC_OVL void
merge_bestcolor(bestcolor, newcolor)
int *bestcolor;
int newcolor;
{
int natr = HL_UNDEF, nclr = NO_COLOR;
split_clridx(newcolor, &nclr, &natr);
if (nclr != NO_COLOR)
*bestcolor = (*bestcolor & 0xff00) | nclr;
if (natr != HL_UNDEF) {
if (natr == HL_NONE)
*bestcolor = *bestcolor & 0x00ff; /* reset all attributes */
else
*bestcolor |= (natr << 8); /* merge attributes */
}
}
/*
* get_hilite_color
* get_hilite
*
* Figures out, based on the value and the direction it is moving,
* the color that the field should be displayed in.
* Returns, based on the value and the direction it is moving,
* the highlight rule that applies to the specified field.
*
* Provide get_hilite_color() with the following to work with:
* Provide get_hilite() with the following to work with:
* actual value vp
* useful for BL_TH_VAL_ABSOLUTE
* indicator of down, up, or the same (-1, 1, 0) chg
@@ -1402,28 +1440,22 @@ int newcolor;
* useful for BL_TH_VAL_PERCENTAGE
*
* Get back:
* color based on user thresholds set in config file.
* The rightmost 8 bits contain a color index.
* The 8 bits to the left of that contain
* the attribute bits.
* color = 0x00FF
* attrib= 0xFF00
* pointer to rule that applies; Null if no rule does.
*/
STATIC_OVL void
get_hilite_color(idx, fldidx, vp, chg, pc, colorptr)
STATIC_OVL struct hilite_s *
get_hilite(idx, fldidx, vp, chg, pc, colorptr)
int idx, fldidx, chg, pc;
genericptr_t vp;
int *colorptr;
{
int bestcolor = NO_COLOR;
struct hilite_s *hl;
struct hilite_s *hl, *rule = 0;
anything *value = (anything *) vp;
char *txtstr;
if (!colorptr || fldidx < 0 || fldidx >= MAXBLSTATS)
return;
if (fldidx < 0 || fldidx >= MAXBLSTATS)
return (struct hilite_s *) 0;
if (blstats[idx][fldidx].thresholds) {
if (has_hilite(fldidx)) {
int dt;
/* there are hilites set here */
int max_pc = -1, min_pc = 101;
@@ -1437,7 +1469,7 @@ int *colorptr;
perc_or_abs = FALSE;
/* min_/max_ are used to track best fit */
for (hl = blstats[idx][fldidx].thresholds; hl; hl = hl->next) {
for (hl = blstats[0][fldidx].thresholds; hl; hl = hl->next) {
dt = initblstats[fldidx].anytype; /* only needed for 'absolute' */
/* if we've already matched a temporary highlight, it takes
precedence over all persistent ones; we still process
@@ -1452,7 +1484,7 @@ int *colorptr;
switch (hl->behavior) {
case BL_TH_VAL_PERCENTAGE: /* percent values are always ANY_INT */
if (hl->rel == EQ_VALUE && pc == hl->value.a_int) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_pc = max_pc = hl->value.a_int;
exactmatch = perc_or_abs = TRUE;
} else if (exactmatch) {
@@ -1460,25 +1492,25 @@ int *colorptr;
} else if (hl->rel == LT_VALUE
&& (pc < hl->value.a_int)
&& (hl->value.a_int <= min_pc)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_pc = hl->value.a_int;
perc_or_abs = TRUE;
} else if (hl->rel == LE_VALUE
&& (pc <= hl->value.a_int)
&& (hl->value.a_int <= min_pc)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_pc = hl->value.a_int;
perc_or_abs = TRUE;
} else if (hl->rel == GT_VALUE
&& (pc > hl->value.a_int)
&& (hl->value.a_int >= max_pc)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
max_pc = hl->value.a_int;
perc_or_abs = TRUE;
} else if (hl->rel == GE_VALUE
&& (pc >= hl->value.a_int)
&& (hl->value.a_int >= max_pc)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
max_pc = hl->value.a_int;
perc_or_abs = TRUE;
}
@@ -1487,13 +1519,13 @@ int *colorptr;
/* specific 'up' or 'down' takes precedence over general
'changed' regardless of their order in the rule set */
if (chg < 0 && hl->rel == LT_VALUE) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
updown = TRUE;
} else if (chg > 0 && hl->rel == GT_VALUE) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
updown = TRUE;
} else if (chg != 0 && hl->rel == EQ_VALUE && !updown) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
changed = TRUE;
}
break;
@@ -1506,7 +1538,7 @@ int *colorptr;
if (dt == ANY_INT) {
if (hl->rel == EQ_VALUE
&& hl->value.a_int == value->a_int) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_ival = max_ival = hl->value.a_int;
exactmatch = perc_or_abs = TRUE;
} else if (exactmatch) {
@@ -1514,32 +1546,32 @@ int *colorptr;
} else if (hl->rel == LT_VALUE
&& (value->a_int < hl->value.a_int)
&& (hl->value.a_int <= min_ival)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_ival = hl->value.a_int;
perc_or_abs = TRUE;
} else if (hl->rel == LE_VALUE
&& (value->a_int <= hl->value.a_int)
&& (hl->value.a_int <= min_ival)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_ival = hl->value.a_int;
perc_or_abs = TRUE;
} else if (hl->rel == GT_VALUE
&& (value->a_int > hl->value.a_int)
&& (hl->value.a_int >= max_ival)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
max_ival = hl->value.a_int;
perc_or_abs = TRUE;
} else if (hl->rel == GE_VALUE
&& (value->a_int >= hl->value.a_int)
&& (hl->value.a_int >= max_ival)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
max_ival = hl->value.a_int;
perc_or_abs = TRUE;
}
} else { /* ANY_LONG */
if (hl->rel == EQ_VALUE
&& hl->value.a_long == value->a_long) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_lval = max_lval = hl->value.a_long;
exactmatch = perc_or_abs = TRUE;
} else if (exactmatch) {
@@ -1547,25 +1579,25 @@ int *colorptr;
} else if (hl->rel == LT_VALUE
&& (value->a_long < hl->value.a_long)
&& (hl->value.a_long <= min_lval)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_lval = hl->value.a_long;
perc_or_abs = TRUE;
} else if (hl->rel == LE_VALUE
&& (value->a_long <= hl->value.a_long)
&& (hl->value.a_long <= min_lval)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
min_lval = hl->value.a_long;
perc_or_abs = TRUE;
} else if (hl->rel == GT_VALUE
&& (value->a_long > hl->value.a_long)
&& (hl->value.a_long >= max_lval)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
max_lval = hl->value.a_long;
perc_or_abs = TRUE;
} else if (hl->rel == GE_VALUE
&& (value->a_long >= hl->value.a_long)
&& (hl->value.a_long >= max_lval)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
max_lval = hl->value.a_long;
perc_or_abs = TRUE;
}
@@ -1578,18 +1610,18 @@ int *colorptr;
txtstr += (strlen(plname) + sizeof " the " - sizeof "");
if (hl->rel == TXT_VALUE && hl->textmatch[0]) {
if (fuzzymatch(hl->textmatch, txtstr, "\" -_", TRUE)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
exactmatch = TRUE;
} else if (exactmatch) {
; /* already found best fit, skip "noneoftheabove" */
} else if (fldidx == BL_TITLE
&& Upolyd && noneoftheabove(hl->textmatch)) {
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
}
}
break;
case BL_TH_ALWAYS_HILITE:
merge_bestcolor(&bestcolor, hl->coloridx);
rule = hl;
break;
case BL_TH_NONE:
break;
@@ -1598,8 +1630,8 @@ int *colorptr;
}
}
}
*colorptr = bestcolor;
return;
*colorptr = rule ? rule->coloridx : NO_COLOR;
return rule;
}
STATIC_OVL void
@@ -2109,9 +2141,9 @@ boolean from_configfile;
hilite.anytype = dt;
if (hilite.behavior == BL_TH_TEXTMATCH && txt
&& strlen(txt) < QBUFSZ - 1) {
Strcpy(hilite.textmatch, txt);
if (hilite.behavior == BL_TH_TEXTMATCH && txt) {
(void) strncpy(hilite.textmatch, txt, sizeof hilite.textmatch);
hilite.textmatch[sizeof hilite.textmatch - 1] = '\0';
(void) trimspaces(hilite.textmatch);
}
@@ -2297,6 +2329,15 @@ int sidx;
/*3.6.1:
OPTION=hilite_status: condition/stone+slime+foodPois/red&inverse */
/*
* TODO?
* It would be simpler to treat each condition (also hunger state
* and encumbrance level) as if it were a separate field. That
* way they could have either or both 'changed' temporary rule and
* 'always' persistent rule and wouldn't need convoluted access to
* the intended color and attributes.
*/
sidx++;
while(s[sidx]) {
int sf = 0; /* subfield count */
@@ -2400,17 +2441,15 @@ clear_status_hilites()
int i;
for (i = 0; i < MAXBLSTATS; ++i) {
if (blstats[0][i].thresholds) {
struct hilite_s *temp = blstats[0][i].thresholds,
*next = (struct hilite_s *)0;
while (temp) {
next = temp->next;
free(temp);
blstats[0][i].thresholds = (struct hilite_s *)0;
blstats[1][i].thresholds = blstats[0][i].thresholds;
temp = next;
}
struct hilite_s *temp, *next;
for (temp = blstats[0][i].thresholds; temp; temp = next) {
next = temp->next;
free(temp);
}
blstats[0][i].thresholds = blstats[1][i].thresholds = 0;
/* pointer into thresholds list, now stale */
blstats[0][i].hilite_rule = blstats[1][i].hilite_rule = 0;
}
}
@@ -3190,7 +3229,7 @@ choose_value:
Strcpy(hilite.textmatch, hutxt[rv]);
} else if (fld == BL_TITLE) {
const char *rolelist[3 * 9 + 1];
char mbuf[QBUFSZ], fbuf[QBUFSZ], obuf[QBUFSZ];
char mbuf[MAXVALWIDTH], fbuf[MAXVALWIDTH], obuf[MAXVALWIDTH];
int i, j, rv;
for (i = j = 0; i < 9; i++) {
@@ -3237,7 +3276,7 @@ choose_value:
goto choose_behavior;
hilite.rel = TXT_VALUE;
if (strlen(inbuf) < QBUFSZ - 1)
if (strlen(inbuf) < sizeof hilite.textmatch)
Strcpy(hilite.textmatch, inbuf);
else
return FALSE;
@@ -3347,25 +3386,25 @@ int id;
return TRUE;
} else {
int fld = hlstr->fld;
struct hilite_s *hl = blstats[0][fld].thresholds;
struct hilite_s *hlprev = (struct hilite_s *) 0;
struct hilite_s *hl, *hlprev = (struct hilite_s *) 0;
if (hl) {
while (hl) {
if (hlstr->hl == hl) {
if (hlprev) {
hlprev->next = hl->next;
} else {
blstats[0][fld].thresholds = hl->next;
blstats[1][fld].thresholds =
blstats[0][fld].thresholds;
}
free((genericptr_t) hl);
return TRUE;
for (hl = blstats[0][fld].thresholds; hl; hl = hl->next) {
if (hlstr->hl == hl) {
if (hlprev) {
hlprev->next = hl->next;
} else {
blstats[0][fld].thresholds = hl->next;
blstats[1][fld].thresholds = blstats[0][fld].thresholds;
}
hlprev = hl;
hl = hl->next;
if (blstats[0][fld].hilite_rule == hl) {
blstats[0][fld].hilite_rule
= blstats[1][fld].hilite_rule = (struct hilite_s *) 0;
blstats[0][fld].time = blstats[1][fld].time = 0L;
}
free((genericptr_t) hl);
return TRUE;
}
hlprev = hl;
}
}
return FALSE;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 display.c $NHDT-Date: 1551138503 2019/02/25 23:48:23 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.97 $ */
/* NetHack 3.6 display.c $NHDT-Date: 1554045810 2019/03/31 15:23:30 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.99 $ */
/* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */
/* and Dave Cohrs, 1990. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1213,8 +1213,7 @@ int mode;
}
}
/* =========================================================================
*/
/* ======================================================================== */
/*
* Loop through all of the monsters and update them. Called when:
@@ -1380,10 +1379,39 @@ docrt()
context.botlx = 1; /* force a redraw of the bottom line */
}
/* =========================================================================
*/
/* Glyph Buffering (3rd screen) ============================================
*/
/* for panning beyond a clipped region; resend the current map data to
the interface rather than use docrt()'s regeneration of that data */
void
redraw_map()
{
int x, y, glyph;
/*
* Not sure whether this is actually necessary; save and restore did
* used to get much too involved with each dungeon level as it was
* read and written.
*
* !u.ux: display isn't ready yet; (restoring || !on_level()): was part
* of cliparound() but interface shouldn't access this much internals
*/
if (!u.ux || restoring || !on_level(&u.uz0, &u.uz))
return;
/*
* This yields sensible clipping when #terrain+getpos is in
* progress and the screen displays something other than what
* the map would currently be showing.
*/
for (y = 0; y < ROWNO; ++y)
for (x = 1; x < COLNO; ++x) {
glyph = glyph_at(x, y); /* not levl[x][y].glyph */
print_glyph(WIN_MAP, x, y, glyph, get_bk_glyph(x, y));
}
flush_screen(1);
}
/* ======================================================================== */
/* Glyph Buffering (3rd screen) =========================================== */
typedef struct {
xchar new; /* perhaps move this bit into the rm structure. */
@@ -1536,7 +1564,7 @@ int start, stop, y;
for (x = start; x <= stop; x++)
if (gbuf[y][x].glyph != cmap_to_glyph(S_stone))
print_glyph(WIN_MAP, x, y, gbuf[y][x].glyph, get_bk_glyph(x,y));
print_glyph(WIN_MAP, x, y, gbuf[y][x].glyph, get_bk_glyph(x, y));
}
void
@@ -1597,10 +1625,11 @@ int cursor_on_u;
flushing = 0;
if (context.botl || context.botlx)
bot();
else if (iflags.time_botl)
timebot();
}
/* =========================================================================
*/
/* ======================================================================== */
/*
* back_to_glyph()
@@ -1804,16 +1833,19 @@ xchar x, y;
/*
* This will be used to get the glyph for the background so that
* it can potentially be merged into graphical window ports
* to improve the appearance of stuff on dark room
* squares and the plane of air etc.
* it can potentially be merged into graphical window ports to
* improve the appearance of stuff on dark room squares and the
* plane of air etc.
*
* Until that is working correctly in the branch, however, for now
* we just return NO_GLYPH as an indicator to ignore it.
*
* [This should be using background as recorded for #overview rather
* than current data from the map.]
*/
STATIC_OVL int
get_bk_glyph(x,y)
get_bk_glyph(x, y)
xchar x, y;
{
int idx, bkglyph = NO_GLYPH;

View File

@@ -51,9 +51,9 @@ boolean FDECL((*gp_getvalidf), (int, int));
}
static const char *const gloc_descr[NUM_GLOCS][4] = {
{ "any monsters", "monster", "next monster", "monsters" },
{ "any items", "item", "next object", "objects" },
{ "any doors", "door", "next door or doorway", "doors or doorways" },
{ "any monsters", "monster", "next/previous monster", "monsters" },
{ "any items", "item", "next/previous object", "objects" },
{ "any doors", "door", "next/previous door or doorway", "doors or doorways" },
{ "any unexplored areas", "unexplored area", "unexplored location",
"unexplored locations" },
{ "anything interesting", "interesting thing", "anything interesting",
@@ -77,7 +77,7 @@ int gloc;
{
char sbuf[BUFSZ];
Sprintf(sbuf, "Use '%s' or '%s' to %s%s%s.",
Sprintf(sbuf, "Use '%s'/'%s' to %s%s%s.",
k1, k2,
iflags.getloc_usemenu ? "get a menu of "
: "move the cursor to ",

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 end.c $NHDT-Date: 1553652951 2019/03/27 02:15:51 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.166 $ */
/* NetHack 3.6 end.c $NHDT-Date: 1554045810 2019/03/31 15:23:30 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.167 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2012. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1048,7 +1048,7 @@ int how;
#endif
) {
/* skip status update if panicking or disconnected */
context.botl = context.botlx = FALSE;
context.botl = context.botlx = iflags.time_botl = FALSE;
} else {
/* otherwise force full status update */
context.botlx = TRUE;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 options.c $NHDT-Date: 1553480404 2019/03/25 02:20:04 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.360 $ */
/* NetHack 3.6 options.c $NHDT-Date: 1554155747 2019/04/01 21:55:47 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.362 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Michael Allison, 2008. */
/* NetHack may be freely redistributed. See license for details. */
@@ -114,7 +114,7 @@ static struct Bool_Opt {
{ "confirm", &flags.confirm, TRUE, SET_IN_GAME },
{ "dark_room", &flags.dark_room, TRUE, SET_IN_GAME },
{ "eight_bit_tty", &iflags.wc_eight_bit_input, FALSE, SET_IN_GAME }, /*WC*/
#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS)
#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) || defined(X11_GRAPHICS)
{ "extmenu", &iflags.extmenu, FALSE, SET_IN_GAME },
#else
{ "extmenu", (boolean *) 0, FALSE, SET_IN_FILE },
@@ -385,20 +385,23 @@ static struct Comp_Opt {
#ifdef MSDOS
{ "soundcard", "type of sound card to use", 20, SET_IN_FILE },
#endif
#ifdef STATUS_HILITES
{ "statushilites",
#ifdef STATUS_HILITES
"0=no status highlighting, N=show highlights for N turns",
20, SET_IN_GAME },
20, SET_IN_GAME
#else
{ "statushilites", "highlight control", 20, SET_IN_FILE },
"highlight control", 20, SET_IN_FILE
#endif
#ifdef CURSES_GRAPHICS
},
{ "statuslines",
#ifdef CURSES_GRAPHICS
"2 or 3 lines for horizonal (bottom or top) status display",
20, SET_IN_GAME }, /*WC2*/
20, SET_IN_GAME
#else
{ "statuslines", "2 or 3 lines for status display", 20, SET_IN_FILE },
"2 or 3 lines for status display",
20, SET_IN_FILE
#endif
}, /*WC2*/
{ "symset", "load a set of display symbols from the symbols file", 70,
SET_IN_GAME },
{ "roguesymset",
@@ -3703,6 +3706,7 @@ boolean tinitial, tfrom_file;
}
return retval;
}
#endif /* CURSES_GRAPHICS */
/* WINCAP2
* statuslines:n */
@@ -3728,7 +3732,6 @@ boolean tinitial, tfrom_file;
}
return retval;
}
#endif /* CURSES_GRAPHICS */
/* menustyle:traditional or combination or full or partial */
fullname = "menustyle";
@@ -5739,8 +5742,9 @@ char *buf;
iflags.hilite_delta, iflags.hilite_delta);
#endif
} else if (!strcmp(optname,"statuslines")) {
Strcpy(buf, (WINDOWPORT("curses")
&& iflags.wc2_statuslines < 3) ? "2" : "3");
if (wc2_supported(optname))
Strcpy(buf, (iflags.wc2_statuslines < 3) ? "2" : "3");
/* else default to "unknown" */
} else if (!strcmp(optname, "suppress_alert")) {
if (flags.suppress_alert == 0L)
Strcpy(buf, none);

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1550524566 2019/02/18 21:16:06 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.110 $ */
/* NetHack 3.6 sp_lev.c $NHDT-Date: 1553787633 2019/03/28 15:40:33 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.111 $ */
/* Copyright (c) 1989 by Jean-Christophe Collet */
/* NetHack may be freely redistributed. See license for details. */
@@ -4711,13 +4711,16 @@ struct sp_coder *coder;
{
static const char nhFunc[] = "spo_drawbridge";
xchar x, y;
int dopen;
struct opvar *dir, *db_open, *dcoord;
if (!OV_pop_i(dir) || !OV_pop_i(db_open) || !OV_pop_c(dcoord))
return;
get_location_coord(&x, &y, DRY | WET | HOT, coder->croom, OV_i(dcoord));
if (!create_drawbridge(x, y, OV_i(dir), OV_i(db_open)))
if ((dopen = OV_i(db_open)) == -1)
dopen = !rn2(2);
if (!create_drawbridge(x, y, OV_i(dir), dopen ? TRUE : FALSE))
impossible("Cannot create drawbridge.");
SpLev_Map[x][y] = 1;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 teleport.c $NHDT-Date: 1550524567 2019/02/18 21:16:07 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.85 $ */
/* NetHack 3.6 teleport.c $NHDT-Date: 1553885439 2019/03/29 18:50:39 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.86 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Robert Patrick Rankin, 2011. */
/* NetHack may be freely redistributed. See license for details. */
@@ -478,7 +478,7 @@ struct obj *scroll;
Strcpy(whobuf, "you");
if (u.usteed)
Sprintf(eos(whobuf), " and %s", mon_nam(u.usteed));
pline("To what position do %s want to be teleported?", whobuf);
pline("Where do %s want to be teleported?", whobuf);
cc.x = u.ux;
cc.y = u.uy;
if (getpos(&cc, TRUE, "the desired position") < 0)

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 winfuncs.c $NHDT-Date: 1433806596 2015/06/08 23:36:36 $ $NHDT-Branch: master $:$NHDT-Revision: 1.15 $ */
/* NetHack 3.6 winfuncs.c $NHDT-Date: 1553895320 2019/03/29 21:35:20 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.16 $ */
/* Copyright (c) Gregg Wonderly, Naperville, Illinois, 1991,1992,1993,1996.
*/
/* NetHack may be freely redistributed. See license for details. */
@@ -2131,13 +2131,13 @@ void
amii_cliparound(x, y)
register int x, y;
{
extern boolean restoring;
#ifdef CLIPPING
int oldx = clipx, oldy = clipy;
int oldxmax = clipxmax, oldymax = clipymax;
int COx, LIx;
#define SCROLLCNT 1 /* Get there in 3 moves... */
int scrollcnt = SCROLLCNT; /* ...or 1 if we changed level */
if (!clipping) /* And 1 in anycase, cleaner, simpler, quicker */
return;
@@ -2306,8 +2306,7 @@ register int x, y;
clipymax += incy;
/* Draw the exposed portion */
if (on_level(&u.uz0, &u.uz) && !restoring)
(void) doredraw();
redraw_map();
flush_glyph_buffer(amii_wins[WIN_MAP]->win);
}
}
@@ -2317,8 +2316,7 @@ register int x, y;
clipymax = saveymax;
clipxmax = savexmax;
#endif
if (on_level(&u.uz0, &u.uz) && !restoring && moves > 1)
(void) doredraw();
redraw_map();
flush_glyph_buffer(amii_wins[WIN_MAP]->win);
}
reclip = 0;

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 winmisc.c $NHDT-Date: 1543830350 2018/12/03 09:45:50 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.42 $ */
/* NetHack 3.6 winmisc.c $NHDT-Date: 1554135506 2019/04/01 16:18:26 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.44 $ */
/* Copyright (c) Dean Luick, 1992 */
/* NetHack may be freely redistributed. See license for details. */
@@ -41,6 +41,8 @@
static Widget extended_command_popup = 0;
static Widget extended_command_form;
static Widget *extended_commands = 0;
static const char **command_list;
static short *command_indx;
static int extended_cmd_selected; /* index of the selected command; */
static int ps_selected; /* index of selected role */
#define PS_RANDOM (-50)
@@ -50,6 +52,7 @@ static const char ps_randchars[] = "*@\n\rrR";
static const char ps_quitchars[] = "\033qQ";
#define EC_NCHARS 32
static boolean ec_full_list = FALSE;
static boolean ec_active = FALSE;
static int ec_nchars = 0;
static char ec_chars[EC_NCHARS];
@@ -111,13 +114,14 @@ XtPointer
i2xtp(i)
int i;
{
return (XtPointer)(long)i;
return (XtPointer) (ptrdiff_t) i;
}
int
xtp2i(x)
XtPointer x;
{
return (long)x;
return (int) (ptrdiff_t) x;
}
/* Player Selection ------------------------------------------------------- */
@@ -1581,9 +1585,16 @@ X11_player_selection()
}
}
/* called by core to have the player pick an extended command */
int
X11_get_ext_cmd()
{
if (iflags.extmenu != ec_full_list) {
/* player has toggled the 'extmenu' option, toss the old widgets */
if (extended_commands)
release_extended_cmds(); /* will set extended_commands to Null */
ec_full_list = iflags.extmenu;
}
if (!extended_commands)
init_extended_commands_popup();
@@ -1597,15 +1608,19 @@ X11_get_ext_cmd()
/* The callbacks will enable the event loop exit. */
(void) x_event(EXIT_ON_EXIT);
return extended_cmd_selected;
if (extended_cmd_selected < 0)
return -1;
return command_indx[extended_cmd_selected];
}
void
release_extended_cmds()
{
if (extended_commands) {
XtDestroyWidget(extended_command_popup);
XtDestroyWidget(extended_command_popup), extended_command_popup = 0;
free((genericptr_t) extended_commands), extended_commands = 0;
free((genericptr_t) command_list), command_list = (const char **) 0;
free((genericptr_t) command_indx), command_indx = (short *) 0;
}
}
@@ -1816,6 +1831,22 @@ int ec_indx; /* might be greater than extended_cmd_selected */
}
}
/* decide whether extcmdlist[idx] should be part of extended commands menu */
static boolean
ignore_extcmd(idx)
int idx;
{
/* #shell or #suspect might not be available;
'extmenu' option controls whether we show full list
or just the traditional extended commands */
if ((extcmdlist[idx].flags & CMD_NOT_AVAILABLE) != 0
|| ((extcmdlist[idx].flags & AUTOCOMPLETE) == 0 && !ec_full_list)
|| strlen(extcmdlist[idx].ef_txt) < 2) /* ignore "#" and "?" */
return TRUE;
return FALSE;
}
/* ARGSUSED */
void
ec_key(w, event, params, num_params)
@@ -1825,11 +1856,12 @@ String *params;
Cardinal *num_params;
{
char ch;
int i;
int pass;
int i, pass;
float shown, top;
Arg arg[2];
Widget hbar, vbar;
XKeyEvent *xkey = (XKeyEvent *) event;
nhUse(w);
nhUse(params);
nhUse(num_params);
@@ -1857,6 +1889,25 @@ Cardinal *num_params;
exit_x_event = TRUE; /* leave event loop */
ec_active = FALSE;
return;
} else if (ch == MENU_FIRST_PAGE || ch == MENU_LAST_PAGE) {
hbar = vbar = (Widget) 0;
find_scrollbars(w, &hbar, &vbar);
if (vbar) {
top = (ch == MENU_FIRST_PAGE) ? 0.0 : 1.0;
XtCallCallbacks(vbar, XtNjumpProc, &top);
}
return;
} else if (ch == MENU_NEXT_PAGE || ch == MENU_PREVIOUS_PAGE) {
hbar = vbar = (Widget) 0;
find_scrollbars(w, &hbar, &vbar);
if (vbar) {
XtSetArg(arg[0], nhStr(XtNshown), &shown);
XtSetArg(arg[1], nhStr(XtNtopOfThumb), &top);
XtGetValues(vbar, arg, TWO);
top += ((ch == MENU_NEXT_PAGE) ? shown : -shown);
XtCallCallbacks(vbar, XtNjumpProc, &top);
}
return;
}
/*
@@ -1886,19 +1937,14 @@ Cardinal *num_params;
if (extended_cmd_selected >= 0)
swap_fg_bg(extended_commands[extended_cmd_selected]);
extended_cmd_selected = -1; /* dismiss */
ec_chars[0] = ec_chars[ec_nchars-1];
ec_chars[0] = ec_chars[ec_nchars - 1];
ec_nchars = 1;
}
for (i = 0; extcmdlist[i].ef_txt; i++) {
if (extcmdlist[i].flags & CMD_NOT_AVAILABLE)
continue;
if (extcmdlist[i].ef_txt[0] == '?')
continue;
if (!strncmp(ec_chars, extcmdlist[i].ef_txt, ec_nchars)) {
for (i = 0; command_list[i]; ++i) {
if (!strncmp(ec_chars, command_list[i], ec_nchars)) {
if (extended_cmd_selected != i) {
/* I should use set() and unset() actions, but how do */
/* I send the an action to the widget? */
/* I should use set() and unset() actions, but how do
I send the an action to the widget? */
if (extended_cmd_selected >= 0)
swap_fg_bg(extended_commands[extended_cmd_selected]);
extended_cmd_selected = i;
@@ -1908,11 +1954,10 @@ Cardinal *num_params;
ambiguous choices, plus one to show thare aren't any
more such, will scroll into view */
do {
if (!extcmdlist[i + 1].ef_txt
|| *extcmdlist[i + 1].ef_txt == '?')
if (!command_list[i + 1])
break; /* end of list */
++i;
} while (!strncmp(ec_chars, extcmdlist[i].ef_txt, ec_nchars));
} while (!strncmp(ec_chars, command_list[i], ec_nchars));
ec_scroll_to_view(i);
return;
@@ -1929,25 +1974,24 @@ static void
init_extended_commands_popup()
{
int i, j, num_commands, ignore_cmds = 0;
const char **command_list;
/* count commands */
for (num_commands = 0; extcmdlist[num_commands].ef_txt; num_commands++)
if (extcmdlist[num_commands].flags & CMD_NOT_AVAILABLE)
if (ignore_extcmd(num_commands))
++ignore_cmds;
/* If the last entry is "help", don't use it. */
if (strcmp(extcmdlist[num_commands - 1].ef_txt, "?") == 0)
--num_commands;
j = num_commands - ignore_cmds;
command_list = (const char **) alloc((unsigned) j * sizeof (char *));
command_list = (const char **) alloc((unsigned) (j * sizeof (char *) + 1));
command_indx = (short *) alloc((unsigned) (j * sizeof (short) + 1));
for (i = j = 0; i < num_commands; i++) {
if (extcmdlist[i].flags & CMD_NOT_AVAILABLE)
if (ignore_extcmd(i))
continue;
command_indx[j] = (short) i;
command_list[j++] = extcmdlist[i].ef_txt;
}
command_list[j] = (char *) 0;
command_indx[j] = -1;
num_commands = j;
extended_command_popup =
@@ -1955,8 +1999,6 @@ init_extended_commands_popup()
extended_command_translations, "dismiss", extend_dismiss,
"help", extend_help, num_commands, command_list,
&extended_commands, extend_select, &extended_command_form);
free((char *) command_list);
}
/* ------------------------------------------------------------------------ */

View File

@@ -17,6 +17,8 @@
#define strncasecmp strncmpi
#endif
extern long curs_mesg_suppress_turn; /* from cursmesg.c */
/*
* Note:
*
@@ -120,6 +122,10 @@ curses_line_input_dialog(const char *prompt, char *answer, int buffer)
int height = prompt_height;
char input[BUFSZ];
/* if messages were being suppressed for the remainder of the turn,
re-activate them now that input is being requested */
curs_mesg_suppress_turn = -1;
if (buffer >= (int) sizeof input)
buffer = (int) sizeof input - 1;
maxwidth = term_cols - 2;
@@ -201,6 +207,10 @@ curses_character_input_dialog(const char *prompt, const char *choices,
boolean any_choice = FALSE;
boolean accept_count = FALSE;
/* if messages were being suppressed for the remainder of the turn,
re-activate them now that input is being requested */
curs_mesg_suppress_turn = -1;
if (invent || (moves > 1)) {
curses_get_window_size(MAP_WIN, &map_height, &map_width);
} else {

View File

@@ -9,6 +9,8 @@
#include "color.h"
#include "wincurs.h"
extern long curs_mesg_suppress_turn; /* from cursmesg.c */
/* Public functions for curses NetHack interface */
/* Interface definition, for windows.c */
@@ -72,8 +74,8 @@ struct window_procs curses_procs = {
curses_end_screen,
genl_outrip,
curses_preference_update,
genl_getmsghistory,
genl_putmsghistory,
curses_getmsghistory,
curses_putmsghistory,
curses_status_init,
curses_status_finish,
genl_status_enablefield,
@@ -687,6 +689,9 @@ curses_nhgetch()
{
int ch;
/* if messages are being suppressed, reenable them */
curs_mesg_suppress_turn = -1;
curses_prehousekeeping();
ch = curses_read_char();
curses_posthousekeeping();

View File

@@ -9,6 +9,10 @@
#include "cursmesg.h"
#include <ctype.h>
/* player can type ESC at More>> prompt to avoid seeing more messages
for the current move; but hero might get more than one move per turn,
so the input routines need to be able to cancel this */
long curs_mesg_suppress_turn = -1; /* also used in cursdial.c && cursmain.c */
/* Message window routines for curses interface */
@@ -46,16 +50,13 @@ curses_message_win_puts(const char *message, boolean recursed)
boolean border = curses_window_has_border(MESSAGE_WIN);
int message_length = strlen(message);
int border_space = 0;
static long suppress_turn = -1;
#if 1
#if 0
/*
* Handled by core's use of putstr(WIN_MESSAGE,ATR_NOHISTORY,message)
* for intermediate counts, but get_count() also uses putmsghistory()
* for the final count, to remember that without showing it. But
* curses is using genl_putmsghistory() which just delivers the text
* via a normal pline(). This hides that at cost of not having it
* in ^P recall and being out of sync with DUMPLOG's message history.
* This was useful when curses used genl_putmsghistory() but is not
* needed now that it has its own curses_putmsghistory() that's
* capable of putting something into the ^P recall history without
* displaying it at the same time.
*/
if (strncmp("Count:", message, 6) == 0) {
curses_count_window(message);
@@ -63,8 +64,8 @@ curses_message_win_puts(const char *message, boolean recursed)
}
#endif
if (suppress_turn == moves) {
return;
if (curs_mesg_suppress_turn == moves) {
return; /* user has typed ESC to avoid seeing remaining messages. */
}
curses_get_window_size(MESSAGE_WIN, &height, &width);
@@ -105,7 +106,7 @@ curses_message_win_puts(const char *message, boolean recursed)
/* Pause until key is hit - Esc suppresses any further
messages that turn */
if (curses_more() == '\033') {
suppress_turn = moves;
curs_mesg_suppress_turn = moves;
return;
}
} else {
@@ -156,6 +157,9 @@ curses_block(boolean noscroll) /* noscroll - blocking because of msgtype
WINDOW *win = curses_get_nhwin(MESSAGE_WIN);
const char *resp = " \r\n\033"; /* space, enter, esc */
/* if messages are being suppressed, reenable them */
curs_mesg_suppress_turn = -1;
curses_get_window_size(MESSAGE_WIN, &height, &width);
curses_toggle_color_attr(win, MORECOLOR, NONE, ON);
mvwprintw(win, my, mx, ">>");
@@ -693,4 +697,99 @@ get_msg_line(boolean reverse, int mindex)
return current_mesg;
}
/* save/restore code retrieves one ^P message at a time during save and
puts it into save file; if any new messages are added to the list while
that is taking place, the results are likely to be scrambled */
char *
curses_getmsghistory(init)
boolean init;
{
static int nxtidx;
nhprev_mesg *mesg;
if (init)
nxtidx = 0;
else
++nxtidx;
if (nxtidx < num_messages) {
/* we could encode mesg->turn with the text of the message,
but then that text might need to be truncated, and more
significantly, restoring the save file with another
interface wouldn't know how find and decode or remove it;
likewise, restoring another interface's save file with
curses wouldn't find the expected turn info;
so, we live without that */
mesg = get_msg_line(FALSE, nxtidx);
} else
mesg = (nhprev_mesg *) 0;
return mesg ? mesg->str : (char *) 0;
}
/*
* This is called by the core savefile restore routines.
* Each time we are called, we stuff the string into our message
* history recall buffer. The core will send the oldest message
* first (actually it sends them in the order they exist in the
* save file, but that is supposed to be the oldest first).
* These messages get pushed behind any which have been issued
* during this session since they come from a previous session
* and logically precede anything (like "Restoring save file...")
* that's happened now.
*
* Called with a null pointer to finish up restoration.
*
* It's also called by the quest pager code when a block message
* has a one-line summary specified. We put that line directly
* into message history for ^P recall without having displayed it.
*/
void
curses_putmsghistory(msg, restoring_msghist)
const char *msg;
boolean restoring_msghist;
{
static boolean initd = FALSE;
static int stash_count;
static nhprev_mesg *stash_head = 0;
if (restoring_msghist && !initd) {
/* hide any messages we've gathered since starting current session
so that the ^P data will start out empty as we add ones being
restored from save file; we'll put these back after that's done */
stash_count = num_messages, num_messages = 0;
stash_head = first_mesg, first_mesg = (nhprev_mesg *) 0;
last_mesg = (nhprev_mesg *) 0; /* no need to remember the tail */
initd = TRUE;
}
if (msg) {
mesg_add_line(msg);
/* treat all saved and restored messages as turn #1 */
last_mesg->turn = 1L;
} else if (stash_count) {
nhprev_mesg *mesg;
long mesg_turn;
/* put any messages generated during the beginning of the current
session back; they logically follow any from the previous
session's save file */
while (stash_count > 0) {
/* we could manipulate the linked list directly but treating
stashed messages as newly occurring ones is much simpler;
we ignore the backlinks because the list is destroyed as it
gets processed hence there can't be any other traversals */
mesg = stash_head;
stash_head = mesg->next_mesg;
--stash_count;
mesg_turn = mesg->turn;
mesg_add_line(mesg->str);
last_mesg->turn = mesg_turn;
free((genericptr_t) mesg->str);
free((genericptr_t) mesg);
}
initd = FALSE; /* reset */
}
}
/*cursmesg.c*/

View File

@@ -18,5 +18,7 @@ void curses_last_messages(void);
void curses_init_mesg_history(void);
void curses_prev_mesg(void);
void curses_count_window(const char *count_text);
char *curses_getmsghistory(BOOLEAN_P);
void curses_putmsghistory(const char *, BOOLEAN_P);
#endif /* CURSMESG_H */

View File

@@ -25,6 +25,7 @@ extern boolean status_activefields[MAXBLSTATS];
static char *status_vals_long[MAXBLSTATS];
#ifdef STATUS_HILITES
static unsigned long *curses_colormasks;
static long curses_condition_bits;
static int curses_status_colors[MAXBLSTATS];
static int hpbar_percent, hpbar_color;
@@ -36,12 +37,11 @@ static int FDECL(condcolor, (long, unsigned long *));
static int FDECL(condattr, (long, unsigned long *));
static int FDECL(nhattr2curses, (int));
#endif /* STATUS_HILITES */
static void FDECL(draw_status, (unsigned long *));
static void FDECL(draw_vertical, (BOOLEAN_P, unsigned long *));
static void FDECL(draw_horizontal, (BOOLEAN_P, unsigned long *));
static void NDECL(draw_status);
static void FDECL(draw_vertical, (BOOLEAN_P));
static void FDECL(draw_horizontal, (BOOLEAN_P));
static void curs_HPbar(char *, int);
static void curs_stat_conds(int, int *, int *, unsigned long *,
char *, boolean *);
static void curs_stat_conds(int, int *, int *, char *, boolean *);
static void curs_vert_status_vals(int);
/* width of a single line in vertical status orientation (one field per line;
@@ -162,6 +162,7 @@ unsigned long *colormasks;
return;
if (fldidx == BL_CONDITION) {
curses_condition_bits = *condptr;
curses_colormasks = colormasks;
} else {
#ifndef TEXTCOLOR
color_and_attr = (color_and_attr & ~0x00FF) | NO_COLOR;
@@ -204,19 +205,13 @@ unsigned long *colormasks;
}
}
} else { /* BL_FLUSH */
if (!changed_fields && !context.botlx) {
; /* TODO: this isn't impossible but we want to track
* down the circumstances where it happens in order to
* minimize occurrences */
}
draw_status(colormasks);
draw_status();
changed_fields = 0;
}
}
void
draw_status(colormasks)
unsigned long *colormasks;
static void
draw_status()
{
WINDOW *win = curses_get_nhwin(STATUS_WIN);
int orient = curses_get_window_orientation(STATUS_WIN);
@@ -242,9 +237,9 @@ unsigned long *colormasks;
werase(win);
if (horiz)
draw_horizontal(border, colormasks);
draw_horizontal(border);
else
draw_vertical(border, colormasks);
draw_vertical(border);
if (border)
box(win, 0, 0);
@@ -252,10 +247,9 @@ unsigned long *colormasks;
}
/* horizontal layout on 2 or 3 lines */
void
draw_horizontal(border, colormasks)
static void
draw_horizontal(border)
boolean border;
unsigned long *colormasks;
{
#define blPAD BL_FLUSH
/* almost all fields already come with a leading space;
@@ -343,7 +337,7 @@ unsigned long *colormasks;
/* collect active conditions in cbuf[], space separated, suitable
for direct output if no highlighting is requested ('asis') but
primarily used to measure the length */
curs_stat_conds(0, &x, &y, colormasks, cbuf, &asis);
curs_stat_conds(0, &x, &y, cbuf, &asis);
clen = (int) strlen(cbuf);
cap_and_hunger = 0;
@@ -640,8 +634,7 @@ unsigned long *colormasks;
if (asis)
waddstr(win, cbuf);
else /* cond by cond if any cond specifies highlighting */
curs_stat_conds(0, &x, &y, colormasks,
(char *) 0, (boolean *) 0);
curs_stat_conds(0, &x, &y, (char *) 0, (boolean *) 0);
} /* curses_condition_bits */
} /* hitpointbar vs regular field vs conditions */
} /* i (fld) */
@@ -651,10 +644,9 @@ unsigned long *colormasks;
}
/* vertical layout, to left or right of map */
void
draw_vertical(border, colormasks)
static void
draw_vertical(border)
boolean border;
unsigned long *colormasks;
{
/* for blank lines, the digit prefix is the order in which they get
removed if we need to shrink to fit within height limit (very rare) */
@@ -893,8 +885,7 @@ unsigned long *colormasks;
if (cond_count) {
/* output active conditions, three per line;
cursor is already positioned where they should start */
curs_stat_conds(1, &x, &y, colormasks,
(char *) 0, (boolean *) 0);
curs_stat_conds(1, &x, &y, (char *) 0, (boolean *) 0);
}
} /* hitpointbar vs regular field vs conditions */
} /* fld loop */
@@ -971,7 +962,6 @@ extern const struct condmap valid_conditions[]; /* botl.c */
static void
curs_stat_conds(int vert_cond, /* 0 => horizontal, 1 => vertical */
int *x, int *y, /* real for vertical, ignored otherwise */
unsigned long *colormasks, /* input */
char *condbuf, /* optional output; collect string of conds */
boolean *nohilite) /* optional output; indicates whether -*/
{ /*+ condbuf[] could be used as-is */
@@ -994,8 +984,8 @@ curs_stat_conds(int vert_cond, /* 0 => horizontal, 1 => vertical */
Strcpy(condnam, valid_conditions[i].id);
Strcat(strcat(condbuf, " "), upstart(condnam));
if (nohilite && *nohilite
&& (condcolor(bitmsk, colormasks) != NO_COLOR
|| condattr(bitmsk, colormasks) != 0))
&& (condcolor(bitmsk, curses_colormasks) != NO_COLOR
|| condattr(bitmsk, curses_colormasks) != 0))
*nohilite = FALSE;
}
}
@@ -1034,12 +1024,14 @@ curs_stat_conds(int vert_cond, /* 0 => horizontal, 1 => vertical */
if (!do_vert || (vert_cond % 3) != 1)
waddch(win, ' ');
if (iflags.hilite_delta) {
if ((attrmask = condattr(bitmsk, colormasks)) != 0) {
if ((attrmask = condattr(bitmsk, curses_colormasks))
!= 0) {
attrmask = nhattr2curses(attrmask);
wattron(win, attrmask);
}
#ifdef TEXTCOLOR
if ((color = condcolor(bitmsk, colormasks)) != NO_COLOR)
if ((color = condcolor(bitmsk, curses_colormasks))
!= NO_COLOR)
curses_toggle_color_attr(win, color, NONE, ON);
#endif
}

View File

@@ -1,4 +1,4 @@
/* NetHack 3.6 termcap.c $NHDT-Date: 1456907853 2016/03/02 08:37:33 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.24 $ */
/* NetHack 3.6 termcap.c $NHDT-Date: 1553858473 2019/03/29 11:21:13 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.29 $ */
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/*-Copyright (c) Pasi Kallinen, 2018. */
/* NetHack may be freely redistributed. See license for details. */
@@ -1206,12 +1206,37 @@ int n;
return nulstr;
}
/* suppress nonfunctional highlights so render_status() might be able to
optimize more; keep this in sync with s_atr2str() */
int
term_attr_fixup(msk)
int msk;
{
/* underline is converted to bold if its start sequence isn't available */
if ((msk & (1 << ATR_ULINE)) && !nh_US) {
msk |= (1 << ATR_BOLD);
msk &= ~(1 << ATR_ULINE);
}
/* blink is converted to bold unconditionally [why?] */
if (msk & (1 << ATR_BLINK)) {
msk |= (1 << ATR_BOLD);
msk &= ~(1 << ATR_BLINK);
}
/* dim is ignored */
if (msk & (1 << ATR_DIM))
msk &= ~(1 << ATR_DIM);
return msk;
}
void
term_start_attr(attr)
int attr;
{
if (attr) {
xputs(s_atr2str(attr));
const char *astr = s_atr2str(attr);
if (*astr)
xputs(s_atr2str(attr));
}
}
@@ -1220,7 +1245,10 @@ term_end_attr(attr)
int attr;
{
if (attr) {
xputs(e_atr2str(attr));
const char *astr = e_atr2str(attr);
if (*astr)
xputs(e_atr2str(attr));
}
}
@@ -1248,7 +1276,8 @@ void
term_start_color(color)
int color;
{
xputs(hilites[color]);
if (color < CLR_MAX)
xputs(hilites[color]);
}
/* not to be confused with has_colors() in unixtty.c */

File diff suppressed because it is too large Load Diff