#ifndef PROP_H
#define PROP_H
-/*** What the properties are ***/
+/*** What the properties are ***
+ *
+ * note: propertynames[] array in timeout.c must be kept in synch with these.
+ * Property #0 is not used.
+ */
/* Resistances to troubles */
#define FIRE_RES 1
#define COLD_RES 2
wiz_intrinsic(VOID_ARGS)
{
if (wizard) {
+ extern const char *const propertynames[]; /* timeout.c */
+ static const char wizintrinsic[] = "#wizintrinsic";
+ static const char fmt[] = "You are%s %s.";
winid win;
anything any;
- int i, n, accelerator;
+ char buf[BUFSZ];
+ int i, n, p, amt, typ;
+ long oldtimeout, newtimeout;
+ const char *propname;
menu_item *pick_list = (menu_item *) 0;
- static const char *const intrinsics[] = {
- "deafness",
- };
-
win = create_nhwindow(NHW_MENU);
start_menu(win);
- accelerator = 0;
- for (i = 0; i < SIZE(intrinsics); ++i) {
- accelerator = intrinsics[i][0];
- any.a_int = i + 1;
- add_menu(win, NO_GLYPH, &any, accelerator, 0,
- ATR_NONE, intrinsics[i], FALSE);
+ for (i = 1; (propname = propertynames[i]) != 0; ++i) {
+ if (i == HALLUC_RES) {
+ /* Grayswandir vs hallucination; ought to be redone to
+ use u.uprops[HALLUC].blocked instead of being treated
+ as a separate property; letting in be manually toggled
+ even only in wizard mode would be asking for trouble... */
+ continue;
+ }
+ any.a_int = i;
+ add_menu(win, NO_GLYPH, &any, 0, 0, ATR_NONE, propname, FALSE);
}
- end_menu(win, "Which intrinsic?");
- n = select_menu(win, PICK_ONE, &pick_list);
+ end_menu(win, "Which intrinsics?");
+ n = select_menu(win, PICK_ANY, &pick_list);
destroy_nhwindow(win);
- if (n >= 1) {
- i = pick_list[0].item.a_int-1;
- free((genericptr_t) pick_list);
- } else {
- return 0;
- }
+ amt = 30; /* TODO: prompt for duration */
+ for (i = 0; i < n; ++i) {
+ p = pick_list[i].item.a_int;
+ oldtimeout = u.uprops[p].intrinsic & TIMEOUT;
+ newtimeout = oldtimeout + (long) amt;
+ switch (p) {
+ case SICK:
+ case SLIMED:
+ case STONED:
+ if (oldtimeout > 0L && newtimeout > oldtimeout)
+ newtimeout = oldtimeout;
+ break;
+ }
- if (!strcmp(intrinsics[i], "deafness")) {
- You("go deaf.");
- incr_itimeout(&HDeaf, 30);
- context.botl = TRUE;
+ switch (p) {
+ case BLINDED:
+ make_blinded(newtimeout, TRUE);
+ break;
+ case CONFUSION:
+ make_confused(newtimeout, TRUE);
+ break;
+ case DEAF:
+ make_deaf(newtimeout, TRUE);
+ break;
+ case HALLUC:
+ make_hallucinated(newtimeout, TRUE, 0L);
+ break;
+ case SICK:
+ typ = !rn2(2) ? SICK_VOMITABLE : SICK_NONVOMITABLE;
+ make_sick(newtimeout, wizintrinsic, TRUE, typ);
+ break;
+ case SLIMED:
+ Sprintf(buf, fmt,
+ !Slimed ? "" : " still", "turning into slime");
+ make_slimed(newtimeout, buf);
+ break;
+ case STONED:
+ Sprintf(buf, fmt,
+ !Stoned ? "" : " still", "turning into stone");
+ make_stoned(newtimeout, buf, KILLED_BY, wizintrinsic);
+ break;
+ case STUNNED:
+ make_stunned(newtimeout, TRUE);
+ break;
+ case VOMITING:
+ Sprintf(buf, fmt, !Vomiting ? "" : " still", "vomiting");
+ make_vomiting(newtimeout, FALSE);
+ pline1(buf);
+ break;
+ default:
+ pline("Timeout for %s %s %d.", propertynames[p],
+ oldtimeout ? "increased by" : "set to", amt);
+ incr_itimeout(&u.uprops[p].intrinsic, amt);
+ break;
+ }
+ context.botl = 1; /* probably not necessary... */
}
+ if (n >= 1)
+ free((genericptr_t) pick_list);
} else
pline("Unavailable command '%s'.",
visctrl((int) cmd_from_func(wiz_intrinsic)));
{ '\\', "known", "show what object types have been discovered",
dodiscovered, IFBURIED | GENERALCMD },
{ '`', "knownclass", "show discovered types for one class of objects",
- doclassdisco, IFBURIED|GENERALCMD },
+ doclassdisco, IFBURIED | GENERALCMD },
{ '\0', "levelchange", "change experience level",
wiz_level_change, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ '\0', "lightsources", "show mobile light sources",
dosacrifice, AUTOCOMPLETE },
{ 'o', "open", "open a door", doopen },
{ 'O', "options", "show option settings, possibly change them",
- doset, IFBURIED|GENERALCMD },
+ doset, IFBURIED | GENERALCMD },
{ C('o'), "overview", "show a summary of the explored dungeon",
- dooverview, IFBURIED|AUTOCOMPLETE },
+ dooverview, IFBURIED | AUTOCOMPLETE },
{ '\0', "panic", "test panic routine (fatal to game)",
- wiz_panic, IFBURIED|AUTOCOMPLETE|WIZMODECMD },
+ wiz_panic, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ 'p', "pay", "pay your shopping bill", dopay },
{ ',', "pickup", "pick up things at the current location", dopickup },
{ '\0', "polyself", "polymorph self",
{ M('p'), "pray", "pray to the gods for help",
dopray, IFBURIED | AUTOCOMPLETE },
{ C('p'), "prevmsg", "view recent game messages",
- doprev_message, IFBURIED|GENERALCMD },
+ doprev_message, IFBURIED | GENERALCMD },
{ 'P', "puton", "put on an accessory (ring, amulet, etc)", doputon },
{ 'q', "quaff", "quaff (drink) something", dodrink },
{ M('q'), "quit", "exit without saving current game",
{ '\0', "terrain", "show map without obstructions",
doterrain, IFBURIED | AUTOCOMPLETE },
{ 't', "throw", "throw something", dothrow },
- { '\0', "timeout", "look at timeout queue",
+ { '\0', "timeout", "look at timeout queue and hero's timed intrinsics",
wiz_timeout_queue, IFBURIED | AUTOCOMPLETE | WIZMODECMD },
{ M('T'), "tip", "empty a container", dotip, AUTOCOMPLETE },
{ '_', "travel", "travel to a specific location on the map", dotravel },
STATIC_DCL void FDECL(lantern_message, (struct obj *));
STATIC_DCL void FDECL(cleanup_burn, (ANY_P *, long));
+/* the order of these must match their numerical sequence in prop.h
+ because the property number is inferred from the array index;
+ used by wizard mode #timeout and #wizintrinsic */
+const char *const propertynames[] = {
+ "0: not used",
+/* Resistances */
+ /* 1..2 */ "fire resistance", "cold resistance",
+ /* 3..4 */ "sleep resistance", "disintegration resistance",
+ /* 5..6 */ "shock resistance", "poison resistance",
+ /* 7..8 */ "acid resistance", "stoning resistance",
+ /* 9..10 */ "drain resistance", "sickness resistance",
+ /* 11..12 */ "invulnerable", "magic resistance",
+/* Troubles */
+ /* 13..16 */ "stunned", "confused", "blinded", "deafness",
+ /* 17..20 */ "fatally sick", "petrifying", "strangling", "vomiting",
+ /* 21..22 */ "slippery fingers", "becoming slime",
+ /* 23..24 */ "hallucinating", "halluicination resistance",
+ /* 25..28 */ "fumbling", "wounded legs", "sleepy", "voracious hunger",
+/* Vision and senses */
+ /* 29..30 */ "see invisible", "telepathic",
+ /* 31..33 */ "warning", "warn:monster", "warn:undead",
+ /* 34..37 */ "searching", "clairvoyant", "infravision", "monster detection",
+/* Appearance and behavior */
+ /* 38..41 */ "adorned (+/-Cha)", "invisible", "displaced", "stealthy",
+ /* 42..43 */ "monster aggrevation", "conflict",
+/* Transportation */
+ /* 44..46 */ "jumping", "teleporting", "teleport control",
+ /* 47..49 */ "levitating", "flying", "water walking",
+ /* 50..52 */ "swimming", "magical breathing", "pass thru walls",
+/* Physical attributes */
+ /* 53..55 */ "slow digestion", "half spell damage", "half physical damage",
+ /* 56..58 */ "HP regeneration", "energy regeneration", "extra protection",
+ /* 59 */ "protection from shape changers",
+ /* 60..62 */ "polymorphing", "polymorph control", "unchanging",
+ /* 63..66 */ "fast", "reflecting", "free action", "fixed abilites",
+ /* 67 */ "life will be saved",
+ 0 /* sentinel */
+};
+
/* He is being petrified - dialogue by inmet!tower */
static NEARDATA const char *const stoned_texts[] = {
"You are slowing down.", /* 5 */
multi_reason = "getting stoned";
nomovemsg = You_can_move_again; /* not unconscious */
break;
+ case 2:
+ if ((HDeaf & TIMEOUT) > 0L && (HDeaf & TIMEOUT) < 5L)
+ set_itimeout(&HDeaf, 5L); /* avoid Hear_again at tail end */
default:
break;
}
if (((HLevitation & TIMEOUT) % 2L) && i > 0L && i <= SIZE(levi_texts)) {
const char *s = levi_texts[SIZE(levi_texts) - i];
if (index(s, '%')) {
- boolean danger = is_pool_or_lava(u.ux, u.uy)
- && !Is_waterlevel(&u.uz);
+ boolean danger = (is_pool_or_lava(u.ux, u.uy)
+ && !Is_waterlevel(&u.uz));
+
pline(s, danger ? "over" : "in",
danger ? surface(u.ux, u.uy) : "air");
} else
if (multi > 0)
nomul(0);
}
+ if (i == 2L && (HDeaf & TIMEOUT) > 0L && (HDeaf & TIMEOUT) < 5L)
+ set_itimeout(&HDeaf, 5L); /* avoid Hear_again at tail end */
exercise(A_DEX, FALSE);
}
char buf[BUFSZ];
if (!base) {
- putstr(win, 0, "<empty>");
+ putstr(win, 0, " <empty>");
} else {
putstr(win, 0, "timeout id kind call");
for (curr = base; curr; curr = curr->next) {
}
}
-static boolean print_prop_header = TRUE;
-void
-print_prop(win, text, prop)
-winid win;
-const char *text;
-long prop;
-{
- char buf[BUFSZ];
- if (prop & TIMEOUT) {
- if (print_prop_header) {
- putstr(win, 0, "");
- putstr(win, 0, "Properties:");
- putstr(win, 0, "");
- print_prop_header = FALSE;
- }
- Sprintf(buf, " %10s: %ld", text, (prop & TIMEOUT));
- putstr(win, 0, buf);
- }
-}
-
int
wiz_timeout_queue()
{
winid win;
char buf[BUFSZ];
+ const char *propname;
+ long intrinsic;
+ int i, count, longestlen, ln;
win = create_nhwindow(NHW_MENU); /* corner text window */
if (win == WIN_ERR)
putstr(win, 0, "");
print_queue(win, timer_base);
- print_prop_header = TRUE;
- print_prop(win, "Confused", Confusion);
- print_prop(win, "Deaf", HDeaf);
- print_prop(win, "Levitation", HLevitation);
- print_prop(win, "Monster detection", HDetect_monsters);
- print_prop(win, "Slimed", Slimed);
- print_prop(win, "Slippery hands", Glib);
- print_prop(win, "Stoned", Stoned);
- print_prop(win, "Strangled", Strangled);
- print_prop(win, "Stunned", Stunned);
- print_prop(win, "Vomiting", Vomiting);
- print_prop(win, "Wounded legs", HWounded_legs);
-
+ /* Timed properies:
+ * check every one; the majority can't obtain temporary timeouts in
+ * normal play but those can be forced via the #wizintrinsic command.
+ */
+ count = longestlen = 0;
+ for (i = 1; (propname = propertynames[i]) != 0; ++i) { /* [0] not used */
+ intrinsic = u.uprops[i].intrinsic;
+ if (intrinsic & TIMEOUT) {
+ ++count;
+ if ((ln = (int) strlen(propname)) > longestlen)
+ longestlen = ln;
+ }
+ }
+ putstr(win, 0, "");
+ if (!count) {
+ putstr(win, 0, "No timed properties.");
+ } else {
+ putstr(win, 0, "Timed properties:");
+ putstr(win, 0, "");
+ for (i = 1; (propname = propertynames[i]) != 0; ++i) {
+ intrinsic = u.uprops[i].intrinsic;
+ if (intrinsic & TIMEOUT) {
+ /* timeout value can be up to 16777215 (0x00ffffff) but
+ width of 4 digits should result in values lining up
+ almost all the time (if/when they don't, it won't
+ look nice but the information will still be accurate) */
+ Sprintf(buf, " %*s %4ld", -longestlen, propname,
+ (intrinsic & TIMEOUT));
+ putstr(win, 0, buf);
+ }
+ }
+ }
display_nhwindow(win, FALSE);
destroy_nhwindow(win);
for (curr = timer_base; curr; curr = curr->next)
if (curr->kind == TIMER_OBJECT) {
struct obj *obj = curr->arg.a_obj;
+
if (obj->timed == 0) {
pline("timer sanity: untimed obj %s, timer %ld",
fmt_ptr((genericptr_t) obj), curr->tid);