1 /* NetHack 3.6 botl.c $NHDT-Date: 1469930895 2016/07/31 02:08:15 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.75 $ */
2 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3 /* NetHack may be freely redistributed. See license for details. */
8 extern const char *hu_stat
[]; /* defined in eat.c */
10 const char *const enc_stat
[] = { "", "Burdened", "Stressed",
11 "Strained", "Overtaxed", "Overloaded" };
13 STATIC_OVL NEARDATA
int mrank_sz
= 0; /* loaded by max_rank_sz (from u_init) */
14 STATIC_DCL
const char *NDECL(rank
);
16 #if !defined(STATUS_VIA_WINDOWPORT) || defined(DUMPLOG)
21 static char newbot1
[BUFSZ
];
25 Strcpy(newbot1
, plname
);
26 if ('a' <= newbot1
[0] && newbot1
[0] <= 'z')
27 newbot1
[0] += 'A' - 'a';
29 Sprintf(nb
= eos(newbot1
), " the ");
35 Strcpy(mbot
, mons
[u
.umonnum
].mname
);
36 while (mbot
[k
] != 0) {
37 if ((k
== 0 || (k
> 0 && mbot
[k
- 1] == ' ')) && 'a' <= mbot
[k
]
42 Strcpy(nb
= eos(nb
), mbot
);
44 Strcpy(nb
= eos(nb
), rank());
46 Sprintf(nb
= eos(nb
), " ");
48 j
= (int) ((nb
+ 2) - newbot1
); /* strlen(newbot1) but less computation */
50 Sprintf(nb
= eos(nb
), "%*s", i
- j
, " "); /* pad with spaces */
51 if (ACURR(A_STR
) > 18) {
52 if (ACURR(A_STR
) > STR18(100))
53 Sprintf(nb
= eos(nb
), "St:%2d ", ACURR(A_STR
) - 100);
54 else if (ACURR(A_STR
) < STR18(100))
55 Sprintf(nb
= eos(nb
), "St:18/%02d ", ACURR(A_STR
) - 18);
57 Sprintf(nb
= eos(nb
), "St:18/** ");
59 Sprintf(nb
= eos(nb
), "St:%-1d ", ACURR(A_STR
));
60 Sprintf(nb
= eos(nb
), "Dx:%-1d Co:%-1d In:%-1d Wi:%-1d Ch:%-1d",
61 ACURR(A_DEX
), ACURR(A_CON
), ACURR(A_INT
), ACURR(A_WIS
),
64 (u
.ualign
.type
== A_CHAOTIC
)
66 : (u
.ualign
.type
== A_NEUTRAL
) ? " Neutral" : " Lawful");
69 Sprintf(nb
= eos(nb
), " S:%ld", botl_score());
77 static char newbot2
[BUFSZ
], /* MAXCO: botl.h */
78 /* dungeon location (and gold), hero health (HP, PW, AC),
79 experience (HD if poly'd, else Exp level and maybe Exp points),
80 time (in moves), varying number of status conditions */
81 dloc
[QBUFSZ
], hlth
[QBUFSZ
], expr
[QBUFSZ
], tmmv
[QBUFSZ
], cond
[QBUFSZ
];
83 unsigned dln
, dx
, hln
, xln
, tln
, cln
;
88 * Various min(x,9999)'s are to avoid having excessive values
89 * violate the field width assumptions in botl.h and should not
90 * impact normal play. Particularly 64-bit long for gold which
91 * could require many more digits if someone figures out a way
92 * to get and carry a really large (or negative) amount of it.
93 * Turn counter is also long, but we'll risk that.
96 /* dungeon location plus gold */
97 (void) describe_level(dloc
); /* includes at least one trailing space */
98 if ((money
= money_cnt(invent
)) < 0L)
99 money
= 0L; /* ought to issue impossible() and then discard gold */
100 Sprintf(eos(dloc
), "%s:%-2ld", /* strongest hero can lift ~300000 gold */
101 iflags
.in_dumplog
? "$" : encglyph(objnum_to_glyph(GOLD_PIECE
)),
102 min(money
, 999999L));
104 /* '$' encoded as \GXXXXNNNN is 9 chars longer than display will need */
105 dx
= strstri(dloc
, "\\G") ? 9 : 0;
107 /* health and armor class (has trailing space for AC 0..9) */
108 hp
= Upolyd
? u
.mh
: u
.uhp
;
109 hpmax
= Upolyd
? u
.mhmax
: u
.uhpmax
;
112 Sprintf(hlth
, "HP:%d(%d) Pw:%d(%d) AC:%-2d",
113 min(hp
, 9999), min(hpmax
, 9999),
114 min(u
.uen
, 9999), min(u
.uenmax
, 9999), u
.uac
);
119 Sprintf(expr
, "HD:%d", mons
[u
.umonnum
].mlevel
);
120 else if (flags
.showexp
)
121 Sprintf(expr
, "Xp:%u/%-1ld", u
.ulevel
, u
.uexp
);
123 Sprintf(expr
, "Exp:%u", u
.ulevel
);
126 /* time/move counter */
128 Sprintf(tmmv
, "T:%ld", moves
);
133 /* status conditions; worst ones first */
134 cond
[0] = '\0'; /* once non-empty, cond will have a leading space */
137 * Stoned, Slimed, Strangled, and both types of Sick are all fatal
138 * unless remedied before timeout expires. Should we order them by
139 * shortest time left? [Probably not worth the effort, since it's
140 * unusual for more than one of them to apply at a time.]
143 Strcpy(nb
= eos(nb
), " Stone");
145 Strcpy(nb
= eos(nb
), " Slime");
147 Strcpy(nb
= eos(nb
), " Strngl");
149 if (u
.usick_type
& SICK_VOMITABLE
)
150 Strcpy(nb
= eos(nb
), " FoodPois");
151 if (u
.usick_type
& SICK_NONVOMITABLE
)
152 Strcpy(nb
= eos(nb
), " TermIll");
154 if (u
.uhs
!= NOT_HUNGRY
)
155 Sprintf(nb
= eos(nb
), " %s", hu_stat
[u
.uhs
]);
156 if ((cap
= near_capacity()) > UNENCUMBERED
)
157 Sprintf(nb
= eos(nb
), " %s", enc_stat
[cap
]);
159 Strcpy(nb
= eos(nb
), " Blind");
161 Strcpy(nb
= eos(nb
), " Deaf");
163 Strcpy(nb
= eos(nb
), " Stun");
165 Strcpy(nb
= eos(nb
), " Conf");
167 Strcpy(nb
= eos(nb
), " Hallu");
168 /* levitation and flying are mutually exclusive; riding is not */
170 Strcpy(nb
= eos(nb
), " Lev");
172 Strcpy(nb
= eos(nb
), " Fly");
174 Strcpy(nb
= eos(nb
), " Ride");
178 * Put the pieces together. If they all fit, keep the traditional
179 * sequence. Otherwise, move least important parts to the end in
180 * case the interface side of things has to truncate. Note that
181 * dloc[] contains '$' encoded in ten character sequence \GXXXXNNNN
182 * so we want to test its display length rather than buffer length.
184 * We don't have an actual display limit here, so have to go by the
185 * width of the map. Since we're reordering rather than truncating,
186 * wider displays can still show wider status than the map if the
187 * interface supports that.
189 if ((dln
- dx
) + 1 + hln
+ 1 + xln
+ 1 + tln
+ 1 + cln
<= COLNO
) {
190 Sprintf(newbot2
, "%s %s %s %s %s", dloc
, hlth
, expr
, tmmv
, cond
);
192 if (dln
+ 1 + hln
+ 1 + xln
+ 1 + tln
+ 1 + cln
+ 1 > MAXCO
) {
193 panic("bot2: second status line exceeds MAXCO (%u > %d)",
194 (dln
+ 1 + hln
+ 1 + xln
+ 1 + tln
+ 1 + cln
+ 1), MAXCO
);
195 } else if ((dln
- dx
) + 1 + hln
+ 1 + xln
+ 1 + cln
<= COLNO
) {
196 Sprintf(newbot2
, "%s %s %s %s %s", dloc
, hlth
, expr
, cond
, tmmv
);
197 } else if ((dln
- dx
) + 1 + hln
+ 1 + cln
<= COLNO
) {
198 Sprintf(newbot2
, "%s %s %s %s %s", dloc
, hlth
, cond
, expr
, tmmv
);
200 Sprintf(newbot2
, "%s %s %s %s %s", hlth
, cond
, dloc
, expr
, tmmv
);
202 /* only two or three consecutive spaces available to squeeze out */
208 #ifndef STATUS_VIA_WINDOWPORT
212 if (youmonst
.data
&& iflags
.status_updates
) {
213 curs(WIN_STATUS
, 1, 0);
214 putstr(WIN_STATUS
, 0, do_statusline1());
215 curs(WIN_STATUS
, 1, 1);
216 putmixed(WIN_STATUS
, 0, do_statusline2());
218 context
.botl
= context
.botlx
= 0;
220 #endif /* !STATUS_VIA_WINDOWPORT */
222 #endif /* !STATUS_VIA_WINDOWPORT || DUMPLOG */
224 /* convert experience level (1..30) to rank index (0..8) */
229 return (xlev
<= 2) ? 0 : (xlev
<= 30) ? ((xlev
+ 2) / 4) : 8;
232 #if 0 /* not currently needed */
233 /* convert rank index (0..8) to experience level (1..30) */
238 return (rank
<= 0) ? 1 : (rank
<= 8) ? ((rank
* 4) - 2) : 30;
243 rank_of(lev
, monnum
, female
)
248 register const struct Role
*role
;
252 for (role
= roles
; role
->name
.m
; role
++)
253 if (monnum
== role
->malenum
|| monnum
== role
->femalenum
)
259 for (i
= xlev_to_rank((int) lev
); i
>= 0; i
--) {
260 if (female
&& role
->rank
[i
].f
)
261 return role
->rank
[i
].f
;
263 return role
->rank
[i
].m
;
266 /* Try the role name, instead */
267 if (female
&& role
->name
.f
)
269 else if (role
->name
.m
)
274 STATIC_OVL
const char *
277 return rank_of(u
.ulevel
, Role_switch
, flags
.female
);
281 title_to_mon(str
, rank_indx
, title_length
)
283 int *rank_indx
, *title_length
;
287 /* Loop through each of the roles */
288 for (i
= 0; roles
[i
].name
.m
; i
++)
289 for (j
= 0; j
< 9; j
++) {
290 if (roles
[i
].rank
[j
].m
291 && !strncmpi(str
, roles
[i
].rank
[j
].m
,
292 strlen(roles
[i
].rank
[j
].m
))) {
296 *title_length
= strlen(roles
[i
].rank
[j
].m
);
297 return roles
[i
].malenum
;
299 if (roles
[i
].rank
[j
].f
300 && !strncmpi(str
, roles
[i
].rank
[j
].f
,
301 strlen(roles
[i
].rank
[j
].f
))) {
305 *title_length
= strlen(roles
[i
].rank
[j
].f
);
306 return (roles
[i
].femalenum
!= NON_PM
) ? roles
[i
].femalenum
316 register int i
, r
, maxr
= 0;
317 for (i
= 0; i
< 9; i
++) {
318 if (urole
.rank
[i
].m
&& (r
= strlen(urole
.rank
[i
].m
)) > maxr
)
320 if (urole
.rank
[i
].f
&& (r
= strlen(urole
.rank
[i
].f
)) > maxr
)
331 long deepest
= deepest_lev_reached(FALSE
);
334 utotal
= money_cnt(invent
) + hidden_gold();
335 if ((utotal
-= u
.umoney0
) < 0L)
337 utotal
+= u
.urexp
+ (50 * (deepest
- 1))
338 + (deepest
> 30 ? 10000 : deepest
> 20 ? 1000 * (deepest
- 20) : 0);
339 if (utotal
< u
.urexp
)
340 utotal
= LONG_MAX
; /* wrap around */
343 #endif /* SCORE_ON_BOTL */
345 /* provide the name of the current level for display by various ports */
352 /* TODO: Add in dungeon name */
354 Sprintf(buf
, "%s ", dungeons
[u
.uz
.dnum
].dname
);
355 else if (In_quest(&u
.uz
))
356 Sprintf(buf
, "Home %d ", dunlev(&u
.uz
));
357 else if (In_endgame(&u
.uz
))
358 Sprintf(buf
, Is_astralevel(&u
.uz
) ? "Astral Plane " : "End Game ");
360 /* ports with more room may expand this one */
361 Sprintf(buf
, "Dlvl:%-2d ", depth(&u
.uz
));
367 #ifdef STATUS_VIA_WINDOWPORT
368 /* =======================================================================*/
370 /* structure that tracks the status details in the core */
377 enum statusfields idxmax
;
378 enum statusfields fld
;
382 STATIC_DCL
void NDECL(init_blstats
);
383 STATIC_DCL
char *FDECL(anything_to_s
, (char *, anything
*, int));
384 STATIC_OVL
int FDECL(percentage
, (struct istat_s
*, struct istat_s
*));
385 STATIC_OVL
int FDECL(compare_blstats
, (struct istat_s
*, struct istat_s
*));
386 #ifdef STATUS_HILITES
387 STATIC_DCL
void FDECL(s_to_anything
, (anything
*, char *, int));
388 STATIC_DCL boolean
FDECL(assign_hilite
, (char *, char *, char *, char *,
390 STATIC_DCL
const char *FDECL(clridx_to_s
, (char *, int));
393 /* If entries are added to this, botl.h will require updating too */
394 STATIC_DCL
struct istat_s initblstats
[MAXBLSTATS
] = {
395 { 0L, ANY_STR
, { (genericptr_t
) 0 }, (char *) 0, 80, 0, BL_TITLE
},
396 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_STR
},
397 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_DX
},
398 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_CO
},
399 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_IN
},
400 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_WI
},
401 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_CH
},
402 { 0L, ANY_STR
, { (genericptr_t
) 0 }, (char *) 0, 40, 0, BL_ALIGN
},
403 { 0L, ANY_LONG
, { (genericptr_t
) 0 }, (char *) 0, 20, 0, BL_SCORE
},
404 { 0L, ANY_LONG
, { (genericptr_t
) 0 }, (char *) 0, 20, 0, BL_CAP
},
405 { 0L, ANY_LONG
, { (genericptr_t
) 0 }, (char *) 0, 30, 0, BL_GOLD
},
406 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, BL_ENEMAX
, BL_ENE
},
407 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_ENEMAX
},
408 { 0L, ANY_LONG
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_XP
},
409 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_AC
},
410 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_HD
},
411 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 20, 0, BL_TIME
},
412 { 0L, ANY_UINT
, { (genericptr_t
) 0 }, (char *) 0, 40, 0, BL_HUNGER
},
413 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, BL_HPMAX
, BL_HP
},
414 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_HPMAX
},
415 { 0L, ANY_STR
, { (genericptr_t
) 0 }, (char *) 0, 80, 0, BL_LEVELDESC
},
416 { 0L, ANY_LONG
, { (genericptr_t
) 0 }, (char *) 0, 20, 0, BL_EXP
},
418 { (genericptr_t
) 0 }, (char *) 0, 0, 0, BL_CONDITION
}
421 struct istat_s blstats
[2][MAXBLSTATS
];
422 static boolean blinit
= FALSE
, update_all
= FALSE
;
429 static int idx
= 0, idx_p
, idxmax
;
433 struct istat_s
*curr
, *prev
;
434 boolean valset
[MAXBLSTATS
], chgval
= FALSE
, updated
= FALSE
;
437 panic("bot before init.");
438 if (!youmonst
.data
|| !iflags
.status_updates
) {
439 context
.botl
= context
.botlx
= 0;
445 idx
= 1 - idx
; /* 0 -> 1, 1 -> 0 */
447 /* clear the "value set" indicators */
448 (void) memset((genericptr_t
) valset
, 0, MAXBLSTATS
* sizeof (boolean
));
451 * Note: min(x,9999) - we enforce the same maximum on hp, maxhp,
452 * pw, maxpw, and gold as basic status formatting so that the two
453 * modes of status display don't produce different information.
457 * Player name and title.
459 Strcpy(nb
= buf
, plname
);
460 nb
[0] = highc(nb
[0]);
462 Sprintf(nb
= eos(nb
), " the ");
464 for (i
= 0, nb
= strcpy(eos(nb
), mons
[u
.umonnum
].mname
); nb
[i
]; i
++)
465 if (i
== 0 || nb
[i
- 1] == ' ')
466 nb
[i
] = highc(nb
[i
]);
468 Strcpy(nb
= eos(nb
), rank());
469 Sprintf(blstats
[idx
][BL_TITLE
].val
, "%-29s", buf
);
470 valset
[BL_TITLE
] = TRUE
; /* indicate val already set */
474 blstats
[idx
][BL_STR
].a
.a_int
= ACURR(A_STR
);
475 if (ACURR(A_STR
) > 18) {
476 if (ACURR(A_STR
) > STR18(100))
477 Sprintf(buf
, "%2d", ACURR(A_STR
) - 100);
478 else if (ACURR(A_STR
) < STR18(100))
479 Sprintf(buf
, "18/%02d", ACURR(A_STR
) - 18);
481 Sprintf(buf
, "18/**");
483 Sprintf(buf
, "%-1d", ACURR(A_STR
));
484 Strcpy(blstats
[idx
][BL_STR
].val
, buf
);
485 valset
[BL_STR
] = TRUE
; /* indicate val already set */
487 /* Dexterity, constitution, intelligence, wisdom, charisma. */
488 blstats
[idx
][BL_DX
].a
.a_int
= ACURR(A_DEX
);
489 blstats
[idx
][BL_CO
].a
.a_int
= ACURR(A_CON
);
490 blstats
[idx
][BL_IN
].a
.a_int
= ACURR(A_INT
);
491 blstats
[idx
][BL_WI
].a
.a_int
= ACURR(A_WIS
);
492 blstats
[idx
][BL_CH
].a
.a_int
= ACURR(A_CHA
);
495 Strcpy(blstats
[idx
][BL_ALIGN
].val
, (u
.ualign
.type
== A_CHAOTIC
)
497 : (u
.ualign
.type
== A_NEUTRAL
)
502 blstats
[idx
][BL_SCORE
].a
.a_long
=
511 i
= Upolyd
? u
.mh
: u
.uhp
;
514 blstats
[idx
][BL_HP
].a
.a_int
= min(i
, 9999);
515 i
= Upolyd
? u
.mhmax
: u
.uhpmax
;
516 blstats
[idx
][BL_HPMAX
].a
.a_int
= min(i
, 9999);
519 (void) describe_level(blstats
[idx
][BL_LEVELDESC
].val
);
520 valset
[BL_LEVELDESC
] = TRUE
; /* indicate val already set */
523 if ((money
= money_cnt(invent
)) < 0L)
524 money
= 0L; /* ought to issue impossible() and then discard gold */
525 blstats
[idx
][BL_GOLD
].a
.a_long
= min(money
, 999999L);
527 * The tty port needs to display the current symbol for gold
528 * as a field header, so to accommodate that we pass gold with
529 * that already included. If a window port needs to use the text
530 * gold amount without the leading "$:" the port will have to
531 * skip past ':' to the value pointer it was passed in status_update()
532 * for the BL_GOLD case.
534 * Another quirk of BL_GOLD is that the field display may have
535 * changed if a new symbol set was loaded, or we entered or left
538 * The currency prefix is encoded as ten character \GXXXXNNNN
541 Sprintf(blstats
[idx
][BL_GOLD
].val
, "%s:%ld",
542 encglyph(objnum_to_glyph(GOLD_PIECE
)),
543 blstats
[idx
][BL_GOLD
].a
.a_long
);
544 valset
[BL_GOLD
] = TRUE
; /* indicate val already set */
546 /* Power (magical energy) */
547 blstats
[idx
][BL_ENE
].a
.a_int
= min(u
.uen
, 9999);
548 blstats
[idx
][BL_ENEMAX
].a
.a_int
= min(u
.uenmax
, 9999);
551 blstats
[idx
][BL_AC
].a
.a_int
= u
.uac
;
553 /* Monster level (if Upolyd) */
554 blstats
[idx
][BL_HD
].a
.a_int
= Upolyd
? mons
[u
.umonnum
].mlevel
: 0;
557 blstats
[idx
][BL_XP
].a
.a_int
= u
.ulevel
;
558 blstats
[idx
][BL_EXP
].a
.a_int
= u
.uexp
;
561 blstats
[idx
][BL_TIME
].a
.a_long
= moves
;
564 blstats
[idx
][BL_HUNGER
].a
.a_uint
= u
.uhs
;
565 Strcpy(blstats
[idx
][BL_HUNGER
].val
,
566 (u
.uhs
!= NOT_HUNGRY
) ? hu_stat
[u
.uhs
] : "");
567 valset
[BL_HUNGER
] = TRUE
;
569 /* Carrying capacity */
570 cap
= near_capacity();
571 blstats
[idx
][BL_CAP
].a
.a_int
= cap
;
572 Strcpy(blstats
[idx
][BL_CAP
].val
,
573 (cap
> UNENCUMBERED
) ? enc_stat
[cap
] : "");
574 valset
[BL_CAP
] = TRUE
;
577 blstats
[idx
][BL_CONDITION
].a
.a_ulong
= 0L;
579 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_STONE
;
581 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_SLIME
;
583 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_STRNGL
;
584 if (Sick
&& (u
.usick_type
& SICK_VOMITABLE
) != 0)
585 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_FOODPOIS
;
586 if (Sick
&& (u
.usick_type
& SICK_NONVOMITABLE
) != 0)
587 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_TERMILL
;
589 * basic formatting puts hunger status and encumbrance here
592 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_BLIND
;
594 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_DEAF
;
596 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_STUN
;
598 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_CONF
;
600 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_HALLU
;
601 /* levitation and flying are mututally exclusive */
603 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_LEV
;
605 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_FLY
;
607 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_RIDE
;
610 * Now pass the changed values to window port.
612 for (i
= 0; i
< MAXBLSTATS
; i
++) {
613 if (((i
== BL_SCORE
) && !flags
.showscore
)
614 || ((i
== BL_EXP
) && !flags
.showexp
)
615 || ((i
== BL_TIME
) && !flags
.time
)
616 || ((i
== BL_HD
) && !Upolyd
)
617 || ((i
== BL_XP
|| i
== BL_EXP
) && Upolyd
))
619 anytype
= blstats
[idx
][i
].anytype
;
620 curr
= &blstats
[idx
][i
];
621 prev
= &blstats
[idx_p
][i
];
624 || ((chg
= compare_blstats(prev
, curr
)) != 0)
625 || ((chgval
= (valset
[i
]
626 && strcmp(blstats
[idx
][i
].val
,
627 blstats
[idx_p
][i
].val
))) != 0)) {
628 idxmax
= blstats
[idx
][i
].idxmax
;
629 pc
= (idxmax
) ? percentage(curr
, &blstats
[idx
][idxmax
]) : 0;
631 (void) anything_to_s(curr
->val
, &curr
->a
, anytype
);
632 if (anytype
!= ANY_MASK32
) {
633 status_update(i
, (genericptr_t
) curr
->val
,
634 valset
[i
] ? chgval
: chg
, pc
);
636 /* send pointer to mask */
637 status_update(i
, (genericptr_t
) &curr
->a
.a_ulong
, chg
, 0);
643 * It is possible to get here, with nothing having been pushed
644 * to the window port, when none of the info has changed. In that
645 * case, we need to force a call to status_update() when
646 * context.botlx is set. The tty port in particular has a problem
647 * if that isn't done, since it sets context.botlx when a menu or
648 * text display obliterates the status line.
650 * To work around it, we call status_update() with fictitious
651 * index of BL_FLUSH (-1).
653 if ((context
.botlx
&& !updated
)
654 || windowprocs
.win_status_update
== genl_status_update
)
655 status_update(BL_FLUSH
, (genericptr_t
) 0, 0, 0);
657 context
.botl
= context
.botlx
= 0;
662 status_initialize(reassessment
)
664 reassessment
; /* TRUE = just reassess fields w/o other initialization*/
667 const char *fieldfmt
= (const char *) 0;
668 const char *fieldname
= (const char *) 0;
672 (*windowprocs
.win_status_init
)();
674 #ifdef STATUS_HILITES
675 status_notify_windowport(TRUE
);
678 for (i
= 0; i
< MAXBLSTATS
; ++i
) {
679 enum statusfields fld
= initblstats
[i
].fld
;
685 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
689 fieldname
= "strength";
690 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
694 fieldname
= "dexterity";
695 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
699 fieldname
= "constitution";
700 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
704 fieldname
= "intelligence";
705 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
709 fieldname
= "wisdom";
710 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
714 fieldname
= "charisma";
715 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
719 fieldname
= "alignment";
720 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
725 status_enablefield(fld
, fieldname
, fieldfmt
,
726 (!flags
.showscore
) ? FALSE
: TRUE
);
730 fieldname
= "carrying-capacity";
731 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
736 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
741 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
745 fieldname
= "power-max";
746 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
750 fieldname
= "experience-level";
751 status_enablefield(fld
, fieldname
, fieldfmt
,
752 (Upolyd
) ? FALSE
: TRUE
);
756 fieldname
= "armor-class";
757 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
762 status_enablefield(fld
, fieldname
, fieldfmt
,
763 (!Upolyd
) ? FALSE
: TRUE
);
768 status_enablefield(fld
, fieldname
, fieldfmt
,
769 (!flags
.time
) ? FALSE
: TRUE
);
773 fieldname
= "hunger";
774 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
778 fieldname
= "hitpoints";
779 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
783 fieldname
= "hitpoint-max";
784 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
788 fieldname
= "dungeon-level";
789 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
793 fieldname
= "experience";
794 status_enablefield(fld
, fieldname
, fieldfmt
,
795 (!flags
.showexp
|| Upolyd
) ? FALSE
: TRUE
);
799 fieldname
= "condition";
800 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
815 /* call the window port cleanup routine first */
816 (*windowprocs
.win_status_finish
)();
818 /* free memory that we alloc'd now */
819 for (i
= 0; i
< MAXBLSTATS
; ++i
) {
820 if (blstats
[0][i
].val
)
821 free((genericptr_t
) blstats
[0][i
].val
);
822 if (blstats
[1][i
].val
)
823 free((genericptr_t
) blstats
[1][i
].val
);
830 static boolean initalready
= FALSE
;
834 impossible("init_blstats called more than once.");
839 for (i
= BEFORE
; i
<= NOW
; ++i
) {
840 for (j
= 0; j
< MAXBLSTATS
; ++j
) {
841 blstats
[i
][j
] = initblstats
[j
];
842 blstats
[i
][j
].a
= zeroany
;
843 if (blstats
[i
][j
].valwidth
) {
844 blstats
[i
][j
].val
= (char *) alloc(blstats
[i
][j
].valwidth
);
845 blstats
[i
][j
].val
[0] = '\0';
847 blstats
[i
][j
].val
= (char *) 0;
853 anything_to_s(buf
, a
, anytype
)
863 Sprintf(buf
, "%lu", a
->a_ulong
);
866 Sprintf(buf
, "%lx", a
->a_ulong
);
869 Sprintf(buf
, "%ld", a
->a_long
);
872 Sprintf(buf
, "%d", a
->a_int
);
875 Sprintf(buf
, "%u", a
->a_uint
);
878 Sprintf(buf
, "%d", *a
->a_iptr
);
881 Sprintf(buf
, "%ld", *a
->a_lptr
);
884 Sprintf(buf
, "%lu", *a
->a_ulptr
);
887 Sprintf(buf
, "%u", *a
->a_uptr
);
889 case ANY_STR
: /* do nothing */
898 #ifdef STATUS_HILITES
901 s_to_anything(a
, buf
, anytype
)
911 a
->a_long
= atol(buf
);
914 a
->a_int
= atoi(buf
);
917 a
->a_uint
= (unsigned) atoi(buf
);
920 a
->a_ulong
= (unsigned long) atol(buf
);
924 *a
->a_iptr
= atoi(buf
);
928 *a
->a_uptr
= (unsigned) atoi(buf
);
932 *a
->a_lptr
= atol(buf
);
936 *a
->a_ulptr
= (unsigned long) atol(buf
);
939 a
->a_ulong
= (unsigned long) atol(buf
);
951 compare_blstats(bl1
, bl2
)
952 struct istat_s
*bl1
, *bl2
;
954 int anytype
, result
= 0;
957 panic("compare_blstat: bad istat pointer %s, %s",
958 fmt_ptr((genericptr_t
) bl1
), fmt_ptr((genericptr_t
) bl2
));
961 anytype
= bl1
->anytype
;
962 if ((!bl1
->a
.a_void
|| !bl2
->a
.a_void
)
963 && (anytype
== ANY_IPTR
|| anytype
== ANY_UPTR
|| anytype
== ANY_LPTR
964 || anytype
== ANY_ULPTR
)) {
965 panic("compare_blstat: invalid pointer %s, %s",
966 fmt_ptr((genericptr_t
) bl1
->a
.a_void
),
967 fmt_ptr((genericptr_t
) bl2
->a
.a_void
));
972 result
= (bl1
->a
.a_int
< bl2
->a
.a_int
)
974 : (bl1
->a
.a_int
> bl2
->a
.a_int
) ? -1 : 0;
977 result
= (*bl1
->a
.a_iptr
< *bl2
->a
.a_iptr
)
979 : (*bl1
->a
.a_iptr
> *bl2
->a
.a_iptr
) ? -1 : 0;
982 result
= (bl1
->a
.a_long
< bl2
->a
.a_long
)
984 : (bl1
->a
.a_long
> bl2
->a
.a_long
) ? -1 : 0;
987 result
= (*bl1
->a
.a_lptr
< *bl2
->a
.a_lptr
)
989 : (*bl1
->a
.a_lptr
> *bl2
->a
.a_lptr
) ? -1 : 0;
992 result
= (bl1
->a
.a_uint
< bl2
->a
.a_uint
)
994 : (bl1
->a
.a_uint
> bl2
->a
.a_uint
) ? -1 : 0;
997 result
= (*bl1
->a
.a_uptr
< *bl2
->a
.a_uptr
)
999 : (*bl1
->a
.a_uptr
> *bl2
->a
.a_uptr
) ? -1 : 0;
1002 result
= (bl1
->a
.a_ulong
< bl2
->a
.a_ulong
)
1004 : (bl1
->a
.a_ulong
> bl2
->a
.a_ulong
) ? -1 : 0;
1007 result
= (*bl1
->a
.a_ulptr
< *bl2
->a
.a_ulptr
)
1009 : (*bl1
->a
.a_ulptr
> *bl2
->a
.a_ulptr
) ? -1 : 0;
1012 if (strcmp(bl1
->val
, bl2
->val
) == 0)
1018 if (bl1
->a
.a_ulong
== bl2
->a
.a_ulong
)
1030 percentage(bl
, maxbl
)
1031 struct istat_s
*bl
, *maxbl
;
1036 if (!bl
|| !maxbl
) {
1037 impossible("percentage: bad istat pointer %s, %s",
1038 fmt_ptr((genericptr_t
) bl
), fmt_ptr((genericptr_t
) maxbl
));
1042 anytype
= bl
->anytype
;
1043 if (maxbl
->a
.a_void
) {
1046 result
= ((100 * bl
->a
.a_int
) / maxbl
->a
.a_int
);
1049 result
= (int) ((100L * bl
->a
.a_long
) / maxbl
->a
.a_long
);
1052 result
= (int) ((100U * bl
->a
.a_uint
) / maxbl
->a
.a_uint
);
1055 result
= (int) ((100UL * bl
->a
.a_ulong
) / maxbl
->a
.a_ulong
);
1058 result
= ((100 * (*bl
->a
.a_iptr
)) / (*maxbl
->a
.a_iptr
));
1061 result
= (int) ((100L * (*bl
->a
.a_lptr
)) / (*maxbl
->a
.a_lptr
));
1064 result
= (int) ((100U * (*bl
->a
.a_uptr
)) / (*maxbl
->a
.a_uptr
));
1067 result
= (int) ((100UL * (*bl
->a
.a_ulptr
)) / (*maxbl
->a
.a_ulptr
));
1075 #ifdef STATUS_HILITES
1077 /****************************************************************************/
1078 /* Core status hiliting support */
1079 /****************************************************************************/
1081 static struct fieldid_t
{
1082 const char *fieldname
;
1083 enum statusfields fldid
;
1085 {"title", BL_TITLE
},
1086 {"strength", BL_STR
},
1087 {"dexterity", BL_DX
},
1088 {"constitution", BL_CO
},
1089 {"intelligence", BL_IN
},
1091 {"charisma", BL_CH
},
1092 {"alignment", BL_ALIGN
},
1093 {"score", BL_SCORE
},
1094 {"carrying-capacity", BL_CAP
},
1097 {"power-max", BL_ENEMAX
},
1098 {"experience-level", BL_XP
},
1099 {"armor-class", BL_AC
},
1102 {"hunger", BL_HUNGER
},
1103 {"hitpoints", BL_HP
},
1104 {"hitpoints-max", BL_HPMAX
},
1105 {"dungeon-level", BL_LEVELDESC
},
1106 {"experience", BL_EXP
},
1107 {"condition", BL_CONDITION
},
1118 struct hilite_s status_hilites
[MAXBLSTATS
];
1121 * This is the parser for the hilite options
1123 * OPTION=hilite_status: hitpoints/10%/red/normal
1125 * set_hilite_status() separates each hilite entry into its 4 component
1126 * strings, then calls assign_hilite() to make the adjustments.
1129 set_status_hilites(op
, from_configfile
)
1131 boolean from_configfile
;
1133 char hsbuf
[4][QBUFSZ
];
1134 boolean rslt
, badopt
= FALSE
;
1135 int fldnum
, num
= 0, ccount
= 0;
1139 hsbuf
[0][0] = hsbuf
[1][0] = hsbuf
[2][0] = hsbuf
[3][0] = '\0';
1140 while (*op
&& fldnum
< 4 && ccount
< (QBUFSZ
- 2)) {
1144 rslt
= assign_hilite(&hsbuf
[0][0], &hsbuf
[1][0], &hsbuf
[2][0],
1145 &hsbuf
[3][0], from_configfile
);
1151 hsbuf
[0][0] = hsbuf
[1][0] = '\0';
1152 hsbuf
[2][0] = hsbuf
[3][0] = '\0';
1155 } else if (c
== '/') {
1159 hsbuf
[fldnum
][ccount
++] = c
;
1160 hsbuf
[fldnum
][ccount
] = '\0';
1164 if (fldnum
>= 2 && !badopt
) {
1165 rslt
= assign_hilite(&hsbuf
[0][0], &hsbuf
[1][0], &hsbuf
[2][0],
1166 &hsbuf
[3][0], from_configfile
);
1176 clear_status_hilites(from_configfile
)
1177 boolean from_configfile
;
1183 for (i
= 0; i
< MAXBLSTATS
; ++i
) {
1184 (void) memset((genericptr_t
) &status_hilites
[i
], 0,
1185 sizeof(struct hilite_s
));
1186 /* notify window port */
1187 if (!from_configfile
)
1188 status_threshold(i
, blstats
[0][i
].anytype
, it
, 0, 0, 0);
1193 assign_hilite(sa
, sb
, sc
, sd
, from_configfile
)
1194 char *sa
, *sb
, *sc
, *sd
;
1195 boolean from_configfile
;
1198 int i
= -1, dt
= -1, idx
= -1;
1199 int coloridx
[2] = { -1, -1 };
1200 boolean inverse
[2] = { FALSE
, FALSE
};
1201 boolean bold
[2] = { FALSE
, FALSE
};
1202 boolean normal
[2] = { 0, 0 };
1203 boolean percent
= FALSE
, down_up
= FALSE
, changed
= FALSE
;
1205 enum statusfields fld
= BL_FLUSH
;
1206 threshold
.a_void
= 0;
1209 * hilite_status: hitpoints/10%/red/normal
1212 /* field name to statusfield */
1213 for (i
= 0; sa
&& i
< SIZE(fieldids
); ++i
) {
1214 if (strcmpi(sa
, fieldids
[i
].fieldname
) == 0) {
1216 fld
= fieldids
[i
].fldid
;
1222 status_hilites
[idx
].set
= FALSE
; /* mark it "unset" */
1227 if ((strcmpi(sb
, "updown") == 0) || (strcmpi(sb
, "downup") == 0)
1228 || (strcmpi(sb
, "up") == 0) || (strcmpi(sb
, "down") == 0)) {
1230 } else if ((strcmpi(sb
, "changed") == 0)
1231 && (fld
== BL_TITLE
|| fld
== BL_ALIGN
|| fld
== BL_LEVELDESC
1232 || fld
== BL_CONDITION
)) {
1233 changed
= TRUE
; /* changed is only thing allowed */
1241 } else if (!index("0123456789", *tmp
))
1245 if (strlen(sb
) > 0) {
1246 dt
= blstats
[0][idx
].anytype
;
1249 (void) s_to_anything(&threshold
, sb
, dt
);
1252 if (percent
&& (threshold
.a_int
< 1 || threshold
.a_int
> 100))
1254 if (!threshold
.a_void
&& (strcmp(sb
, "0") != 0))
1259 for (i
= 0; i
< 2; ++i
) {
1264 break; /* sc is mandatory; sd is not */
1267 if (strcmpi(how
, "bold") == 0) {
1269 } else if (strcmpi(how
, "inverse") == 0) {
1271 } else if (strcmpi(how
, "normal") == 0) {
1274 int k
= match_str2clr(how
);
1282 /* Assign the values */
1284 for (i
= 0; i
< 2; ++i
) {
1286 status_hilites
[idx
].coloridx
[i
] = BL_HILITE_INVERSE
;
1288 status_hilites
[idx
].coloridx
[i
] = BL_HILITE_BOLD
;
1289 else if (coloridx
[i
])
1290 status_hilites
[idx
].coloridx
[i
] = coloridx
[i
];
1292 status_hilites
[idx
].coloridx
[i
] = BL_HILITE_NONE
;
1296 status_hilites
[idx
].behavior
= BL_TH_VAL_PERCENTAGE
;
1298 status_hilites
[idx
].behavior
= BL_TH_UPDOWN
;
1299 else if (threshold
.a_void
)
1300 status_hilites
[idx
].behavior
= BL_TH_VAL_ABSOLUTE
;
1302 status_hilites
[idx
].behavior
= BL_TH_NONE
;
1304 if (status_hilites
[idx
].behavior
!= BL_TH_NONE
) {
1305 status_hilites
[idx
].threshold
= threshold
;
1306 status_hilites
[idx
].set
= TRUE
;
1308 status_hilites
[idx
].anytype
= dt
;
1310 /* Now finally, we notify the window port */
1311 if (!from_configfile
)
1312 status_threshold(idx
, status_hilites
[idx
].anytype
,
1313 status_hilites
[idx
].threshold
,
1314 status_hilites
[idx
].behavior
,
1315 status_hilites
[idx
].coloridx
[0],
1316 status_hilites
[idx
].coloridx
[1]);
1323 status_notify_windowport(all
)
1330 for (idx
= 0; idx
< MAXBLSTATS
; ++idx
) {
1331 if (status_hilites
[idx
].set
)
1332 status_threshold(idx
, status_hilites
[idx
].anytype
,
1333 status_hilites
[idx
].threshold
,
1334 status_hilites
[idx
].behavior
,
1335 status_hilites
[idx
].coloridx
[0],
1336 status_hilites
[idx
].coloridx
[1]);
1338 status_threshold(idx
, blstats
[0][idx
].anytype
, it
, 0, 0, 0);
1344 * get_status_hilites
1346 * Returns a string containing all the status hilites in the
1347 * same format that is used to specify a status hilite preference
1348 * in the config file.
1351 get_status_hilites(buf
, bufsiz
)
1355 int i
, j
, k
, coloridx
;
1356 const char *text
= (char *) 0;
1357 char tmp
[BUFSZ
], colorname
[BUFSZ
];
1358 boolean val_percentage
, val_absolute
, up_down
;
1359 boolean added_one
= FALSE
;
1365 bufsiz
--; /* required trailing null */
1366 for (i
= 0; i
< MAXBLSTATS
; ++i
) {
1367 val_percentage
= val_absolute
= up_down
= FALSE
;
1368 if (status_hilites
[i
].set
) {
1375 k
= strlen(fieldids
[i
].fieldname
);
1377 Strcat(buf
, fieldids
[i
].fieldname
);
1384 if (status_hilites
[i
].behavior
== BL_TH_VAL_PERCENTAGE
) {
1385 val_percentage
= TRUE
;
1386 } else if (status_hilites
[i
].behavior
== BL_TH_VAL_ABSOLUTE
) {
1387 val_absolute
= TRUE
;
1388 } else if (status_hilites
[i
].behavior
== BL_TH_UPDOWN
) {
1393 if (status_hilites
[i
].behavior
!= BL_TH_UPDOWN
) {
1394 anything_to_s(tmp
, &status_hilites
[i
].threshold
,
1395 blstats
[0][i
].anytype
);
1399 if (k
< (bufsiz
- 1)) {
1402 Strcat(buf
, "%"), k
++;
1405 for (j
= 0; j
< 2; ++j
) {
1410 coloridx
= status_hilites
[i
].coloridx
[j
];
1412 if (coloridx
== BL_HILITE_BOLD
)
1414 else if (coloridx
== BL_HILITE_INVERSE
)
1421 (void) strcpy(colorname
, c_obj_colors
[coloridx
]);
1422 for (blank
= index(colorname
, ' '); blank
;
1423 blank
= index(colorname
, ' '))
1438 STATIC_OVL
const char *
1439 clridx_to_s(buf
, idx
)
1443 static const char *a
[] = { "bold", "inverse", "normal" };
1448 if (idx
< 0 && idx
>= BL_HILITE_BOLD
)
1449 Strcpy(buf
, a
[idx
+ 3]);
1450 else if (idx
>= 0 && idx
< CLR_MAX
)
1451 Strcpy(buf
, c_obj_colors
[idx
]);
1452 /* replace spaces with - */
1453 for(p
= buf
; *p
; p
++)
1454 if(*p
== ' ') *p
= '-';
1460 status_hilite_menu()
1462 int i
, j
, k
, pick_cnt
, pick_idx
, opt_idx
;
1463 menu_item
*statfield_picks
= (menu_item
*) 0;
1464 const char *fieldname
;
1465 int field_picks
[MAXBLSTATS
], res
;
1466 struct hilite_s hltemp
[MAXBLSTATS
];
1467 char buf
[BUFSZ
], thresholdbuf
[BUFSZ
], below
[BUFSZ
], above
[BUFSZ
];
1471 tmpwin
= create_nhwindow(NHW_MENU
);
1473 for (i
= 0; i
< MAXBLSTATS
; i
++) {
1474 (void) memset(&hltemp
[i
], 0, sizeof(struct hilite_s
));
1475 fieldname
= fieldids
[i
].fieldname
;
1477 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, ATR_NONE
, fieldname
,
1481 end_menu(tmpwin
, "Change hilite on which status field(s):");
1482 if ((pick_cnt
= select_menu(tmpwin
, PICK_ANY
, &statfield_picks
)) > 0) {
1483 for (pick_idx
= 0; pick_idx
< pick_cnt
; ++pick_idx
) {
1484 opt_idx
= statfield_picks
[pick_idx
].item
.a_int
- 1;
1485 field_picks
[opt_idx
] = 1;
1487 free((genericptr_t
) statfield_picks
);
1488 statfield_picks
= (menu_item
*) 0;
1490 destroy_nhwindow(tmpwin
);
1494 for (i
= 0; i
< MAXBLSTATS
; i
++) {
1495 if (field_picks
[i
]) {
1496 menu_item
*pick
= (menu_item
*) 0;
1498 Sprintf(buf
, "Threshold behavior options for %s:",
1499 fieldids
[i
].fieldname
);
1500 tmpwin
= create_nhwindow(NHW_MENU
);
1502 if (i
== BL_CONDITION
) {
1504 any
.a_int
= BL_TH_CONDITION
+ 1;
1505 add_menu(tmpwin
, NO_GLYPH
, &any
, 'c', 0, ATR_NONE
,
1506 "Condition bitmask threshold.", MENU_UNSELECTED
);
1509 any
.a_int
= BL_TH_NONE
+ 1;
1510 add_menu(tmpwin
, NO_GLYPH
, &any
, 'n', 0, ATR_NONE
, "None",
1512 if (i
!= BL_CONDITION
) {
1513 if (blstats
[0][i
].idxmax
> 0) {
1515 any
.a_int
= BL_TH_VAL_PERCENTAGE
+ 1;
1516 add_menu(tmpwin
, NO_GLYPH
, &any
, 'p', 0, ATR_NONE
,
1517 "Percentage threshold.", MENU_UNSELECTED
);
1520 any
.a_int
= BL_TH_UPDOWN
+ 1;
1521 add_menu(tmpwin
, NO_GLYPH
, &any
, 'u', 0, ATR_NONE
,
1522 "UpDown threshold.", MENU_UNSELECTED
);
1524 any
.a_int
= BL_TH_VAL_ABSOLUTE
+ 1;
1525 add_menu(tmpwin
, NO_GLYPH
, &any
, 'v', 0, ATR_NONE
,
1526 "Value threshold.", MENU_UNSELECTED
);
1528 end_menu(tmpwin
, buf
);
1529 if ((res
= select_menu(tmpwin
, PICK_ONE
, &pick
)) > 0) {
1530 hltemp
[i
].behavior
= pick
->item
.a_int
- 1;
1531 free((genericptr_t
) pick
);
1533 destroy_nhwindow(tmpwin
);
1537 if (hltemp
[i
].behavior
== BL_TH_UPDOWN
) {
1538 Sprintf(below
, "%s decreases", fieldids
[i
].fieldname
);
1539 Sprintf(above
, "%s increases", fieldids
[i
].fieldname
);
1540 } else if (hltemp
[i
].behavior
) {
1541 /* Have them enter the threshold*/
1543 buf
, "Set %s threshold to what%s?", fieldids
[i
].fieldname
,
1544 (hltemp
[i
].behavior
== BL_TH_VAL_PERCENTAGE
)
1546 : (hltemp
[i
].behavior
== BL_TH_CONDITION
) ? " mask"
1548 getlin(buf
, thresholdbuf
);
1549 if (thresholdbuf
[0] == '\033')
1551 (void) s_to_anything(&hltemp
[i
].threshold
, thresholdbuf
,
1552 blstats
[0][i
].anytype
);
1553 if (!hltemp
[i
].threshold
.a_void
)
1556 Sprintf(below
, "%s falls below %s%s", fieldids
[i
].fieldname
,
1558 (hltemp
[i
].behavior
== BL_TH_VAL_PERCENTAGE
) ? "%"
1560 Sprintf(above
, "%s rises above %s%s", fieldids
[i
].fieldname
,
1562 (hltemp
[i
].behavior
== BL_TH_VAL_PERCENTAGE
) ? "%"
1565 for (j
= 0; j
< 2 && (hltemp
[i
].behavior
!= BL_TH_NONE
); ++j
) {
1566 char prompt
[QBUFSZ
];
1567 /* j == 0 below, j == 1 above */
1568 menu_item
*pick2
= (menu_item
*) 0;
1570 Sprintf(prompt
, "Display how when %s?", j
? above
: below
);
1571 tmpwin
= create_nhwindow(NHW_MENU
);
1573 for (k
= -3; k
< CLR_MAX
; ++k
) {
1574 /* if (k == -1) continue; */
1576 any
.a_int
= (k
>= 0) ? k
+ 1 : k
;
1578 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, ATR_NONE
,
1579 c_obj_colors
[k
], MENU_UNSELECTED
);
1581 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, ATR_NONE
,
1582 "normal", MENU_UNSELECTED
);
1584 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, ATR_NONE
,
1585 "inverse", MENU_UNSELECTED
);
1587 add_menu(tmpwin
, NO_GLYPH
, &any
, 0, 0, ATR_NONE
,
1588 "bold", MENU_UNSELECTED
);
1590 end_menu(tmpwin
, prompt
);
1591 if ((res
= select_menu(tmpwin
, PICK_ONE
, &pick2
)) > 0) {
1592 hltemp
[i
].coloridx
[j
] = (pick2
->item
.a_char
> 0)
1593 ? pick2
->item
.a_int
- 1
1594 : pick2
->item
.a_int
;
1595 free((genericptr_t
) pick2
);
1597 destroy_nhwindow(tmpwin
);
1604 for (i
= 0; i
< MAXBLSTATS
; i
++) {
1605 if (field_picks
[i
]) {
1606 Sprintf(eos(buf
), "%s/%s%s/", fieldids
[i
].fieldname
,
1607 (hltemp
[i
].behavior
== BL_TH_UPDOWN
)
1609 : anything_to_s(thresholdbuf
, &hltemp
[i
].threshold
,
1610 blstats
[0][i
].anytype
),
1611 (hltemp
[i
].behavior
== BL_TH_VAL_PERCENTAGE
) ? "%" : "");
1612 /* borrow thresholdbuf for use with these last two */
1613 Sprintf(eos(buf
), "%s/",
1614 clridx_to_s(thresholdbuf
, hltemp
[i
].coloridx
[0]));
1615 Sprintf(eos(buf
), "%s ",
1616 clridx_to_s(thresholdbuf
, hltemp
[i
].coloridx
[1]));
1619 return set_status_hilites(buf
, FALSE
);
1621 #endif /*STATUS_HILITES*/
1622 #endif /*STATUS_VIA_WINDOWPORT*/