| 2361 | * pointer to rule that applies; Null if no rule does. |
| 2362 | */ |
| 2363 | staticfn struct hilite_s * |
| 2364 | get_hilite( |
| 2365 | int idx, int fldidx, |
| 2366 | genericptr_t vp, |
| 2367 | int chg, int pc, |
| 2368 | int *colorptr) |
| 2369 | { |
| 2370 | struct hilite_s *hl, *rule = 0; |
| 2371 | anything *value = (anything *) vp; |
| 2372 | char *txtstr; |
| 2373 | |
| 2374 | if (fldidx < 0 || fldidx >= MAXBLSTATS) |
| 2375 | return (struct hilite_s *) 0; |
| 2376 | |
| 2377 | if (has_hilite(fldidx)) { |
| 2378 | int dt; |
| 2379 | /* there are hilites set here */ |
| 2380 | int max_pc = -1, min_pc = 101; |
| 2381 | /* LARGEST_INT isn't INT_MAX; it fits within 16 bits, but that |
| 2382 | value is big enough to handle all 'int' status fields */ |
| 2383 | int max_ival = -LARGEST_INT, min_ival = LARGEST_INT; |
| 2384 | /* LONG_MAX comes from <limits.h> which might not be available for |
| 2385 | ancient configurations; we don't need LONG_MIN */ |
| 2386 | long max_lval = -LONG_MAX, min_lval = LONG_MAX; |
| 2387 | boolean exactmatch = FALSE, updown = FALSE, changed = FALSE, |
| 2388 | perc_or_abs = FALSE, crit_hp = FALSE; |
| 2389 | |
| 2390 | /* min_/max_ are used to track best fit */ |
| 2391 | for (hl = gb.blstats[0][fldidx].thresholds; hl; hl = hl->next) { |
| 2392 | dt = initblstats[fldidx].anytype; /* only needed for 'absolute' */ |
| 2393 | /* for HP, if we already have a critical-hp rule then we ignore |
| 2394 | other HP rules unless we hit another critical-hp one (last |
| 2395 | one found wins); critical-hp takes precedence over temporary |
| 2396 | HP highlights, otherwise a hero with regeneration and an up |
| 2397 | or changed rule for HP would always show that up or changed |
| 2398 | highlight even when within the critical-hp threshold because |
| 2399 | the value will go up by at least one on every move */ |
| 2400 | if (crit_hp && hl->behavior != BL_TH_CRITICALHP) |
| 2401 | continue; |
| 2402 | /* if we've already matched a temporary highlight, it takes |
| 2403 | precedence over all persistent ones; we still process |
| 2404 | updown rules to get the last one which qualifies */ |
| 2405 | if ((updown || changed) && hl->behavior != BL_TH_UPDOWN) |
| 2406 | continue; |
| 2407 | /* among persistent highlights, if a 'percentage' or 'absolute' |
| 2408 | rule has been matched, it takes precedence over 'always' */ |
| 2409 | if (perc_or_abs && hl->behavior == BL_TH_ALWAYS_HILITE) |
| 2410 | continue; |
| 2411 | |
| 2412 | switch (hl->behavior) { |
| 2413 | case BL_TH_VAL_PERCENTAGE: /* percent values are always ANY_INT */ |
| 2414 | if (hl->rel == EQ_VALUE && pc == hl->value.a_int) { |
| 2415 | rule = hl; |
| 2416 | min_pc = max_pc = hl->value.a_int; |
| 2417 | exactmatch = perc_or_abs = TRUE; |
| 2418 | } else if (exactmatch) { |
| 2419 | ; /* already found best fit, skip lt,ge,&c */ |
| 2420 | } else if (hl->rel == LT_VALUE |
no test coverage detected