extend #timeout to cover all properties
Extend the wizard mode #timeout command: show timeouts for all 67 intrinsics rather than just a handful. Most won't appear because they don't have any way to receive a timed value. Except for... Extend the wizard mode #wizintrinsic command: allow setting a brief (30 turn) timeout for any/every intrinsic, not just for deafness. It ought to prompt for duration, but that's more effort than I'm willing to expend. This might turn up lots of quirks that the code isn't prepared to handle (like setting life-saving to non-zero will break the assumption that it comes from worn amulet). Perhaps some will warrant fixing, others just a shrug. There are still some timed events that aren't listed by #timeout: remaining duration to stay polymorphed in current form, number of turns until it's safe to pray, luck decay, number of turns until next attribute exercise/abuse check, probably others that I'm overlooking. Bug fix: while testing, I observed Your limbs have turned to stone. You have turned to stone. You can hear again. You are a statue. when deafness and petrification were timing out at the same time. This modifies the stoning and sliming countdowns to extend deafness duration a little if it's about to time out at the tail end of the stoning or sliming sequence, so that "you can hear again" won't happen until after life-saving. There are probably other variations of simultaneous or near simultaneous timeout that interact oddly.
This commit is contained in:
111
src/cmd.c
111
src/cmd.c
@@ -1141,41 +1141,94 @@ STATIC_PTR int
|
||||
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)));
|
||||
@@ -2814,7 +2867,7 @@ struct ext_func_tab extcmdlist[] = {
|
||||
{ '\\', "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",
|
||||
@@ -2835,11 +2888,11 @@ struct ext_func_tab extcmdlist[] = {
|
||||
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",
|
||||
@@ -2851,7 +2904,7 @@ struct ext_func_tab extcmdlist[] = {
|
||||
{ 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",
|
||||
@@ -2900,7 +2953,7 @@ struct ext_func_tab extcmdlist[] = {
|
||||
{ '\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 },
|
||||
|
||||
Reference in New Issue
Block a user