Files
nethack/include/botl.h
PatR 41a5565403 new 'showvers' option
Add options 'showvers' (boolean) and 'versinfo' (numeric mask) to
show nethack's version on the status lines during play.  It won't be
particularly interesting to ordinary players but should be useful
when making screenshots or video to be streamed, or for someone who
switches between git branches or between nethack and variants.

I worked on this several months back but it was combined with
unfinished changes to 'hitpointbar'.  I've separated it out so that
it can be put into use.  When enabled, one or more components of
"<name> <branch> <version>" will be shown right justified after
status conditions.  At present the default is "<branch>" if that is
available and overall status isn't 'released', or "<version>" if
'released' or if branch isn't available.  That might need some
refinement.

It works as intended for tty and curses, although some abbreviation
mechanism would be useful if/when the program resorts to abbreviating
status conditions to make things narrow enough to fit.

For X11, it works ok for fancy_status:True (the default, controlled
via NetHack.ad settings) but is messed up for tty-style status.  The
text is positioned correctly but there are gaps in it, making it
appear garbled, similar to what I saw when I tried and failed to
implement statuslines:3 for X11.  [It might be due to having empty
condition widgets be 1 pixel wide instead of being totally removed
but I don't think the situation is that simple.]

For Qt, if the text needs to be truncated in order to fit, the center
portion of the string will be shown, discarding parts from the left
and right.  That ought to discard from left and retain rightmost
portion instead.

For win32|mswin|Win GUI, no attempt to support it has been included.
Things should be ok when 'showvers' is left as False (the default)
but I don't know what will happen if that gets toggled to True.  At a
minimum, the version info won't be right justified.  The information,
or at least some of it, is displayed in the game window's title bar
so there isn't any pressing need to add it to status, but toggling
the option will need to behave sensibly if it doesn't already.
2024-02-28 11:47:16 -08:00

290 lines
9.3 KiB
C

/* NetHack 3.7 botl.h $NHDT-Date: 1694893330 2023/09/16 19:42:10 $ $NHDT-Branch: NetHack-3.7 $:$NHDT-Revision: 1.37 $ */
/* Copyright (c) Michael Allison, 2003 */
/* NetHack may be freely redistributed. See license for details. */
#ifndef BOTL_H
#define BOTL_H
/* MAXCO must hold longest uncompressed status line, and must be larger
* than COLNO
*
* longest practical second status line at the moment is
Astral Plane \GXXXXNNNN:123456 HP:1234(1234) Pw:1234(1234) AC:-127
Xp:30/123456789 T:123456 Stone Slime Strngl FoodPois TermIll
Satiated Overloaded Blind Deaf Stun Conf Hallu Lev Ride
* -- or about 185 characters. '$' gets encoded even when it
* could be used as-is. The first five status conditions are fatal
* so it's rare to have more than one at a time.
*
* When the full line is wider than the map, the basic status line
* formatting will move less important fields to the end, so if/when
* truncation is necessary, it will chop off the least significant
* information.
*/
#if COLNO <= 160
#define MAXCO 200
#else
#define MAXCO (COLNO + 40)
#endif
struct condmap {
const char *id;
unsigned long bitmask;
};
enum statusfields {
BL_CHARACTERISTICS = -3, /* alias for BL_STR..BL_CH */
BL_RESET = -2, /* Force everything to redisplay */
BL_FLUSH = -1, /* Finished cycling through bot fields */
BL_TITLE = 0,
BL_STR, BL_DX, BL_CO, BL_IN, BL_WI, BL_CH, /* 1..6 */
BL_ALIGN, BL_SCORE, BL_CAP, BL_GOLD, BL_ENE, BL_ENEMAX, /* 7..12 */
BL_XP, BL_AC, BL_HD, BL_TIME, BL_HUNGER, BL_HP, /* 13..18 */
BL_HPMAX, BL_LEVELDESC, BL_EXP, BL_CONDITION, /* 19..22 */
BL_VERS, /* 23 */
MAXBLSTATS, /* [24] */
};
enum relationships {
NO_LTEQGT = -1,
EQ_VALUE, LT_VALUE, LE_VALUE,
GE_VALUE, GT_VALUE, TXT_VALUE
};
enum blconditions {
bl_bareh,
bl_blind,
bl_busy,
bl_conf,
bl_deaf,
bl_elf_iron,
bl_fly,
bl_foodpois,
bl_glowhands,
bl_grab,
bl_hallu,
bl_held,
bl_icy,
bl_inlava,
bl_lev,
bl_parlyz,
bl_ride,
bl_sleeping,
bl_slime,
bl_slippery,
bl_stone,
bl_strngl,
bl_stun,
bl_submerged,
bl_termill,
bl_tethered,
bl_trapped,
bl_unconsc,
bl_woundedl,
bl_holding,
CONDITION_COUNT
};
/* Boolean condition bits for the condition mask */
/* clang-format off */
#define BL_MASK_BAREH 0x00000001L
#define BL_MASK_BLIND 0x00000002L
#define BL_MASK_BUSY 0x00000004L
#define BL_MASK_CONF 0x00000008L
#define BL_MASK_DEAF 0x00000010L
#define BL_MASK_ELF_IRON 0x00000020L
#define BL_MASK_FLY 0x00000040L
#define BL_MASK_FOODPOIS 0x00000080L
#define BL_MASK_GLOWHANDS 0x00000100L
#define BL_MASK_GRAB 0x00000200L
#define BL_MASK_HALLU 0x00000400L
#define BL_MASK_HELD 0x00000800L
#define BL_MASK_ICY 0x00001000L
#define BL_MASK_INLAVA 0x00002000L
#define BL_MASK_LEV 0x00004000L
#define BL_MASK_PARLYZ 0x00008000L
#define BL_MASK_RIDE 0x00010000L
#define BL_MASK_SLEEPING 0x00020000L
#define BL_MASK_SLIME 0x00040000L
#define BL_MASK_SLIPPERY 0x00080000L
#define BL_MASK_STONE 0x00100000L
#define BL_MASK_STRNGL 0x00200000L
#define BL_MASK_STUN 0x00400000L
#define BL_MASK_SUBMERGED 0x00800000L
#define BL_MASK_TERMILL 0x01000000L
#define BL_MASK_TETHERED 0x02000000L
#define BL_MASK_TRAPPED 0x04000000L
#define BL_MASK_UNCONSC 0x08000000L
#define BL_MASK_WOUNDEDL 0x10000000L
#define BL_MASK_HOLDING 0x20000000L
#define BL_MASK_BITS 30 /* number of mask bits that can be set */
/* clang-format on */
struct conditions_t {
int ranking;
long mask;
enum blconditions c;
const char *text[3];
};
extern const struct conditions_t conditions[CONDITION_COUNT];
struct condtests_t {
enum blconditions c;
const char *useroption;
enum optchoice opt;
boolean enabled;
boolean choice;
boolean test;
};
extern struct condtests_t condtests[CONDITION_COUNT];
extern int cond_idx[CONDITION_COUNT];
#define BEFORE 0
#define NOW 1
/*
* Possible additional conditions:
* major:
* grab - grabbed by eel so about to be drowned ("wrapd"? damage type
* is AD_WRAP but message is "<mon> swings itself around you")
* digst - swallowed and being digested
* lava - trapped sinking into lava
* in_between: (potentially severe but don't necessarily lead to death;
* explains to player why he isn't getting to take any turns)
* unconc - unconscious
* parlyz - (multi < 0 && (!strncmp(multi_reason, "paralyzed", 9)
* || !strncmp(multi_reason, "frozen", 6)))
* asleep - (multi < 0 && !strncmp(multi_reason, "sleeping", 8))
* busy - other multi < 0
* minor:
* held - grabbed by non-eel or by eel but not susceptible to drowning
* englf - engulfed or swallowed but not being digested (usually
* obvious but the blank symbol set makes that uncertain)
* vomit - vomiting (causes confusion and stun late in countdown)
* trap - trapped in pit, bear trap, web, or floor (solidified lava)
* teth - tethered to buried iron ball
* chain - punished
* slip - slippery fingers
* ice - standing on ice (movement becomes uncertain)
* [underwater - movement uncertain, vision truncated, equipment at risk]
* other:
* [hold - poly'd into grabber and holding adjacent monster]
* Stormbringer - wielded weapon poses risks
* Cleaver - wielded weapon risks unintended consequences
* barehand - not wielding any weapon nor wearing gloves
* no-weapon - not wielding any weapon
* bow/xbow/sling - wielding a missile launcher of specified type
* pole - wielding a polearm
* pick - wielding a pickaxe
* junk - wielding non-weapon, non-weptool
* naked - no armor
* no-gloves - self-explanatory
* no-cloak - ditto
* [no-{other armor slots?} - probably much too verbose]
* conduct?
* [maybe if third status line is added]
*
* Can't add all of these and probably don't want to. But maybe we
* can add some of them and it's not as many as first appears:
* lava/trap/teth are mutually exclusive;
* digst/grab/englf/held/hold are also mutually exclusive;
* Stormbringer/Cleaver/barehand/no-weapon/bow&c/pole/pick/junk too;
* naked/no-{any armor slot} likewise.
*/
#define VIA_WINDOWPORT() \
((windowprocs.wincap2 & (WC2_HILITE_STATUS | WC2_FLUSH_STATUS)) != 0)
#define REASSESS_ONLY TRUE
/* #ifdef STATUS_HILITES */
/* hilite status field behavior - coloridx values */
#define BL_HILITE_NONE -1 /* no hilite of this field */
#if 0
#define BL_HILITE_BOLD -2 /* bold hilite */
#define BL_HILITE_DIM -3 /* dim hilite */
#define BL_HILITE_ITALIC -4 /* italic hilite */
#define BL_HILITE_ULINE -5 /* underline hilite */
#define BL_HILITE_BLINK -6 /* blink hilite */
#define BL_HILITE_INVERSE -7 /* inverse hilite */
/* or any CLR_ index (0 - 15) */
#endif
#define BL_TH_NONE 0
#define BL_TH_VAL_PERCENTAGE 100 /* threshold is percentage */
#define BL_TH_VAL_ABSOLUTE 101 /* threshold is particular value */
#define BL_TH_UPDOWN 102 /* threshold is up or down change */
#define BL_TH_CONDITION 103 /* threshold is bitmask of conditions */
#define BL_TH_TEXTMATCH 104 /* threshold text value to match against */
#define BL_TH_ALWAYS_HILITE 105 /* highlight regardless of value */
#define BL_TH_CRITICALHP 106 /* highlight critically low HP */
#define HL_ATTCLR_NONE CLR_MAX + 1
#define HL_ATTCLR_BOLD CLR_MAX + 2
#define HL_ATTCLR_DIM CLR_MAX + 3
#define HL_ATTCLR_ITALIC CLR_MAX + 4
#define HL_ATTCLR_ULINE CLR_MAX + 5
#define HL_ATTCLR_BLINK CLR_MAX + 6
#define HL_ATTCLR_INVERSE CLR_MAX + 7
#define BL_ATTCLR_MAX CLR_MAX + 8
enum hlattribs {
HL_UNDEF = 0x00,
HL_NONE = 0x01,
HL_BOLD = 0x02,
HL_DIM = 0x04,
HL_ITALIC = 0x08,
HL_ULINE = 0x10,
HL_BLINK = 0x20,
HL_INVERSE = 0x40
};
#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;
boolean set;
unsigned anytype;
anything value;
int behavior;
char textmatch[MAXVALWIDTH];
enum relationships rel;
int coloridx;
struct hilite_s *next;
};
#endif
/*
* Note: If you add/change/remove fields in istat_s, you need to
* update the initialization of the istat_s struct blstats[][]
* array in instance_globals_b (decl.c).
*/
struct istat_s {
const char *fldname;
const char *fldfmt;
long time; /* moves when this field hilite times out */
boolean chg; /* need to recalc time? */
boolean percent_matters;
short percent_value;
unsigned anytype;
anything a, rawval;
char *val;
int valwidth;
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
};
extern const char *status_fieldnames[]; /* in botl.c */
#endif /* BOTL_H */