1 /* NetHack 3.6 botl.c $NHDT-Date: 1452660188 2016/01/13 04:43:08 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.70 $ */
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 #ifndef STATUS_VIA_WINDOWPORT
18 STATIC_DCL
void NDECL(bot1
);
19 STATIC_DCL
void NDECL(bot2
);
28 Strcpy(newbot1
, plname
);
29 if ('a' <= newbot1
[0] && newbot1
[0] <= 'z')
30 newbot1
[0] += 'A' - 'a';
32 Sprintf(nb
= eos(newbot1
), " the ");
38 Strcpy(mbot
, mons
[u
.umonnum
].mname
);
39 while (mbot
[k
] != 0) {
40 if ((k
== 0 || (k
> 0 && mbot
[k
- 1] == ' ')) && 'a' <= mbot
[k
]
45 Strcpy(nb
= eos(nb
), mbot
);
47 Strcpy(nb
= eos(nb
), rank());
49 Sprintf(nb
= eos(nb
), " ");
51 j
= (int) ((nb
+ 2) - newbot1
); /* strlen(newbot1) but less computation */
53 Sprintf(nb
= eos(nb
), "%*s", i
- j
, " "); /* pad with spaces */
54 if (ACURR(A_STR
) > 18) {
55 if (ACURR(A_STR
) > STR18(100))
56 Sprintf(nb
= eos(nb
), "St:%2d ", ACURR(A_STR
) - 100);
57 else if (ACURR(A_STR
) < STR18(100))
58 Sprintf(nb
= eos(nb
), "St:18/%02d ", ACURR(A_STR
) - 18);
60 Sprintf(nb
= eos(nb
), "St:18/** ");
62 Sprintf(nb
= eos(nb
), "St:%-1d ", ACURR(A_STR
));
63 Sprintf(nb
= eos(nb
), "Dx:%-1d Co:%-1d In:%-1d Wi:%-1d Ch:%-1d",
64 ACURR(A_DEX
), ACURR(A_CON
), ACURR(A_INT
), ACURR(A_WIS
),
67 (u
.ualign
.type
== A_CHAOTIC
)
69 : (u
.ualign
.type
== A_NEUTRAL
) ? " Neutral" : " Lawful");
72 Sprintf(nb
= eos(nb
), " S:%ld", botl_score());
74 curs(WIN_STATUS
, 1, 0);
75 putstr(WIN_STATUS
, 0, newbot1
);
81 char newbot2
[MAXCO
], /* MAXCO: botl.h */
82 /* dungeon location (and gold), hero health (HP, PW, AC),
83 experience (HD if poly'd, else Exp level and maybe Exp points),
84 time (in moves), varying number of status conditions */
85 dloc
[QBUFSZ
], hlth
[QBUFSZ
], expr
[QBUFSZ
], tmmv
[QBUFSZ
], cond
[QBUFSZ
];
87 unsigned dln
, dx
, hln
, xln
, tln
, cln
;
92 * Various min(x,9999)'s are to avoid having excessive values
93 * violate the field width assumptions in botl.h and should not
94 * impact normal play. Particularly 64-bit long for gold which
95 * could require many more digits if someone figures out a way
96 * to get and carry a really large (or negative) amount of it.
97 * Turn counter is also long, but we'll risk that.
100 /* dungeon location plus gold */
101 (void) describe_level(dloc
); /* includes at least one trailing space */
102 if ((money
= money_cnt(invent
)) < 0L)
103 money
= 0L; /* ought to issue impossible() and then discard gold */
104 Sprintf(eos(dloc
), "%s:%-2ld", /* strongest hero can lift ~300000 gold */
105 encglyph(objnum_to_glyph(GOLD_PIECE
)), min(money
, 999999L));
107 /* '$' encoded as \GXXXXNNNN is 9 chars longer than display will need */
108 dx
= strstri(dloc
, "\\G") ? 9 : 0;
110 /* health and armor class (has trailing space for AC 0..9) */
111 hp
= Upolyd
? u
.mh
: u
.uhp
;
112 hpmax
= Upolyd
? u
.mhmax
: u
.uhpmax
;
115 Sprintf(hlth
, "HP:%d(%d) Pw:%d(%d) AC:%-2d",
116 min(hp
, 9999), min(hpmax
, 9999),
117 min(u
.uen
, 9999), min(u
.uenmax
, 9999), u
.uac
);
122 Sprintf(expr
, "HD:%d", mons
[u
.umonnum
].mlevel
);
123 else if (flags
.showexp
)
124 Sprintf(expr
, "Xp:%u/%-1ld", u
.ulevel
, u
.uexp
);
126 Sprintf(expr
, "Exp:%u", u
.ulevel
);
129 /* time/move counter */
131 Sprintf(tmmv
, "T:%ld", moves
);
136 /* status conditions; worst ones first */
137 cond
[0] = '\0'; /* once non-empty, cond will have a leading space */
140 * Stoned, Slimed, Strangled, and both types of Sick are all fatal
141 * unless remedied before timeout expires. Should we order them by
142 * shortest time left? [Probably not worth the effort, since it's
143 * unusual for more than one of them to apply at a time.]
146 Strcpy(nb
= eos(nb
), " Stone");
148 Strcpy(nb
= eos(nb
), " Slime");
150 Strcpy(nb
= eos(nb
), " Strngl");
152 if (u
.usick_type
& SICK_VOMITABLE
)
153 Strcpy(nb
= eos(nb
), " FoodPois");
154 if (u
.usick_type
& SICK_NONVOMITABLE
)
155 Strcpy(nb
= eos(nb
), " TermIll");
157 if (u
.uhs
!= NOT_HUNGRY
)
158 Sprintf(nb
= eos(nb
), " %s", hu_stat
[u
.uhs
]);
159 if ((cap
= near_capacity()) > UNENCUMBERED
)
160 Sprintf(nb
= eos(nb
), " %s", enc_stat
[cap
]);
162 Strcpy(nb
= eos(nb
), " Blind");
164 Strcpy(nb
= eos(nb
), " Deaf");
166 Strcpy(nb
= eos(nb
), " Stun");
168 Strcpy(nb
= eos(nb
), " Conf");
170 Strcpy(nb
= eos(nb
), " Hallu");
171 /* levitation and flying are mutually exclusive; riding is not */
173 Strcpy(nb
= eos(nb
), " Lev");
175 Strcpy(nb
= eos(nb
), " Fly");
177 Strcpy(nb
= eos(nb
), " Ride");
181 * Put the pieces together. If they all fit, keep the traditional
182 * sequence. Otherwise, move least important parts to the end in
183 * case the interface side of things has to truncate. Note that
184 * dloc[] contains '$' encoded in ten character sequence \GXXXXNNNN
185 * so we want to test its display length rather than buffer length.
187 * We don't have an actual display limit here, so have to go by the
188 * width of the map. Since we're reordering rather than truncating,
189 * wider displays can still show wider status than the map if the
190 * interface supports that.
192 if ((dln
- dx
) + 1 + hln
+ 1 + xln
+ 1 + tln
+ 1 + cln
<= COLNO
) {
193 Sprintf(newbot2
, "%s %s %s %s %s", dloc
, hlth
, expr
, tmmv
, cond
);
195 if (dln
+ 1 + hln
+ 1 + xln
+ 1 + tln
+ 1 + cln
+ 1 > MAXCO
) {
196 panic("bot2: second status line exceeds MAXCO (%u > %d)",
197 (dln
+ 1 + hln
+ 1 + xln
+ 1 + tln
+ 1 + cln
+ 1), MAXCO
);
198 } else if ((dln
- dx
) + 1 + hln
+ 1 + xln
+ 1 + cln
<= COLNO
) {
199 Sprintf(newbot2
, "%s %s %s %s %s", dloc
, hlth
, expr
, cond
, tmmv
);
200 } else if ((dln
- dx
) + 1 + hln
+ 1 + cln
<= COLNO
) {
201 Sprintf(newbot2
, "%s %s %s %s %s", dloc
, hlth
, cond
, expr
, tmmv
);
203 Sprintf(newbot2
, "%s %s %s %s %s", hlth
, cond
, dloc
, expr
, tmmv
);
205 /* only two or three consecutive spaces available to squeeze out */
209 curs(WIN_STATUS
, 1, 1);
210 putmixed(WIN_STATUS
, 0, newbot2
);
220 context
.botl
= context
.botlx
= 0;
223 #endif /* !STATUS_VIA_WINDOWPORT */
225 /* convert experience level (1..30) to rank index (0..8) */
230 return (xlev
<= 2) ? 0 : (xlev
<= 30) ? ((xlev
+ 2) / 4) : 8;
233 #if 0 /* not currently needed */
234 /* convert rank index (0..8) to experience level (1..30) */
239 return (rank
<= 0) ? 1 : (rank
<= 8) ? ((rank
* 4) - 2) : 30;
244 rank_of(lev
, monnum
, female
)
249 register const struct Role
*role
;
253 for (role
= roles
; role
->name
.m
; role
++)
254 if (monnum
== role
->malenum
|| monnum
== role
->femalenum
)
260 for (i
= xlev_to_rank((int) lev
); i
>= 0; i
--) {
261 if (female
&& role
->rank
[i
].f
)
262 return role
->rank
[i
].f
;
264 return role
->rank
[i
].m
;
267 /* Try the role name, instead */
268 if (female
&& role
->name
.f
)
270 else if (role
->name
.m
)
275 STATIC_OVL
const char *
278 return rank_of(u
.ulevel
, Role_switch
, flags
.female
);
282 title_to_mon(str
, rank_indx
, title_length
)
284 int *rank_indx
, *title_length
;
288 /* Loop through each of the roles */
289 for (i
= 0; roles
[i
].name
.m
; i
++)
290 for (j
= 0; j
< 9; j
++) {
291 if (roles
[i
].rank
[j
].m
292 && !strncmpi(str
, roles
[i
].rank
[j
].m
,
293 strlen(roles
[i
].rank
[j
].m
))) {
297 *title_length
= strlen(roles
[i
].rank
[j
].m
);
298 return roles
[i
].malenum
;
300 if (roles
[i
].rank
[j
].f
301 && !strncmpi(str
, roles
[i
].rank
[j
].f
,
302 strlen(roles
[i
].rank
[j
].f
))) {
306 *title_length
= strlen(roles
[i
].rank
[j
].f
);
307 return (roles
[i
].femalenum
!= NON_PM
) ? roles
[i
].femalenum
317 register int i
, r
, maxr
= 0;
318 for (i
= 0; i
< 9; i
++) {
319 if (urole
.rank
[i
].m
&& (r
= strlen(urole
.rank
[i
].m
)) > maxr
)
321 if (urole
.rank
[i
].f
&& (r
= strlen(urole
.rank
[i
].f
)) > maxr
)
332 long deepest
= deepest_lev_reached(FALSE
);
335 utotal
= money_cnt(invent
) + hidden_gold();
336 if ((utotal
-= u
.umoney0
) < 0L)
338 utotal
+= u
.urexp
+ (50 * (deepest
- 1))
339 + (deepest
> 30 ? 10000 : deepest
> 20 ? 1000 * (deepest
- 20) : 0);
340 if (utotal
< u
.urexp
)
341 utotal
= LONG_MAX
; /* wrap around */
344 #endif /* SCORE_ON_BOTL */
346 /* provide the name of the current level for display by various ports */
353 /* TODO: Add in dungeon name */
355 Sprintf(buf
, "%s ", dungeons
[u
.uz
.dnum
].dname
);
356 else if (In_quest(&u
.uz
))
357 Sprintf(buf
, "Home %d ", dunlev(&u
.uz
));
358 else if (In_endgame(&u
.uz
))
359 Sprintf(buf
, Is_astralevel(&u
.uz
) ? "Astral Plane " : "End Game ");
361 /* ports with more room may expand this one */
362 Sprintf(buf
, "Dlvl:%-2d ", depth(&u
.uz
));
368 #ifdef STATUS_VIA_WINDOWPORT
369 /* =======================================================================*/
371 /* structure that tracks the status details in the core */
378 enum statusfields idxmax
;
379 enum statusfields fld
;
383 STATIC_DCL
void NDECL(init_blstats
);
384 STATIC_DCL
char *FDECL(anything_to_s
, (char *, anything
*, int));
385 STATIC_OVL
int FDECL(percentage
, (struct istat_s
*, struct istat_s
*));
386 STATIC_OVL
int FDECL(compare_blstats
, (struct istat_s
*, struct istat_s
*));
387 #ifdef STATUS_HILITES
388 STATIC_DCL
void FDECL(s_to_anything
, (anything
*, char *, int));
389 STATIC_DCL boolean
FDECL(assign_hilite
, (char *, char *, char *, char *,
391 STATIC_DCL
const char *FDECL(clridx_to_s
, (char *, int));
394 /* If entries are added to this, botl.h will require updating too */
395 STATIC_DCL
struct istat_s initblstats
[MAXBLSTATS
] = {
396 { 0L, ANY_STR
, { (genericptr_t
) 0 }, (char *) 0, 80, 0, BL_TITLE
},
397 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_STR
},
398 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_DX
},
399 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_CO
},
400 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_IN
},
401 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_WI
},
402 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_CH
},
403 { 0L, ANY_STR
, { (genericptr_t
) 0 }, (char *) 0, 40, 0, BL_ALIGN
},
404 { 0L, ANY_LONG
, { (genericptr_t
) 0 }, (char *) 0, 20, 0, BL_SCORE
},
405 { 0L, ANY_LONG
, { (genericptr_t
) 0 }, (char *) 0, 20, 0, BL_CAP
},
406 { 0L, ANY_LONG
, { (genericptr_t
) 0 }, (char *) 0, 30, 0, BL_GOLD
},
407 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, BL_ENEMAX
, BL_ENE
},
408 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_ENEMAX
},
409 { 0L, ANY_LONG
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_XP
},
410 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_AC
},
411 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_HD
},
412 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 20, 0, BL_TIME
},
413 { 0L, ANY_UINT
, { (genericptr_t
) 0 }, (char *) 0, 40, 0, BL_HUNGER
},
414 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, BL_HPMAX
, BL_HP
},
415 { 0L, ANY_INT
, { (genericptr_t
) 0 }, (char *) 0, 10, 0, BL_HPMAX
},
416 { 0L, ANY_STR
, { (genericptr_t
) 0 }, (char *) 0, 80, 0, BL_LEVELDESC
},
417 { 0L, ANY_LONG
, { (genericptr_t
) 0 }, (char *) 0, 20, 0, BL_EXP
},
419 { (genericptr_t
) 0 }, (char *) 0, 0, 0, BL_CONDITION
}
422 struct istat_s blstats
[2][MAXBLSTATS
];
423 static boolean blinit
= FALSE
, update_all
= FALSE
;
430 static int idx
= 0, idx_p
, idxmax
;
434 struct istat_s
*curr
, *prev
;
435 boolean valset
[MAXBLSTATS
], chgval
= FALSE
, updated
= FALSE
;
438 panic("bot before init.");
439 if (!youmonst
.data
) {
440 context
.botl
= context
.botlx
= 0;
446 idx
= 1 - idx
; /* 0 -> 1, 1 -> 0 */
448 /* clear the "value set" indicators */
449 (void) memset((genericptr_t
) valset
, 0, MAXBLSTATS
* sizeof (boolean
));
452 * Note: min(x,9999) - we enforce the same maximum on hp, maxhp,
453 * pw, maxpw, and gold as basic status formatting so that the two
454 * modes of status display don't produce different information.
458 * Player name and title.
460 Strcpy(nb
= buf
, plname
);
461 nb
[0] = highc(nb
[0]);
463 Sprintf(nb
= eos(nb
), " the ");
465 for (i
= 0, nb
= strcpy(eos(nb
), mons
[u
.umonnum
].mname
); nb
[i
]; i
++)
466 if (i
== 0 || nb
[i
- 1] == ' ')
467 nb
[i
] = highc(nb
[i
]);
469 Strcpy(nb
= eos(nb
), rank());
470 Sprintf(blstats
[idx
][BL_TITLE
].val
, "%-29s", buf
);
471 valset
[BL_TITLE
] = TRUE
; /* indicate val already set */
475 blstats
[idx
][BL_STR
].a
.a_int
= ACURR(A_STR
);
476 if (ACURR(A_STR
) > 18) {
477 if (ACURR(A_STR
) > STR18(100))
478 Sprintf(buf
, "%2d", ACURR(A_STR
) - 100);
479 else if (ACURR(A_STR
) < STR18(100))
480 Sprintf(buf
, "18/%02d", ACURR(A_STR
) - 18);
482 Sprintf(buf
, "18/**");
484 Sprintf(buf
, "%-1d", ACURR(A_STR
));
485 Strcpy(blstats
[idx
][BL_STR
].val
, buf
);
486 valset
[BL_STR
] = TRUE
; /* indicate val already set */
488 /* Dexterity, constitution, intelligence, wisdom, charisma. */
489 blstats
[idx
][BL_DX
].a
.a_int
= ACURR(A_DEX
);
490 blstats
[idx
][BL_CO
].a
.a_int
= ACURR(A_CON
);
491 blstats
[idx
][BL_IN
].a
.a_int
= ACURR(A_INT
);
492 blstats
[idx
][BL_WI
].a
.a_int
= ACURR(A_WIS
);
493 blstats
[idx
][BL_CH
].a
.a_int
= ACURR(A_CHA
);
496 Strcpy(blstats
[idx
][BL_ALIGN
].val
, (u
.ualign
.type
== A_CHAOTIC
)
498 : (u
.ualign
.type
== A_NEUTRAL
)
503 blstats
[idx
][BL_SCORE
].a
.a_long
=
512 i
= Upolyd
? u
.mh
: u
.uhp
;
515 blstats
[idx
][BL_HP
].a
.a_int
= min(i
, 9999);
516 i
= Upolyd
? u
.mhmax
: u
.uhpmax
;
517 blstats
[idx
][BL_HPMAX
].a
.a_int
= min(i
, 9999);
520 (void) describe_level(blstats
[idx
][BL_LEVELDESC
].val
);
521 valset
[BL_LEVELDESC
] = TRUE
; /* indicate val already set */
524 if ((money
= money_cnt(invent
)) < 0L)
525 money
= 0L; /* ought to issue impossible() and then discard gold */
526 blstats
[idx
][BL_GOLD
].a
.a_long
= min(money
, 999999L);
528 * The tty port needs to display the current symbol for gold
529 * as a field header, so to accommodate that we pass gold with
530 * that already included. If a window port needs to use the text
531 * gold amount without the leading "$:" the port will have to
532 * skip past ':' to the value pointer it was passed in status_update()
533 * for the BL_GOLD case.
535 * Another quirk of BL_GOLD is that the field display may have
536 * changed if a new symbol set was loaded, or we entered or left
539 * The currency prefix is encoded as ten character \GXXXXNNNN
542 Sprintf(blstats
[idx
][BL_GOLD
].val
, "%s:%ld",
543 encglyph(objnum_to_glyph(GOLD_PIECE
)),
544 blstats
[idx
][BL_GOLD
].a
.a_long
);
545 valset
[BL_GOLD
] = TRUE
; /* indicate val already set */
547 /* Power (magical energy) */
548 blstats
[idx
][BL_ENE
].a
.a_int
= min(u
.uen
, 9999);
549 blstats
[idx
][BL_ENEMAX
].a
.a_int
= min(u
.uenmax
, 9999);
552 blstats
[idx
][BL_AC
].a
.a_int
= u
.uac
;
554 /* Monster level (if Upolyd) */
555 blstats
[idx
][BL_HD
].a
.a_int
= Upolyd
? mons
[u
.umonnum
].mlevel
: 0;
558 blstats
[idx
][BL_XP
].a
.a_int
= u
.ulevel
;
559 blstats
[idx
][BL_EXP
].a
.a_int
= u
.uexp
;
562 blstats
[idx
][BL_TIME
].a
.a_long
= moves
;
565 blstats
[idx
][BL_HUNGER
].a
.a_uint
= u
.uhs
;
566 Strcpy(blstats
[idx
][BL_HUNGER
].val
,
567 (u
.uhs
!= NOT_HUNGRY
) ? hu_stat
[u
.uhs
] : "");
568 valset
[BL_HUNGER
] = TRUE
;
570 /* Carrying capacity */
571 cap
= near_capacity();
572 blstats
[idx
][BL_CAP
].a
.a_int
= cap
;
573 Strcpy(blstats
[idx
][BL_CAP
].val
,
574 (cap
> UNENCUMBERED
) ? enc_stat
[cap
] : "");
575 valset
[BL_CAP
] = TRUE
;
578 blstats
[idx
][BL_CONDITION
].a
.a_ulong
= 0L;
580 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_STONE
;
582 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_SLIME
;
584 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_STRNGL
;
585 if (Sick
&& (u
.usick_type
& SICK_VOMITABLE
) != 0)
586 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_FOODPOIS
;
587 if (Sick
&& (u
.usick_type
& SICK_NONVOMITABLE
) != 0)
588 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_TERMILL
;
590 * basic formatting puts hunger status and encumbrance here
593 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_BLIND
;
595 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_DEAF
;
597 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_STUN
;
599 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_CONF
;
601 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_HALLU
;
602 /* levitation and flying are mututally exclusive */
604 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_LEV
;
606 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_FLY
;
608 blstats
[idx
][BL_CONDITION
].a
.a_ulong
|= BL_MASK_RIDE
;
611 * Now pass the changed values to window port.
613 for (i
= 0; i
< MAXBLSTATS
; i
++) {
614 if (((i
== BL_SCORE
) && !flags
.showscore
)
615 || ((i
== BL_EXP
) && !flags
.showexp
)
616 || ((i
== BL_TIME
) && !flags
.time
)
617 || ((i
== BL_HD
) && !Upolyd
)
618 || ((i
== BL_XP
|| i
== BL_EXP
) && Upolyd
))
620 anytype
= blstats
[idx
][i
].anytype
;
621 curr
= &blstats
[idx
][i
];
622 prev
= &blstats
[idx_p
][i
];
625 || ((chg
= compare_blstats(prev
, curr
)) != 0)
626 || ((chgval
= (valset
[i
]
627 && strcmp(blstats
[idx
][i
].val
,
628 blstats
[idx_p
][i
].val
))) != 0)) {
629 idxmax
= blstats
[idx
][i
].idxmax
;
630 pc
= (idxmax
) ? percentage(curr
, &blstats
[idx
][idxmax
]) : 0;
632 (void) anything_to_s(curr
->val
, &curr
->a
, anytype
);
633 if (anytype
!= ANY_MASK32
) {
634 status_update(i
, (genericptr_t
) curr
->val
,
635 valset
[i
] ? chgval
: chg
, pc
);
637 /* send pointer to mask */
638 status_update(i
, (genericptr_t
) &curr
->a
.a_ulong
, chg
, 0);
644 * It is possible to get here, with nothing having been pushed
645 * to the window port, when none of the info has changed. In that
646 * case, we need to force a call to status_update() when
647 * context.botlx is set. The tty port in particular has a problem
648 * if that isn't done, since it sets context.botlx when a menu or
649 * text display obliterates the status line.
651 * To work around it, we call status_update() with fictitious
652 * index of BL_FLUSH (-1).
654 if ((context
.botlx
&& !updated
)
655 || windowprocs
.win_status_update
== genl_status_update
)
656 status_update(BL_FLUSH
, (genericptr_t
) 0, 0, 0);
658 context
.botl
= context
.botlx
= 0;
663 status_initialize(reassessment
)
665 reassessment
; /* TRUE = just reassess fields w/o other initialization*/
668 const char *fieldfmt
= (const char *) 0;
669 const char *fieldname
= (const char *) 0;
673 (*windowprocs
.win_status_init
)();
675 #ifdef STATUS_HILITES
676 status_notify_windowport(TRUE
);
679 for (i
= 0; i
< MAXBLSTATS
; ++i
) {
680 enum statusfields fld
= initblstats
[i
].fld
;
686 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
690 fieldname
= "strength";
691 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
695 fieldname
= "dexterity";
696 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
700 fieldname
= "constitution";
701 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
705 fieldname
= "intelligence";
706 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
710 fieldname
= "wisdom";
711 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
715 fieldname
= "charisma";
716 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
720 fieldname
= "alignment";
721 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
726 status_enablefield(fld
, fieldname
, fieldfmt
,
727 (!flags
.showscore
) ? FALSE
: TRUE
);
731 fieldname
= "carrying-capacity";
732 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
737 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
742 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
746 fieldname
= "power-max";
747 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
751 fieldname
= "experience-level";
752 status_enablefield(fld
, fieldname
, fieldfmt
,
753 (Upolyd
) ? FALSE
: TRUE
);
757 fieldname
= "armor-class";
758 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
763 status_enablefield(fld
, fieldname
, fieldfmt
,
764 (!Upolyd
) ? FALSE
: TRUE
);
769 status_enablefield(fld
, fieldname
, fieldfmt
,
770 (!flags
.time
) ? FALSE
: TRUE
);
774 fieldname
= "hunger";
775 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
779 fieldname
= "hitpoints";
780 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
784 fieldname
= "hitpoint-max";
785 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
789 fieldname
= "dungeon-level";
790 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
794 fieldname
= "experience";
795 status_enablefield(fld
, fieldname
, fieldfmt
,
796 (!flags
.showexp
|| Upolyd
) ? FALSE
: TRUE
);
800 fieldname
= "condition";
801 status_enablefield(fld
, fieldname
, fieldfmt
, TRUE
);
816 /* call the window port cleanup routine first */
817 (*windowprocs
.win_status_finish
)();
819 /* free memory that we alloc'd now */
820 for (i
= 0; i
< MAXBLSTATS
; ++i
) {
821 if (blstats
[0][i
].val
)
822 free((genericptr_t
) blstats
[0][i
].val
);
823 if (blstats
[1][i
].val
)
824 free((genericptr_t
) blstats
[1][i
].val
);
831 static boolean initalready
= FALSE
;
835 impossible("init_blstats called more than once.");
840 for (i
= BEFORE
; i
<= NOW
; ++i
) {
841 for (j
= 0; j
< MAXBLSTATS
; ++j
) {
842 blstats
[i
][j
] = initblstats
[j
];
843 blstats
[i
][j
].a
= zeroany
;
844 if (blstats
[i
][j
].valwidth
) {
845 blstats
[i
][j
].val
= (char *) alloc(blstats
[i
][j
].valwidth
);
846 blstats
[i
][j
].val
[0] = '\0';
848 blstats
[i
][j
].val
= (char *) 0;
854 anything_to_s(buf
, a
, anytype
)
864 Sprintf(buf
, "%lu", a
->a_ulong
);
867 Sprintf(buf
, "%lx", a
->a_ulong
);
870 Sprintf(buf
, "%ld", a
->a_long
);
873 Sprintf(buf
, "%d", a
->a_int
);
876 Sprintf(buf
, "%u", a
->a_uint
);
879 Sprintf(buf
, "%d", *a
->a_iptr
);
882 Sprintf(buf
, "%ld", *a
->a_lptr
);
885 Sprintf(buf
, "%lu", *a
->a_ulptr
);
888 Sprintf(buf
, "%u", *a
->a_uptr
);
890 case ANY_STR
: /* do nothing */
899 #ifdef STATUS_HILITES
902 s_to_anything(a
, buf
, anytype
)
912 a
->a_long
= atol(buf
);
915 a
->a_int
= atoi(buf
);
918 a
->a_uint
= (unsigned) atoi(buf
);
921 a
->a_ulong
= (unsigned long) atol(buf
);
925 *a
->a_iptr
= atoi(buf
);
929 *a
->a_uptr
= (unsigned) atoi(buf
);
933 *a
->a_lptr
= atol(buf
);
937 *a
->a_ulptr
= (unsigned long) atol(buf
);
940 a
->a_ulong
= (unsigned long) atol(buf
);
952 compare_blstats(bl1
, bl2
)
953 struct istat_s
*bl1
, *bl2
;
955 int anytype
, result
= 0;
958 panic("compare_blstat: bad istat pointer %s, %s",
959 fmt_ptr((genericptr_t
) bl1
), fmt_ptr((genericptr_t
) bl2
));
962 anytype
= bl1
->anytype
;
963 if ((!bl1
->a
.a_void
|| !bl2
->a
.a_void
)
964 && (anytype
== ANY_IPTR
|| anytype
== ANY_UPTR
|| anytype
== ANY_LPTR
965 || anytype
== ANY_ULPTR
)) {
966 panic("compare_blstat: invalid pointer %s, %s",
967 fmt_ptr((genericptr_t
) bl1
->a
.a_void
),
968 fmt_ptr((genericptr_t
) bl2
->a
.a_void
));
973 result
= (bl1
->a
.a_int
< bl2
->a
.a_int
)
975 : (bl1
->a
.a_int
> bl2
->a
.a_int
) ? -1 : 0;
978 result
= (*bl1
->a
.a_iptr
< *bl2
->a
.a_iptr
)
980 : (*bl1
->a
.a_iptr
> *bl2
->a
.a_iptr
) ? -1 : 0;
983 result
= (bl1
->a
.a_long
< bl2
->a
.a_long
)
985 : (bl1
->a
.a_long
> bl2
->a
.a_long
) ? -1 : 0;
988 result
= (*bl1
->a
.a_lptr
< *bl2
->a
.a_lptr
)
990 : (*bl1
->a
.a_lptr
> *bl2
->a
.a_lptr
) ? -1 : 0;
993 result
= (bl1
->a
.a_uint
< bl2
->a
.a_uint
)
995 : (bl1
->a
.a_uint
> bl2
->a
.a_uint
) ? -1 : 0;
998 result
= (*bl1
->a
.a_uptr
< *bl2
->a
.a_uptr
)
1000 : (*bl1
->a
.a_uptr
> *bl2
->a
.a_uptr
) ? -1 : 0;
1003 result
= (bl1
->a
.a_ulong
< bl2
->a
.a_ulong
)
1005 : (bl1
->a
.a_ulong
> bl2
->a
.a_ulong
) ? -1 : 0;
1008 result
= (*bl1
->a
.a_ulptr
< *bl2
->a
.a_ulptr
)
1010 : (*bl1
->a
.a_ulptr
> *bl2
->a
.a_ulptr
) ? -1 : 0;
1013 if (strcmp(bl1
->val
, bl2
->val
) == 0)
1019 if (bl1
->a
.a_ulong
== bl2
->a
.a_ulong
)
1031 percentage(bl
, maxbl
)
1032 struct istat_s
*bl
, *maxbl
;
1037 if (!bl
|| !maxbl
) {
1038 impossible("percentage: bad istat pointer %s, %s",
1039 fmt_ptr((genericptr_t
) bl
), fmt_ptr((genericptr_t
) maxbl
));
1043 anytype
= bl
->anytype
;
1044 if (maxbl
->a
.a_void
) {
1047 result
= ((100 * bl
->a
.a_int
) / maxbl
->a
.a_int
);
1050 result
= (int) ((100L * bl
->a
.a_long
) / maxbl
->a
.a_long
);
1053 result
= (int) ((100U * bl
->a
.a_uint
) / maxbl
->a
.a_uint
);
1056 result
= (int) ((100UL * bl
->a
.a_ulong
) / maxbl
->a
.a_ulong
);
1059 result
= ((100 * (*bl
->a
.a_iptr
)) / (*maxbl
->a
.a_iptr
));
1062 result
= (int) ((100L * (*bl
->a
.a_lptr
)) / (*maxbl
->a
.a_lptr
));
1065 result
= (int) ((100U * (*bl
->a
.a_uptr
)) / (*maxbl
->a
.a_uptr
));
1068 result
= (int) ((100UL * (*bl
->a
.a_ulptr
)) / (*maxbl
->a
.a_ulptr
));
1076 #ifdef STATUS_HILITES
1078 /****************************************************************************/
1079 /* Core status hiliting support */
1080 /****************************************************************************/
1082 static struct fieldid_t
{
1083 const char *fieldname
;
1084 enum statusfields fldid
;
1086 {"title", BL_TITLE
},
1087 {"strength", BL_STR
},
1088 {"dexterity", BL_DX
},
1089 {"constitution", BL_CO
},
1090 {"intelligence", BL_IN
},
1092 {"charisma", BL_CH
},
1093 {"alignment", BL_ALIGN
},
1094 {"score", BL_SCORE
},
1095 {"carrying-capacity", BL_CAP
},
1098 {"power-max", BL_ENEMAX
},
1099 {"experience-level", BL_XP
},
1100 {"armor-class", BL_AC
},
1103 {"hunger", BL_HUNGER
},
1104 {"hitpoints", BL_HP
},
1105 {"hitpoints-max", BL_HPMAX
},
1106 {"dungeon-level", BL_LEVELDESC
},
1107 {"experience", BL_EXP
},
1108 {"condition", BL_CONDITION
},
1119 struct hilite_s status_hilites
[MAXBLSTATS
];
1122 * This is the parser for the hilite options
1124 * OPTION=hilite_status: hitpoints/10%/red/normal
1126 * set_hilite_status() separates each hilite entry into its 4 component
1127 * strings, then calls assign_hilite() to make the adjustments.
1130 set_status_hilites(op
, from_configfile
)
1132 boolean from_configfile
;
1134 char hsbuf
[4][QBUFSZ
];
1135 boolean rslt
, badopt
= FALSE
;
1136 int fldnum
, num
= 0, ccount
= 0;
1140 hsbuf
[0][0] = hsbuf
[1][0] = hsbuf
[2][0] = hsbuf
[3][0] = '\0';
1141 while (*op
&& fldnum
< 4 && ccount
< (QBUFSZ
- 2)) {
1145 rslt
= assign_hilite(&hsbuf
[0][0], &hsbuf
[1][0], &hsbuf
[2][0],
1146 &hsbuf
[3][0], from_configfile
);
1152 hsbuf
[0][0] = hsbuf
[1][0] = '\0';
1153 hsbuf
[2][0] = hsbuf
[3][0] = '\0';
1156 } else if (c
== '/') {
1160 hsbuf
[fldnum
][ccount
++] = c
;
1161 hsbuf
[fldnum
][ccount
] = '\0';
1165 if (fldnum
>= 2 && !badopt
) {
1166 rslt
= assign_hilite(&hsbuf
[0][0], &hsbuf
[1][0], &hsbuf
[2][0],
1167 &hsbuf
[3][0], from_configfile
);
1177 clear_status_hilites(from_configfile
)
1178 boolean from_configfile
;
1184 for (i
= 0; i
< MAXBLSTATS
; ++i
) {
1185 (void) memset((genericptr_t
) &status_hilites
[i
], 0,
1186 sizeof(struct hilite_s
));
1187 /* notify window port */
1188 if (!from_configfile
)
1189 status_threshold(i
, blstats
[0][i
].anytype
, it
, 0, 0, 0);
1194 assign_hilite(sa
, sb
, sc
, sd
, from_configfile
)
1195 char *sa
, *sb
, *sc
, *sd
;
1196 boolean from_configfile
;
1199 int i
= -1, dt
= -1, idx
= -1;
1200 int coloridx
[2] = { -1, -1 };
1201 boolean inverse
[2] = { FALSE
, FALSE
};
1202 boolean bold
[2] = { FALSE
, FALSE
};
1203 boolean normal
[2] = { 0, 0 };
1204 boolean percent
= FALSE
, down_up
= FALSE
, changed
= FALSE
;
1206 enum statusfields fld
= BL_FLUSH
;
1207 threshold
.a_void
= 0;
1210 * hilite_status: hitpoints/10%/red/normal
1213 /* field name to statusfield */
1214 for (i
= 0; sa
&& i
< SIZE(fieldids
); ++i
) {
1215 if (strcmpi(sa
, fieldids
[i
].fieldname
) == 0) {
1217 fld
= fieldids
[i
].fldid
;
1223 status_hilites
[idx
].set
= FALSE
; /* mark it "unset" */
1228 if ((strcmpi(sb
, "updown") == 0) || (strcmpi(sb
, "downup") == 0)
1229 || (strcmpi(sb
, "up") == 0) || (strcmpi(sb
, "down") == 0)) {
1231 } else if ((strcmpi(sb
, "changed") == 0)
1232 && (fld
== BL_TITLE
|| fld
== BL_ALIGN
|| fld
== BL_LEVELDESC
1233 || fld
== BL_CONDITION
)) {
1234 changed
= TRUE
; /* changed is only thing allowed */
1242 } else if (!index("0123456789", *tmp
))
1246 if (strlen(sb
) > 0) {
1247 dt
= blstats
[0][idx
].anytype
;
1250 (void) s_to_anything(&threshold
, sb
, dt
);
1253 if (percent
&& (threshold
.a_int
< 1 || threshold
.a_int
> 100))
1255 if (!threshold
.a_void
&& (strcmp(sb
, "0") != 0))
1260 for (i
= 0; i
< 2; ++i
) {
1265 break; /* sc is mandatory; sd is not */
1268 if (strcmpi(how
, "bold") == 0) {
1270 } else if (strcmpi(how
, "inverse") == 0) {
1272 } else if (strcmpi(how
, "normal") == 0) {
1275 int k
= match_str2clr(how
);
1283 /* Assign the values */
1285 for (i
= 0; i
< 2; ++i
) {
1287 status_hilites
[idx
].coloridx
[i
] = BL_HILITE_INVERSE
;
1289 status_hilites
[idx
].coloridx
[i
] = BL_HILITE_BOLD
;
1290 else if (coloridx
[i
])
1291 status_hilites
[idx
].coloridx
[i
] = coloridx
[i
];
1293 status_hilites
[idx
].coloridx
[i
] = BL_HILITE_NONE
;
1297 status_hilites
[idx
].behavior
= BL_TH_VAL_PERCENTAGE
;
1299 status_hilites
[idx
].behavior
= BL_TH_UPDOWN
;
1300 else if (threshold
.a_void
)
1301 status_hilites
[idx
].behavior
= BL_TH_VAL_ABSOLUTE
;
1303 status_hilites
[idx
].behavior
= BL_TH_NONE
;
1305 if (status_hilites
[idx
].behavior
!= BL_TH_NONE
) {
1306 status_hilites
[idx
].threshold
= threshold
;
1307 status_hilites
[idx
].set
= TRUE
;
1309 status_hilites
[idx
].anytype
= dt
;
1311 /* Now finally, we notify the window port */
1312 if (!from_configfile
)
1313 status_threshold(idx
, status_hilites
[idx
].anytype
,
1314 status_hilites
[idx
].threshold
,
1315 status_hilites
[idx
].behavior
,
1316 status_hilites
[idx
].coloridx
[0],
1317 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*/