Merge branch 'new-status-conditions' into NetHack-3.7

This commit is contained in:
nhmall
2020-02-08 01:24:51 -05:00
7 changed files with 457 additions and 142 deletions

View File

@@ -420,19 +420,35 @@ status_update(int fldindex, genericptr_t ptr, int chg, int percentage, int color
-- ptr is usually a "char *", unless fldindex is BL_CONDITION.
If fldindex is BL_CONDITION, then ptr is a long value with
any or none of the following bits set (from botl.h):
BL_MASK_STONE 0x00000001L
BL_MASK_SLIME 0x00000002L
BL_MASK_STRNGL 0x00000004L
BL_MASK_FOODPOIS 0x00000008L
BL_MASK_TERMILL 0x00000010L
BL_MASK_BLIND 0x00000020L
BL_MASK_DEAF 0x00000040L
BL_MASK_STUN 0x00000080L
BL_MASK_CONF 0x00000100L
BL_MASK_HALLU 0x00000200L
BL_MASK_LEV 0x00000400L
BL_MASK_FLY 0x00000800L
BL_MASK_RIDE 0x00001000L
BL_MASK_BAREH 0x00000001L
BL_MASK_BLIND 0x00000002L
BL_MASK_BUSY 0x00000004L
BL_MASK_CONF 0x00000008L
BL_MASK_DEAF 0x00000010L
BL_MASK_ELF_IRON 0x00000020L
BL_MASK_FLY 0x00000040L
BL_MASK_FOODPOIS 0x00000080L
BL_MASK_GLOWHANDS 0x00000100L
BL_MASK_GRAB 0x00000200L
BL_MASK_HALLU 0x00000400L
BL_MASK_HELD 0x00000800L
BL_MASK_ICY 0x00001000L
BL_MASK_INLAVA 0x00002000L
BL_MASK_LEV 0x00004000L
BL_MASK_PARLYZ 0x00008000L
BL_MASK_RIDE 0x00010000L
BL_MASK_SLEEPING 0x00020000L
BL_MASK_SLIME 0x00040000L
BL_MASK_SLIPPERY 0x00080000L
BL_MASK_STONE 0x00100000L
BL_MASK_STRNGL 0x00200000L
BL_MASK_STUN 0x00400000L
BL_MASK_SUBMERGED 0x00800000L
BL_MASK_TERMILL 0x01000000L
BL_MASK_TETHERED 0x02000000L
BL_MASK_TRAPPED 0x04000000L
BL_MASK_UNCONSC 0x08000000L
BL_MASK_WOUNDEDL 0x10000000L
-- The value passed for BL_GOLD includes a leading
symbol for GOLD "$:nnn". If the window port needs to use
the textual gold amount without the leading "$:" the port

View File

@@ -48,28 +48,97 @@ enum relationships { NO_LTEQGT = -1,
EQ_VALUE, LT_VALUE, LE_VALUE,
GE_VALUE, GT_VALUE, TXT_VALUE };
#define BEFORE 0
#define NOW 1
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,
CONDITION_COUNT
};
/* Boolean condition bits for the condition mask */
/* clang-format off */
#define BL_MASK_STONE 0x00000001L
#define BL_MASK_SLIME 0x00000002L
#define BL_MASK_STRNGL 0x00000004L
#define BL_MASK_FOODPOIS 0x00000008L
#define BL_MASK_TERMILL 0x00000010L
#define BL_MASK_BLIND 0x00000020L
#define BL_MASK_DEAF 0x00000040L
#define BL_MASK_STUN 0x00000080L
#define BL_MASK_CONF 0x00000100L
#define BL_MASK_HALLU 0x00000200L
#define BL_MASK_LEV 0x00000400L
#define BL_MASK_FLY 0x00000800L
#define BL_MASK_RIDE 0x00001000L
#define BL_MASK_BITS 13 /* number of mask bits that can be set */
#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_BITS 28 /* number of mask bits that can be set */
/* clang-format on */
struct conditions_t {
int priority;
long mask;
enum blconditions c;
const char *text[3];
};
extern const struct conditions_t conditions[CONDITION_COUNT];
enum condchoice { opt_in, opt_out};
struct condtests_t {
enum blconditions c;
enum condchoice opt;
boolean enabled;
boolean choice;
boolean test;
};
extern struct condtests_t condtests[CONDITION_COUNT];
#define BEFORE 0
#define NOW 1
/*
* Possible additional conditions:
* major:

View File

@@ -183,6 +183,7 @@ E boolean NDECL(exp_percent_changing);
E int NDECL(stat_cap_indx);
E int NDECL(stat_hunger_indx);
E const char *FDECL(bl_idx_to_fldname, (int));
E void FDECL(condopt, (boolean *, BOOLEAN_P));
#ifdef STATUS_HILITES
E void NDECL(status_eval_next_unhilite);
E void NDECL(reset_status_hilites);

View File

@@ -421,6 +421,7 @@ static int FDECL(compare_blstats, (struct istat_s *, struct istat_s *));
static char *FDECL(anything_to_s, (char *, anything *, int));
static int FDECL(percentage, (struct istat_s *, struct istat_s *));
static int NDECL(exp_percentage);
static boolean FDECL(test_condition, (enum blconditions, struct permonst *));
#ifdef STATUS_HILITES
static void FDECL(s_to_anything, (anything *, char *, int));
@@ -510,8 +511,117 @@ static struct istat_s initblstats[MAXBLSTATS] = {
#undef INIT_BLSTAT
#undef INIT_THRESH
#ifdef STATUS_HILITES
#endif
const struct conditions_t conditions[] = {
/* priority, mask, identifier, txt1, txt2, txt3 */
{ 3, BL_MASK_BAREH, bl_bareh, { "Bare", "Bar", "Bh" } },
{ 2, BL_MASK_BLIND, bl_blind, { "Blind", "Blnd", "Bl" } },
{ 3, BL_MASK_BUSY, bl_busy, { "Busy", "Bsy", "By" } },
{ 2, BL_MASK_CONF, bl_conf, { "Conf", "Cnf", "Cf" } },
{ 2, BL_MASK_DEAF, bl_deaf, { "Deaf", "Def", "Df" } },
{ 3, BL_MASK_ELF_IRON, bl_elf_iron, { "Iron", "Irn", "Fe" } },
{ 2, BL_MASK_FLY, bl_fly, { "Fly", "Fly", "Fl" } },
{ 2, BL_MASK_FOODPOIS, bl_foodpois, { "FoodPois", "Fpois", "Poi" } },
{ 3, BL_MASK_GLOWHANDS, bl_glowhands, { "Glow", "Glo", "Gl" } },
{ 2, BL_MASK_GRAB, bl_grab, { "Grab", "Grb", "Gr" } },
{ 2, BL_MASK_HALLU, bl_hallu, { "Hallu", "Hal", "Hl" } },
{ 3, BL_MASK_HELD, bl_held, { "Held", "Hld", "Hd" } },
{ 3, BL_MASK_ICY, bl_icy, { "Icy", "Icy", "Ic" } },
{ 2, BL_MASK_INLAVA, bl_inlava, { "Lava", "Lav", "La" } },
{ 2, BL_MASK_LEV, bl_lev, { "Lev", "Lev", "Lv" } },
{ 3, BL_MASK_PARLYZ, bl_parlyz, { "Parlyz", "Para", "Par" } },
{ 2, BL_MASK_RIDE, bl_ride, { "Ride", "Rid", "Rd" } },
{ 3, BL_MASK_SLEEPING, bl_sleeping, { "Zzz", "Zzz", "Zz" } },
{ 2, BL_MASK_SLIME, bl_slime, { "Slime", "Slim", "Slm" } },
{ 3, BL_MASK_SLIPPERY, bl_slippery, { "Slip", "Sli", "Sl" } },
{ 2, BL_MASK_STONE, bl_stone, { "Stone", "Ston", "Sto" } },
{ 2, BL_MASK_STRNGL, bl_strngl, { "Strngl", "Stngl", "Str" } },
{ 2, BL_MASK_STUN, bl_stun, { "Stun", "Stun", "St" } },
{ 3, BL_MASK_SUBMERGED, bl_submerged, { "Sub", "Sub", "Sw" } },
{ 2, BL_MASK_TERMILL, bl_termill, { "TermIll", "Ill", "Ill" } },
{ 3, BL_MASK_TETHERED, bl_tethered, { "Teth", "Tth", "Te" } },
{ 3, BL_MASK_TRAPPED, bl_trapped, { "Trap", "Trp", "Tr" } },
{ 3, BL_MASK_UNCONSC, bl_unconsc, { "Out", "Out", "KO" } },
{ 3, BL_MASK_WOUNDEDL, bl_woundedl, { "Legs", "Leg", "Lg" } },
};
struct condtests_t condtests[CONDITION_COUNT] = {
/* id, opt_in or out, enabled, configchoice, testresult */
{ bl_bareh, opt_in, FALSE, FALSE, FALSE },
{ bl_blind, opt_out, TRUE, FALSE, FALSE },
{ bl_busy, opt_in, FALSE, FALSE, FALSE },
{ bl_conf, opt_out, TRUE, FALSE, FALSE },
{ bl_deaf, opt_out, TRUE, FALSE, FALSE },
{ bl_elf_iron, opt_out, TRUE, FALSE, FALSE },
{ bl_fly, opt_out, TRUE, FALSE, FALSE },
{ bl_foodpois, opt_out, TRUE, FALSE, FALSE },
{ bl_glowhands, opt_in, FALSE, FALSE, FALSE },
{ bl_grab, opt_out, TRUE, FALSE, FALSE },
{ bl_hallu, opt_out, TRUE, FALSE, FALSE },
{ bl_held, opt_in, FALSE, FALSE, FALSE },
{ bl_icy, opt_in, FALSE, FALSE, FALSE },
{ bl_inlava, opt_out, TRUE, FALSE, FALSE },
{ bl_lev, opt_out, TRUE, FALSE, FALSE },
{ bl_parlyz, opt_in, FALSE, FALSE, FALSE },
{ bl_ride, opt_out, TRUE, FALSE, FALSE },
{ bl_sleeping, opt_in, FALSE, FALSE, FALSE },
{ bl_slime, opt_out, TRUE, FALSE, FALSE },
{ bl_slippery, opt_in, FALSE, FALSE, FALSE },
{ bl_stone, opt_out, TRUE, FALSE, FALSE },
{ bl_strngl, opt_out, TRUE, FALSE, FALSE },
{ bl_stun, opt_out, TRUE, FALSE, FALSE },
{ bl_submerged, opt_in, FALSE, FALSE, FALSE },
{ bl_termill, opt_out, TRUE, FALSE, FALSE },
{ bl_tethered, opt_in, FALSE, FALSE, FALSE },
{ bl_trapped, opt_in, FALSE, FALSE, FALSE },
{ bl_unconsc, opt_in, FALSE, FALSE, FALSE },
{ bl_woundedl, opt_in, FALSE, FALSE, FALSE },
};
/* cache-related */
static boolean cache_avail[3] = { FALSE, FALSE, FALSE };
static boolean cache_reslt[3] = { FALSE, FALSE, FALSE };
static const char *cache_nomovemsg = NULL, *cache_multi_reason = NULL;
static d_level cache_uz = { 0 };
static boolean cache_underwater = FALSE;
#define cond_cache_prep() \
do { \
boolean clear_cache = FALSE, refresh_cache = FALSE; \
\
if (g.multi < 0) { \
if (g.nomovemsg || g.multi_reason) { \
if (cache_nomovemsg != g.nomovemsg) \
refresh_cache = TRUE; \
if (cache_multi_reason != g.multi_reason) \
refresh_cache = TRUE; \
} else { \
clear_cache = TRUE; \
} \
} else { \
clear_cache = TRUE; \
} \
if (clear_cache) { \
cache_nomovemsg = (const char *) 0; \
cache_multi_reason = (const char *) 0; \
} \
if (refresh_cache) { \
cache_nomovemsg = g.nomovemsg; \
cache_multi_reason = g.multi_reason; \
} \
if (clear_cache || refresh_cache) { \
cache_reslt[0] = cache_avail[0] = FALSE; \
cache_reslt[1] = cache_avail[1] = FALSE; \
} \
if (((cache_uz.dnum != u.uz.dnum) \
|| (cache_uz.dlevel != u.uz.dlevel)) \
|| (cache_underwater != Underwater)) { \
cache_uz.dnum = 0; \
cache_uz.dlevel = 0; \
cache_underwater = 0; \
cache_reslt[2] = cache_avail[2] = FALSE; \
} \
} while (0)
/* we don't put this next declaration in #ifdef STATUS_HILITES.
* In the absence of STATUS_HILITES, each array
* element will be 0 however, and quite meaningless,
@@ -667,40 +777,119 @@ bot_via_windowport()
g.valset[BL_CAP] = TRUE;
/* Conditions */
g.blstats[idx][BL_CONDITION].a.a_ulong = 0L;
if (Stoned)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_STONE;
if (Slimed)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_SLIME;
if (Strangled)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_STRNGL;
if (Sick && (u.usick_type & SICK_VOMITABLE) != 0)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_FOODPOIS;
if (Sick && (u.usick_type & SICK_NONVOMITABLE) != 0)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_TERMILL;
/*
* basic formatting puts hunger status and encumbrance here
*/
if (Blind)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_BLIND;
if (Deaf)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_DEAF;
if (Stunned)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_STUN;
if (Confusion)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_CONF;
if (Hallucination)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_HALLU;
/* levitation and flying are mututally exclusive */
if (Levitation)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_LEV;
if (Flying)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_FLY;
if (u.usteed)
g.blstats[idx][BL_CONDITION].a.a_ulong |= BL_MASK_RIDE;
/* avoid anything that does string comparisons in here because this
is called *extremely* often, for every screen update and the same
string comparisons would be repeated, thus contributing toward
performance degradation. If it is essential that string comparisons
are needed for a particular condition, consider adding a caching
mechanism to limit the string comparisons to the first occurrence
for that cache lifetime. There is caching of that nature done for
unconsc (1) and parlyz (2) because the suggested way of being able
to distinguish unconsc, parlyz, sleeping, and busy involves multiple
string comparisons. There is also caching done for submerged (3) to
avoid repeatedly calling the on_level() function unnecessarily. */
#define test_if_enabled(c) if (condtests[(c)].enabled) condtests[(c)].test
condtests[bl_blind].test = (Blind);
condtests[bl_conf].test = (Confusion) ? TRUE : FALSE;
condtests[bl_deaf].test = (Deaf);
condtests[bl_fly].test = (Flying);
condtests[bl_foodpois].test = (Sick && (u.usick_type & SICK_VOMITABLE) != 0);
condtests[bl_glowhands].test = (u.umconf);
condtests[bl_grab].test = (u.ustuck && u.ustuck->data->mlet == S_EEL);
condtests[bl_hallu].test = (Hallucination);
condtests[bl_inlava].test = (u.utrap && u.utraptype == TT_LAVA);
condtests[bl_lev].test = (Levitation);
condtests[bl_ride].test = (u.usteed) ? TRUE : FALSE;
condtests[bl_slime].test = (Slimed) ? TRUE : FALSE;
condtests[bl_stone].test = (Stoned) ? TRUE : FALSE;
condtests[bl_strngl].test = (Strangled) ? TRUE : FALSE;
condtests[bl_stun].test = (Stunned) ? TRUE : FALSE;
condtests[bl_termill].test = (Sick && (u.usick_type & SICK_NONVOMITABLE) != 0);
test_if_enabled(bl_elf_iron) = (FALSE);
test_if_enabled(bl_bareh) = (!uarmg && !uwep);
test_if_enabled(bl_held) = (u.ustuck && !condtests[bl_grab].test);
test_if_enabled(bl_icy) = levl[u.ux][u.uy].typ == ICE;
test_if_enabled(bl_slippery) = (Glib) ? TRUE : FALSE;
test_if_enabled(bl_trapped) = (u.utrap && u.utraptype != TT_BURIEDBALL
&& u.utraptype != TT_LAVA);
test_if_enabled(bl_tethered) = (u.utrap && u.utraptype == TT_BURIEDBALL);
test_if_enabled(bl_woundedl) = (Wounded_legs);
cond_cache_prep();
if (condtests[bl_unconsc].enabled) {
if (cache_nomovemsg && !cache_avail[0]) {
cache_reslt[0] = unconscious();
cache_avail[0] = TRUE;
}
}
if (condtests[bl_parlyz].enabled) {
if (cache_multi_reason && !cache_avail[1]) {
cache_reslt[1] = (!strncmp(cache_multi_reason, "paralyzed", 9)
|| !strncmp(cache_multi_reason, "frozen", 6));
cache_avail[1] = TRUE;
}
}
/* unconsc */
if (cache_avail[0] && condtests[bl_unconsc].enabled) {
condtests[bl_unconsc].test = cache_reslt[0];
} else {
condtests[bl_unconsc].test = FALSE;
}
/* parlyz */
if (cache_avail[1] && condtests[bl_parlyz].enabled
&& !condtests[bl_unconsc].test) {
condtests[bl_parlyz].test = cache_reslt[1];
} else {
condtests[bl_parlyz].test = FALSE;
}
/* sleeping */
if (!condtests[bl_unconsc].test && !condtests[bl_parlyz].test) {
condtests[bl_sleeping].test = u.usleep ? TRUE : FALSE;
} else {
condtests[bl_sleeping].test = FALSE;
}
/* busy */
if (!condtests[bl_unconsc].test && !condtests[bl_parlyz].test
&& !condtests[bl_sleeping].test) {
condtests[bl_busy].test = (g.multi < 0);
} else {
condtests[bl_busy].test = FALSE;
}
/* submerged */
if (condtests[bl_submerged].enabled) {
if (!cache_avail[2] && cache_underwater == 0
&& (cache_uz.dlevel == 0 && cache_uz.dnum == 0)) {
cache_uz = u.uz;
cache_underwater = (Underwater) ? TRUE : FALSE;
cache_reslt[2] = (Underwater && !Is_waterlevel(&u.uz));
cache_avail[2] = TRUE;
}
if (cache_avail[2]) {
condtests[bl_submerged].test = cache_reslt[2];
} else {
condtests[bl_submerged].test = FALSE;
}
}
#define cond_bitset(c) \
g.blstats[idx][BL_CONDITION].a.a_ulong |= conditions[(c)].mask;
for (i = 0; i < CONDITION_COUNT; ++i) {
if (condtests[i].enabled && condtests[i].test)
cond_bitset(i);
}
evaluate_and_notify_windowport(g.valset, idx);
}
/* update just the status lines' 'time' field */
static void
stat_update_time()
@@ -1368,6 +1557,28 @@ int idx;
return (const char *) 0;
}
/* deal with player's choice to change processing of a condition */
void
condopt(addr, negated)
boolean *addr;
boolean negated;
{
int i;
for (i = 0; i < CONDITION_COUNT; ++i) {
if (!addr) {
/* special: indicates a request to init so
set the choice values to match the defaults */
condtests[i].choice = condtests[i].enabled;
} else if (addr == &condtests[i].choice) {
condtests[i].enabled = negated ? FALSE : TRUE;
}
/* avoid lingering false positives if test is no longer run */
if (!condtests[i].enabled)
condtests[i].test = FALSE;
}
}
#ifdef STATUS_HILITES
/****************************************************************************/
@@ -2269,22 +2480,6 @@ boolean from_configfile;
}
#endif /* STATUS_HILITES */
const struct condmap valid_conditions[] = {
{ "stone", BL_MASK_STONE },
{ "slime", BL_MASK_SLIME },
{ "strngl", BL_MASK_STRNGL },
{ "foodPois", BL_MASK_FOODPOIS },
{ "termIll", BL_MASK_TERMILL },
{ "blind", BL_MASK_BLIND },
{ "deaf", BL_MASK_DEAF },
{ "stun", BL_MASK_STUN },
{ "conf", BL_MASK_CONF },
{ "hallu", BL_MASK_HALLU },
{ "lev", BL_MASK_LEV },
{ "fly", BL_MASK_FLY },
{ "ride", BL_MASK_RIDE },
};
#ifdef STATUS_HILITES
const struct condmap condition_aliases[] = {
@@ -2293,12 +2488,14 @@ const struct condmap condition_aliases[] = {
| BL_MASK_FOODPOIS | BL_MASK_TERMILL
| BL_MASK_BLIND | BL_MASK_DEAF | BL_MASK_STUN
| BL_MASK_CONF | BL_MASK_HALLU
| BL_MASK_LEV | BL_MASK_FLY | BL_MASK_RIDE },
| BL_MASK_LEV | BL_MASK_FLY | BL_MASK_RIDE
| BL_MASK_ELF_IRON },
{ "major_troubles", BL_MASK_STONE | BL_MASK_SLIME | BL_MASK_STRNGL
| BL_MASK_FOODPOIS | BL_MASK_TERMILL },
{ "minor_troubles", BL_MASK_BLIND | BL_MASK_DEAF | BL_MASK_STUN
| BL_MASK_CONF | BL_MASK_HALLU },
{ "movement", BL_MASK_LEV | BL_MASK_FLY | BL_MASK_RIDE }
{ "movement", BL_MASK_LEV | BL_MASK_FLY | BL_MASK_RIDE },
{ "moreconditions", BL_MASK_ELF_IRON },
};
unsigned long
@@ -2313,11 +2510,11 @@ query_conditions()
tmpwin = create_nhwindow(NHW_MENU);
start_menu(tmpwin);
for (i = 0; i < SIZE(valid_conditions); i++) {
for (i = 0; i < SIZE(conditions); i++) {
any = cg.zeroany;
any.a_ulong = valid_conditions[i].bitmask;
any.a_ulong = conditions[i].mask;
add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE,
valid_conditions[i].id, MENU_ITEMFLAGS_NONE);
conditions[i].text[0], MENU_ITEMFLAGS_NONE);
}
end_menu(tmpwin, "Choose status conditions");
@@ -2350,10 +2547,10 @@ unsigned long ul;
if (condition_aliases[i].bitmask == ul)
alias = condition_aliases[i].id;
for (i = 0; i < SIZE(valid_conditions); i++)
if ((valid_conditions[i].bitmask & ul) != 0UL) {
for (i = 0; i < SIZE(conditions); i++)
if ((conditions[i].mask & ul) != 0UL) {
Sprintf(eos(buf), "%s%s", (first) ? "" : "+",
valid_conditions[i].id);
conditions[i].text[0]);
first = FALSE;
}
@@ -2372,9 +2569,9 @@ const char *str;
if (str && *str) {
/* check matches to canonical names */
for (i = 0; i < SIZE(valid_conditions); i++)
if (fuzzymatch(valid_conditions[i].id, str, " -_", TRUE)) {
mask |= valid_conditions[i].bitmask;
for (i = 0; i < SIZE(conditions); i++)
if (fuzzymatch(conditions[i].text[0], str, " -_", TRUE)) {
mask |= conditions[i].mask;
nmatches++;
}
@@ -2410,7 +2607,7 @@ char *str;
char **subfields;
int i, sf;
sf = splitsubfields(str, &subfields, SIZE(valid_conditions));
sf = splitsubfields(str, &subfields, SIZE(conditions));
if (sf < 1)
return 0UL;
@@ -2694,30 +2891,30 @@ status_hilite_linestr_gather_conditions()
struct _cond_map {
unsigned long bm;
unsigned long clratr;
} cond_maps[SIZE(valid_conditions)];
} cond_maps[SIZE(conditions)];
(void) memset(cond_maps, 0,
SIZE(valid_conditions) * sizeof (struct _cond_map));
SIZE(conditions) * sizeof (struct _cond_map));
for (i = 0; i < SIZE(valid_conditions); i++) {
for (i = 0; i < SIZE(conditions); i++) {
int clr = NO_COLOR;
int atr = HL_NONE;
int j;
for (j = 0; j < CLR_MAX; j++)
if (g.cond_hilites[j] & valid_conditions[i].bitmask) {
if (g.cond_hilites[j] & conditions[i].mask) {
clr = j;
break;
}
if (g.cond_hilites[HL_ATTCLR_DIM] & valid_conditions[i].bitmask)
if (g.cond_hilites[HL_ATTCLR_DIM] & conditions[i].mask)
atr |= HL_DIM;
if (g.cond_hilites[HL_ATTCLR_BOLD] & valid_conditions[i].bitmask)
if (g.cond_hilites[HL_ATTCLR_BOLD] & conditions[i].mask)
atr |= HL_BOLD;
if (g.cond_hilites[HL_ATTCLR_BLINK] & valid_conditions[i].bitmask)
if (g.cond_hilites[HL_ATTCLR_BLINK] & conditions[i].mask)
atr |= HL_BLINK;
if (g.cond_hilites[HL_ATTCLR_ULINE] & valid_conditions[i].bitmask)
if (g.cond_hilites[HL_ATTCLR_ULINE] & conditions[i].mask)
atr |= HL_ULINE;
if (g.cond_hilites[HL_ATTCLR_INVERSE] & valid_conditions[i].bitmask)
if (g.cond_hilites[HL_ATTCLR_INVERSE] & conditions[i].mask)
atr |= HL_INVERSE;
if (atr != HL_NONE)
atr &= ~HL_NONE;
@@ -2726,16 +2923,16 @@ status_hilite_linestr_gather_conditions()
unsigned long ca = clr | (atr << 8);
boolean added_condmap = FALSE;
for (j = 0; j < SIZE(valid_conditions); j++)
for (j = 0; j < SIZE(conditions); j++)
if (cond_maps[j].clratr == ca) {
cond_maps[j].bm |= valid_conditions[i].bitmask;
cond_maps[j].bm |= conditions[i].mask;
added_condmap = TRUE;
break;
}
if (!added_condmap) {
for (j = 0; j < SIZE(valid_conditions); j++)
for (j = 0; j < SIZE(conditions); j++)
if (!cond_maps[j].bm) {
cond_maps[j].bm = valid_conditions[i].bitmask;
cond_maps[j].bm = conditions[i].mask;
cond_maps[j].clratr = ca;
break;
}
@@ -2743,7 +2940,7 @@ status_hilite_linestr_gather_conditions()
}
}
for (i = 0; i < SIZE(valid_conditions); i++)
for (i = 0; i < SIZE(conditions); i++)
if (cond_maps[i].bm) {
int clr = NO_COLOR, atr = HL_NONE;

View File

@@ -115,6 +115,35 @@ static const struct Bool_Opt {
{ "color", &iflags.wc_color, FALSE, SET_IN_GAME },
#endif
{ "confirm", &flags.confirm, TRUE, SET_IN_GAME },
{ "cond_barehanded", &condtests[bl_bareh].choice, FALSE, SET_IN_GAME },
{ "cond_blind", &condtests[bl_blind].choice, FALSE, SET_IN_GAME },
{ "cond_busy", &condtests[bl_busy].choice, FALSE, SET_IN_GAME },
{ "cond_conf", &condtests[bl_conf].choice, FALSE, SET_IN_GAME },
{ "cond_deaf", &condtests[bl_deaf].choice, FALSE, SET_IN_GAME },
{ "cond_fly", &condtests[bl_fly].choice, FALSE, SET_IN_GAME },
{ "cond_foodPois", &condtests[bl_foodpois].choice, FALSE, SET_IN_GAME },
{ "cond_glowhands", &condtests[bl_glowhands].choice, FALSE, SET_IN_GAME },
{ "cond_grab", &condtests[bl_grab].choice, FALSE, SET_IN_GAME },
{ "cond_hallu", &condtests[bl_hallu].choice, FALSE, SET_IN_GAME },
{ "cond_held", &condtests[bl_held].choice, FALSE, SET_IN_GAME },
{ "cond_ice" , &condtests[bl_icy].choice, FALSE, SET_IN_GAME },
{ "cond_iron", &condtests[bl_elf_iron].choice, FALSE, SET_IN_GAME },
{ "cond_lava", &condtests[bl_inlava].choice, FALSE, SET_IN_GAME },
{ "cond_lev", &condtests[bl_lev].choice, FALSE, SET_IN_GAME },
{ "cond_unconscious", &condtests[bl_unconsc].choice, FALSE, SET_IN_GAME },
{ "cond_paralyze", &condtests[bl_parlyz].choice, FALSE, SET_IN_GAME },
{ "cond_ride", &condtests[bl_ride].choice, FALSE, SET_IN_GAME },
{ "cond_sleep" , &condtests[bl_sleeping].choice, FALSE, SET_IN_GAME },
{ "cond_slime", &condtests[bl_slime].choice, FALSE, SET_IN_GAME },
{ "cond_slip", &condtests[bl_slippery].choice, FALSE, SET_IN_GAME },
{ "cond_stone", &condtests[bl_stone].choice, FALSE, SET_IN_GAME },
{ "cond_strngl", &condtests[bl_strngl].choice, FALSE, SET_IN_GAME },
{ "cond_stun", &condtests[bl_stun].choice, FALSE, SET_IN_GAME },
{ "cond_submerged" , &condtests[bl_submerged].choice, FALSE, SET_IN_GAME },
{ "cond_termIll", &condtests[bl_termill].choice, FALSE, SET_IN_GAME },
{ "cond_tethered", &condtests[bl_tethered].choice, FALSE, SET_IN_GAME },
{ "cond_trap", &condtests[bl_trapped].choice, FALSE, SET_IN_GAME },
{ "cond_woundedl", &condtests[bl_woundedl].choice, FALSE, 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) || defined(X11_GRAPHICS)
@@ -703,7 +732,7 @@ initoptions_init()
if (boolopt[i].addr)
*(boolopt[i].addr) = boolopt[i].initvalue;
}
condopt((boolean *) 0, 0); /* make the choices match defaults */
#ifdef SYSFLAGS
Strcpy(sysflags.sysflagsid, "sysflags");
sysflags.sysflagsid[9] = (char) sizeof (struct sysflag);
@@ -4089,6 +4118,9 @@ boolean tinitial, tfrom_file;
map if ascii map isn't supported? */
iflags.wc_ascii_map = negated;
}
if (!strncmpi(opts, "cond_", sizeof "cond_" - 1)) {
condopt(boolopt[i].addr, negated);
}
/* only do processing below if setting with doset() */
if (g.opt_initial)
return retval;

View File

@@ -972,9 +972,9 @@ curs_HPbar(char *text, /* pre-padded with trailing spaces if short */
waddch(win, ']');
}
/* valid_conditions[] is used primarily for parsing hilite_status rules, but
/* conditions[] is used primarily for parsing hilite_status rules, but
we can use it for condition names and mask bits, avoiding duplication */
extern const struct condmap valid_conditions[]; /* botl.c */
extern const struct conditions_t conditions[]; /* botl.c */
static void
curs_stat_conds(int vert_cond, /* 0 => horizontal, 1 => vertical */
@@ -996,9 +996,9 @@ curs_stat_conds(int vert_cond, /* 0 => horizontal, 1 => vertical */
if (nohilite)
*nohilite = TRUE; /* assume ok */
for (i = 0; i < BL_MASK_BITS; ++i) {
bitmsk = valid_conditions[i].bitmask;
bitmsk = conditions[i].mask;
if (curses_condition_bits & bitmsk) {
Strcpy(condnam, valid_conditions[i].id);
Strcpy(condnam, conditions[i].text[0]);
Strcat(strcat(condbuf, " "), upstart(condnam));
#ifdef STATUS_HILITES
if (nohilite && *nohilite
@@ -1024,9 +1024,9 @@ curs_stat_conds(int vert_cond, /* 0 => horizontal, 1 => vertical */
cond_bits = curses_condition_bits;
/* show active conditions directly; for vertical, three per line */
for (i = 0; i < BL_MASK_BITS; ++i) {
bitmsk = valid_conditions[i].bitmask;
bitmsk = conditions[i].mask;
if (cond_bits & bitmsk) {
Strcpy(condnam, valid_conditions[i].id);
Strcpy(condnam, conditions[i].text[0]);
cndlen = 1 + (int) strlen(condnam); /* count leading space */
if (!do_vert) {
getyx(win, cy, cx);

View File

@@ -3691,25 +3691,8 @@ static unsigned long *tty_colormasks;
static long tty_condition_bits;
static struct tty_status_fields tty_status[2][MAXBLSTATS]; /* 2: NOW,BEFORE */
static int hpbar_percent, hpbar_color;
static struct condition_t {
long mask;
const char *text[3]; /* 3: potential display vals, progressively shorter */
} conditions[] = {
/* The sequence order of these matters */
{ BL_MASK_STONE, { "Stone", "Ston", "Sto" } },
{ BL_MASK_SLIME, { "Slime", "Slim", "Slm" } },
{ BL_MASK_STRNGL, { "Strngl", "Stngl", "Str" } },
{ BL_MASK_FOODPOIS, { "FoodPois", "Fpois", "Poi" } },
{ BL_MASK_TERMILL, { "TermIll" , "Ill", "Ill" } },
{ BL_MASK_BLIND, { "Blind", "Blnd", "Bl" } },
{ BL_MASK_DEAF, { "Deaf", "Def", "Df" } },
{ BL_MASK_STUN, { "Stun", "Stun", "St" } },
{ BL_MASK_CONF, { "Conf", "Cnf", "Cf" } },
{ BL_MASK_HALLU, { "Hallu", "Hal", "Hl" } },
{ BL_MASK_LEV, { "Lev", "Lev", "Lv" } },
{ BL_MASK_FLY, { "Fly", "Fly", "Fl" } },
{ BL_MASK_RIDE, { "Ride", "Rid", "Rd" } },
};
extern const struct conditions_t conditions[CONDITION_COUNT];
static const char *encvals[3][6] = {
{ "", "Burdened", "Stressed", "Strained", "Overtaxed", "Overloaded" },
{ "", "Burden", "Stress", "Strain", "Overtax", "Overload" },
@@ -3833,19 +3816,36 @@ boolean enable;
* -- ptr is usually a "char *", unless fldindex is BL_CONDITION.
* If fldindex is BL_CONDITION, then ptr is a long value with
* any or none of the following bits set (from botl.h):
* BL_MASK_STONE 0x00000001L
* BL_MASK_SLIME 0x00000002L
* BL_MASK_STRNGL 0x00000004L
* BL_MASK_FOODPOIS 0x00000008L
* BL_MASK_TERMILL 0x00000010L
* BL_MASK_BLIND 0x00000020L
* BL_MASK_DEAF 0x00000040L
* BL_MASK_STUN 0x00000080L
* BL_MASK_CONF 0x00000100L
* BL_MASK_HALLU 0x00000200L
* BL_MASK_LEV 0x00000400L
* BL_MASK_FLY 0x00000800L
* BL_MASK_RIDE 0x00001000L
* BL_MASK_BAREH 0x00000001L
* BL_MASK_BLIND 0x00000002L
* BL_MASK_BUSY 0x00000004L
* BL_MASK_CONF 0x00000008L
* BL_MASK_DEAF 0x00000010L
* BL_MASK_ELF_IRON 0x00000020L
* BL_MASK_FLY 0x00000040L
* BL_MASK_FOODPOIS 0x00000080L
* BL_MASK_GLOWHANDS 0x00000100L
* BL_MASK_GRAB 0x00000200L
* BL_MASK_HALLU 0x00000400L
* BL_MASK_HELD 0x00000800L
* BL_MASK_ICY 0x00001000L
* BL_MASK_INLAVA 0x00002000L
* BL_MASK_LEV 0x00004000L
* BL_MASK_PARLYZ 0x00008000L
* BL_MASK_RIDE 0x00010000L
* BL_MASK_SLEEPING 0x00020000L
* BL_MASK_SLIME 0x00040000L
* BL_MASK_SLIPPERY 0x00080000L
* BL_MASK_STONE 0x00100000L
* BL_MASK_STRNGL 0x00200000L
* BL_MASK_STUN 0x00400000L
* BL_MASK_SUBMERGED 0x00800000L
* BL_MASK_TERMILL 0x01000000L
* BL_MASK_TETHERED 0x02000000L
* BL_MASK_TRAPPED 0x04000000L
* BL_MASK_UNCONSC 0x08000000L
* BL_MASK_WOUNDEDL 0x10000000L
*
* -- The value passed for BL_GOLD usually includes an encoded leading
* symbol for GOLD "\GXXXXNNNN:nnn". If the window port needs to use
* the textual gold amount without the leading "$:" the port will