X-Git-Url: http://git.osdn.net/view?a=blobdiff_plain;f=src%2Fcmd.c;h=e1db0954fe1aef0d7cb3434729c9843a58d4da34;hb=3be5d02819c7185d7cffb673ed4119a2e0303c7a;hp=ea1e4a03ce69ed0af3cdb3f48ce82c57561a0102;hpb=3b714e4f6d98edc6dc02769739fdbf0c3fa89e61;p=jnethack%2Fsource.git diff --git a/src/cmd.c b/src/cmd.c index ea1e4a0..e1db095 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -1,17 +1,33 @@ -/* NetHack 3.6 cmd.c $NHDT-Date: 1523306904 2018/04/09 20:48:24 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.281 $ */ +/* NetHack 3.6 cmd.c $NHDT-Date: 1557088405 2019/05/05 20:33:25 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.333 $ */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /*-Copyright (c) Robert Patrick Rankin, 2013. */ /* NetHack may be freely redistributed. See license for details. */ /* JNetHack Copyright */ /* (c) Issei Numata, Naoki Hamada, Shigehiro Miyashita, 1994-2000 */ -/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2018 */ +/* For 3.4-, Copyright (c) SHIRAKATA Kentaro, 2002-2019 */ /* JNetHack may be freely redistributed. See license for details. */ #include "hack.h" #include "lev.h" #include "func_tab.h" +/* Macros for meta and ctrl modifiers: + * M and C return the meta/ctrl code for the given character; + * e.g., (C('c') is ctrl-c + */ +#ifndef M +#ifndef NHSTDC +#define M(c) (0x80 | (c)) +#else +#define M(c) ((c) - 128) +#endif /* NHSTDC */ +#endif + +#ifndef C +#define C(c) (0x1f & (c)) +#endif + #ifdef ALTMETA STATIC_VAR boolean alt_esc = FALSE; #endif @@ -36,7 +52,6 @@ extern const char *enc_stat[]; /* encumbrance status from botl.c */ #ifdef DEBUG extern int NDECL(wiz_debug_cmd_bury); -extern int NDECL(wiz_debug_cmd_traveldisplay); #endif #ifdef DUMB /* stuff commented out in extern.h, but needed here */ @@ -105,7 +120,7 @@ extern int NDECL(dosit); /**/ extern int NDECL(dotalk); /**/ extern int NDECL(docast); /**/ extern int NDECL(dovspell); /**/ -extern int NDECL(dotele); /**/ +extern int NDECL(dotelecmd); /**/ extern int NDECL(dountrap); /**/ extern int NDECL(doversion); /**/ extern int NDECL(doextversion); /**/ @@ -116,10 +131,10 @@ extern int NDECL(dozap); /**/ extern int NDECL(doorganize); /**/ #endif /* DUMB */ -static int NDECL(dosuspend_core); /**/ - static int NDECL((*timed_occ_fn)); +STATIC_PTR int NDECL(dosuspend_core); +STATIC_PTR int NDECL(dosh_core); STATIC_PTR int NDECL(doherecmdmenu); STATIC_PTR int NDECL(dotherecmdmenu); STATIC_PTR int NDECL(doprev_message); @@ -143,7 +158,6 @@ STATIC_PTR int NDECL(wiz_show_seenv); STATIC_PTR int NDECL(wiz_show_vision); STATIC_PTR int NDECL(wiz_smell); STATIC_PTR int NDECL(wiz_intrinsic); -STATIC_PTR int NDECL(wiz_mon_polycontrol); STATIC_PTR int NDECL(wiz_show_wmodes); STATIC_DCL void NDECL(wiz_map_levltyp); STATIC_DCL void NDECL(wiz_levltyp_legend); @@ -167,12 +181,10 @@ STATIC_DCL void FDECL(contained_stats, (winid, const char *, long *, long *)); STATIC_DCL void FDECL(misc_stats, (winid, long *, long *)); STATIC_PTR int NDECL(wiz_show_stats); STATIC_DCL boolean FDECL(accept_menu_prefix, (int NDECL((*)))); -#ifdef PORT_DEBUG -STATIC_DCL int NDECL(wiz_port_debug); -#endif STATIC_PTR int NDECL(wiz_rumor_check); STATIC_PTR int NDECL(doattributes); +STATIC_DCL void FDECL(enlght_out, (const char *)); STATIC_DCL void FDECL(enlght_line, (const char *, const char *, const char *, const char *)); STATIC_DCL char *FDECL(enlght_combatinc, (const char *, int, int, char *)); @@ -181,14 +193,12 @@ STATIC_DCL boolean NDECL(walking_on_water); STATIC_DCL boolean FDECL(cause_known, (int)); STATIC_DCL char *FDECL(attrval, (int, int, char *)); STATIC_DCL void FDECL(background_enlightenment, (int, int)); +STATIC_DCL void FDECL(basics_enlightenment, (int, int)); STATIC_DCL void FDECL(characteristics_enlightenment, (int, int)); STATIC_DCL void FDECL(one_characteristic, (int, int, int)); STATIC_DCL void FDECL(status_enlightenment, (int, int)); STATIC_DCL void FDECL(attributes_enlightenment, (int, int)); -static const char *readchar_queue = ""; -static coord clicklook_cc; - STATIC_DCL void FDECL(add_herecmd_menuitem, (winid, int NDECL((*)), const char *)); STATIC_DCL char FDECL(here_cmd_menu, (BOOLEAN_P)); @@ -197,6 +207,19 @@ STATIC_DCL char *NDECL(parse); STATIC_DCL void FDECL(show_direction_keys, (winid, CHAR_P, BOOLEAN_P)); STATIC_DCL boolean FDECL(help_dir, (CHAR_P, int, const char *)); +static const char *readchar_queue = ""; +static coord clicklook_cc; +/* for rejecting attempts to use wizard mode commands */ +/*JP +static const char unavailcmd[] = "Unavailable command '%s'."; +*/ +static const char unavailcmd[] = "'%s'ƒRƒ}ƒ“ƒh‚ÍŽg‚¦‚È‚¢D"; +/* for rejecting #if !SHELL, !SUSPEND */ +/*JP +static const char cmdnotavail[] = "'%s' command not available."; +*/ +static const char cmdnotavail[] = "'%s'ƒRƒ}ƒ“ƒh‚Í—˜—p‚Å‚«‚Ü‚¹‚ñD"; + STATIC_PTR int doprev_message(VOID_ARGS) { @@ -287,6 +310,8 @@ pgetchar() /* courtesy of aeb@cwi.nl */ { register int ch; + if (iflags.debug_fuzzer) + return randomkey(); if (!(ch = popch())) ch = nhgetch(); return (char) ch; @@ -359,54 +384,219 @@ doextcmd(VOID_ARGS) return retval; } -/* here after #? - now list all full-word commands */ +/* here after #? - now list all full-word commands and provid + some navigation capability through the long list */ int doextlist(VOID_ARGS) { register const struct ext_func_tab *efp; - char buf[BUFSZ]; - winid datawin; - char ch = cmd_from_func(doextcmd); + char buf[BUFSZ], searchbuf[BUFSZ], promptbuf[QBUFSZ]; + winid menuwin; + anything any; + menu_item *selected; + int n, pass; + int menumode = 0, menushown[2], onelist = 0; + boolean redisplay = TRUE, search = FALSE; +#if 0 /*JP*/ + static const char *headings[] = { "Extended commands", + "Debugging Extended Commands" }; +#else + static const char *headings[] = { "Šg’£ƒRƒ}ƒ“ƒh", + "ƒfƒoƒbƒOŠg’£ƒRƒ}ƒ“ƒh" }; +#endif - datawin = create_nhwindow(NHW_TEXT); - putstr(datawin, 0, ""); -/*JP - putstr(datawin, 0, " Extended Commands List"); -*/ - putstr(datawin, 0, " Šg’£ƒRƒ}ƒ“ƒhˆê——"); - putstr(datawin, 0, ""); - if (ch) { + searchbuf[0] = '\0'; + menuwin = create_nhwindow(NHW_MENU); + + while (redisplay) { + redisplay = FALSE; + any = zeroany; + start_menu(menuwin); #if 0 /*JP*/ - Sprintf(buf, " Press '%s', then type:", - visctrl(ch)); + add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + "Extended Commands List", MENU_UNSELECTED); #else - Sprintf(buf, " '%s'‚ð‰Ÿ‚µ‚½‚ ‚ƃ^ƒCƒv‚¹‚æ:", - visctrl(ch)); + add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + "Šg’£ƒRƒ}ƒ“ƒhˆê——", MENU_UNSELECTED); #endif - putstr(datawin, 0, buf); - putstr(datawin, 0, ""); - } + add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + "", MENU_UNSELECTED); - for (efp = extcmdlist; efp->ef_txt; efp++) { - if (!wizard && (efp->flags & WIZMODECMD)) - continue; - Sprintf(buf, " %-15s %c %s.", - efp->ef_txt, - (efp->flags & AUTOCOMPLETE) ? '*' : ' ', - efp->ef_desc); - putstr(datawin, 0, buf); +#if 0 /*JP*/ + Strcpy(buf, menumode ? "Show" : "Hide"); + Strcat(buf, " commands that don't autocomplete"); + if (!menumode) + Strcat(buf, " (those not marked with [A])"); +#else + Strcpy(buf, "Ž©“®•âŠ®‚³‚ê‚È‚¢ƒRƒ}ƒ“ƒh‚ð"); + Strcat(buf, menumode ? "•\Ž¦‚·‚é" : "•\Ž¦‚µ‚È‚¢ (‚±‚ê‚ç‚Í[A]ƒ}[ƒN‚ª‚‚©‚È‚¢)"); +#endif + any.a_int = 1; + add_menu(menuwin, NO_GLYPH, &any, 'a', 0, ATR_NONE, buf, + MENU_UNSELECTED); + + if (!*searchbuf) { + any.a_int = 2; + /* was 's', but then using ':' handling within the interface + would only examine the two or three meta entries, not the + actual list of extended commands shown via separator lines; + having ':' as an explicit selector overrides the default + menu behavior for it; we retain 's' as a group accelerator */ +#if 0 /*JP*/ + add_menu(menuwin, NO_GLYPH, &any, ':', 's', ATR_NONE, + "Search extended commands", MENU_UNSELECTED); +#else + add_menu(menuwin, NO_GLYPH, &any, ':', 's', ATR_NONE, + "Šg’£ƒRƒ}ƒ“ƒh‚ðŒŸõ‚·‚é", MENU_UNSELECTED); +#endif + } else { +#if 0 /*JP*/ + Strcpy(buf, "Show all, clear search"); +#else + Strcpy(buf, "‘S‚Ä•\Ž¦; ŒŸõ‚ðƒNƒŠƒA"); +#endif + if (strlen(buf) + strlen(searchbuf) + strlen(" (\"\")") < QBUFSZ) + Sprintf(eos(buf), " (\"%s\")", searchbuf); + any.a_int = 3; + /* specifying ':' as a group accelerator here is mostly a + statement of intent (we'd like to accept it as a synonym but + also want to hide it from general menu use) because it won't + work for interfaces which support ':' to search; use as a + general menu command takes precedence over group accelerator */ + add_menu(menuwin, NO_GLYPH, &any, 's', ':', ATR_NONE, + buf, MENU_UNSELECTED); + } + if (wizard) { + any.a_int = 4; +#if 0 /*JP*/ + add_menu(menuwin, NO_GLYPH, &any, 'z', 0, ATR_NONE, + onelist ? "Show debugging commands in separate section" + : "Show all alphabetically, including debugging commands", + MENU_UNSELECTED); +#else + add_menu(menuwin, NO_GLYPH, &any, 'z', 0, ATR_NONE, + onelist ? "ƒfƒoƒbƒOƒRƒ}ƒ“ƒh‚͕ʂ̐߂ɕ\Ž¦‚·‚é" + : "ƒfƒoƒbƒOƒRƒ}ƒ“ƒh‚ðŠÜ‚Þ‘S‚ẴRƒ}ƒ“ƒh‚ðƒAƒ‹ƒtƒ@ƒxƒbƒg‡‚É•\Ž¦‚·‚é", + MENU_UNSELECTED); +#endif + } + any = zeroany; + add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + "", MENU_UNSELECTED); + menushown[0] = menushown[1] = 0; + n = 0; + for (pass = 0; pass <= 1; ++pass) { + /* skip second pass if not in wizard mode or wizard mode + commands are being integrated into a single list */ + if (pass == 1 && (onelist || !wizard)) + break; + for (efp = extcmdlist; efp->ef_txt; efp++) { + int wizc; + + if ((efp->flags & CMD_NOT_AVAILABLE) != 0) + continue; + /* if hiding non-autocomplete commands, skip such */ + if (menumode == 1 && (efp->flags & AUTOCOMPLETE) == 0) + continue; + /* if searching, skip this command if it doesn't match */ + if (*searchbuf + /* first try case-insensitive substring match */ + && !strstri(efp->ef_txt, searchbuf) + && !strstri(efp->ef_desc, searchbuf) + /* wildcard support; most interfaces use case-insensitve + pmatch rather than regexp for menu searching */ + && !pmatchi(searchbuf, efp->ef_txt) + && !pmatchi(searchbuf, efp->ef_desc)) + continue; + /* skip wizard mode commands if not in wizard mode; + when showing two sections, skip wizard mode commands + in pass==0 and skip other commands in pass==1 */ + wizc = (efp->flags & WIZMODECMD) != 0; + if (wizc && !wizard) + continue; + if (!onelist && pass != wizc) + continue; + + /* We're about to show an item, have we shown the menu yet? + Doing menu in inner loop like this on demand avoids a + heading with no subordinate entries on the search + results menu. */ + if (!menushown[pass]) { + Strcpy(buf, headings[pass]); + add_menu(menuwin, NO_GLYPH, &any, 0, 0, + iflags.menu_headings, buf, MENU_UNSELECTED); + menushown[pass] = 1; + } + Sprintf(buf, " %-14s %-3s %s", + efp->ef_txt, + (efp->flags & AUTOCOMPLETE) ? "[A]" : " ", + efp->ef_desc); + add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + buf, MENU_UNSELECTED); + ++n; + } + if (n) + add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + "", MENU_UNSELECTED); + } + if (*searchbuf && !n) +#if 0 /*JP*/ + add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + "no matches", MENU_UNSELECTED); +#else + add_menu(menuwin, NO_GLYPH, &any, 0, 0, ATR_NONE, + "ˆê’v‚È‚µ", MENU_UNSELECTED); +#endif + + end_menu(menuwin, (char *) 0); + n = select_menu(menuwin, PICK_ONE, &selected); + if (n > 0) { + switch (selected[0].item.a_int) { + case 1: /* 'a': toggle show/hide non-autocomplete */ + menumode = 1 - menumode; /* toggle 0 -> 1, 1 -> 0 */ + redisplay = TRUE; + break; + case 2: /* ':' when not searching yet: enable search */ + search = TRUE; + break; + case 3: /* 's' when already searching: disable search */ + search = FALSE; + searchbuf[0] = '\0'; + redisplay = TRUE; + break; + case 4: /* 'z': toggle showing wizard mode commands separately */ + search = FALSE; + searchbuf[0] = '\0'; + onelist = 1 - onelist; /* toggle 0 -> 1, 1 -> 0 */ + redisplay = TRUE; + break; + } + free((genericptr_t) selected); + } else { + search = FALSE; + searchbuf[0] = '\0'; + } + if (search) { +#if 0 /*JP*/ + Strcpy(promptbuf, "Extended command list search phrase"); + Strcat(promptbuf, "?"); +#else + Strcpy(promptbuf, "Šg’£ƒRƒ}ƒ“ƒh‚ÌŒŸõ•¶Žš—ñ‚Í?"); +#endif + getlin(promptbuf, searchbuf); + (void) mungspaces(searchbuf); + if (searchbuf[0] == '\033') + searchbuf[0] = '\0'; + if (*searchbuf) + redisplay = TRUE; + search = FALSE; + } } - putstr(datawin, 0, ""); -/*JP - putstr(datawin, 0, " Commands marked with a * will be autocompleted."); -*/ - putstr(datawin, 0, " *•t‚«‚̃Rƒ}ƒ“ƒh‚ÍŽ©“®•âŠ®‚³‚ê‚Ü‚·D"); - display_nhwindow(datawin, FALSE); - destroy_nhwindow(datawin); + destroy_nhwindow(menuwin); return 0; } -#ifdef TTY_GRAPHICS +#if defined(TTY_GRAPHICS) || defined(CURSES_GRAPHICS) #define MAX_EXT_CMD 200 /* Change if we ever have more ext cmds */ /* @@ -443,7 +633,8 @@ extcmd_via_menu() any = zeroany; /* populate choices */ for (efp = extcmdlist; efp->ef_txt; efp++) { - if (!(efp->flags & AUTOCOMPLETE) + if ((efp->flags & CMD_NOT_AVAILABLE) + || !(efp->flags & AUTOCOMPLETE) || (!wizard && (efp->flags & WIZMODECMD))) continue; if (!matchlevel || !strncmp(efp->ef_txt, cbuf, matchlevel)) { @@ -691,11 +882,7 @@ wiz_wish(VOID_ARGS) /* Unlimited wishes for debug mode by Paul Polderman */ flags.verbose = save_verbose; (void) encumber_msg(); } else -/*JP - pline("Unavailable command '%s'.", -*/ - pline("'%s'ƒRƒ}ƒ“ƒh‚ÍŽg‚¦‚È‚¢D", - visctrl((int) cmd_from_func(wiz_wish))); + pline(unavailcmd, visctrl((int) cmd_from_func(wiz_wish))); return 0; } @@ -705,47 +892,103 @@ wiz_identify(VOID_ARGS) { if (wizard) { iflags.override_ID = (int) cmd_from_func(wiz_identify); - if (display_inventory((char *) 0, TRUE) == -1) - identify_pack(0, FALSE); + /* command remapping might leave #wizidentify as the only way + to invoke us, in which case cmd_from_func() will yield NUL; + it won't matter to display_inventory()/display_pickinv() + if ^I invokes some other command--what matters is that + display_pickinv() and xname() see override_ID as nonzero */ + if (!iflags.override_ID) + iflags.override_ID = C('I'); + (void) display_inventory((char *) 0, FALSE); iflags.override_ID = 0; } else -/*JP - pline("Unavailable command '%s'.", -*/ - pline("'%s'ƒRƒ}ƒ“ƒh‚ÍŽg‚¦‚È‚¢D", - visctrl((int) cmd_from_func(wiz_identify))); + pline(unavailcmd, visctrl((int) cmd_from_func(wiz_identify))); return 0; } +/* #wizmakemap - discard current dungeon level and replace with a new one */ STATIC_PTR int wiz_makemap(VOID_ARGS) { - /* FIXME: doesn't handle riding */ if (wizard) { struct monst *mtmp; + boolean was_in_W_tower = In_W_tower(u.ux, u.uy, &u.uz); rm_mapseen(ledger_no(&u.uz)); - for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) + for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) { + if (mtmp->isgd) { /* vault is going away; get rid of guard */ + mtmp->isgd = 0; + mongone(mtmp); + } + if (DEADMONSTER(mtmp)) + continue; if (mtmp->isshk) setpaid(mtmp); + /* TODO? + * Reduce 'born' tally for each monster about to be discarded + * by savelev(), otherwise replacing heavily populated levels + * tends to make their inhabitants become extinct. + */ + } if (Punished) { ballrelease(FALSE); unplacebc(); } - check_special_room(TRUE); - dmonsfree(); + /* reset lock picking unless it's for a carried container */ + maybe_reset_pick((struct obj *) 0); + /* reset interrupted digging if it was taking place on this level */ + if (on_level(&context.digging.level, &u.uz)) + (void) memset((genericptr_t) &context.digging, 0, + sizeof (struct dig_info)); + /* reset cached targets */ + iflags.travelcc.x = iflags.travelcc.y = 0; /* travel destination */ + context.polearm.hitmon = (struct monst *) 0; /* polearm target */ + /* escape from trap */ + reset_utrap(FALSE); + check_special_room(TRUE); /* room exit */ + u.ustuck = (struct monst *) 0; + u.uswallow = 0; + u.uinwater = 0; + u.uundetected = 0; /* not hidden, even if means are available */ + dmonsfree(); /* purge dead monsters from 'fmon' */ + /* keep steed and other adjacent pets after releasing them + from traps, stopping eating, &c as if hero were ascending */ + keepdogs(TRUE); /* (pets-only; normally we'd be using 'FALSE' here) */ + + /* discard current level; "saving" is used to release dynamic data */ savelev(-1, ledger_no(&u.uz), FREE_SAVE); + /* create a new level; various things like bestowing a guardian + angel on Astral or setting off alarm on Ft.Ludios are handled + by goto_level(do.c) so won't occur for replacement levels */ mklev(); + vision_reset(); vision_full_recalc = 1; cls(); - (void) safe_teleds(TRUE); + /* was using safe_teleds() but that doesn't honor arrival region + on levels which have such; we don't force stairs, just area */ + u_on_rndspot((u.uhave.amulet ? 1 : 0) /* 'going up' flag */ + | (was_in_W_tower ? 2 : 0)); + losedogs(); + /* u_on_rndspot() might pick a spot that has a monster, or losedogs() + might pick the hero's spot (only if there isn't already a monster + there), so we might have to move hero or the co-located monster */ + if ((mtmp = m_at(u.ux, u.uy)) != 0) + u_collide_m(mtmp); + initrack(); if (Punished) { unplacebc(); placebc(); } docrt(); flush_screen(1); + deliver_splev_message(); /* level entry */ + check_special_room(FALSE); /* room entry */ +#ifdef INSURANCE + save_currentstate(); +#endif + } else { + pline(unavailcmd, "#wizmakemap"); } return 0; } @@ -767,11 +1010,7 @@ wiz_map(VOID_ARGS) HConfusion = save_Hconf; HHallucination = save_Hhallu; } else -/*JP - pline("Unavailable command '%s'.", -*/ - pline("'%s'ƒRƒ}ƒ“ƒh‚ÍŽg‚¦‚È‚¢D", - visctrl((int) cmd_from_func(wiz_map))); + pline(unavailcmd, visctrl((int) cmd_from_func(wiz_map))); return 0; } @@ -782,11 +1021,7 @@ wiz_genesis(VOID_ARGS) if (wizard) (void) create_particular(); else -/*JP - pline("Unavailable command '%s'.", -*/ - pline("'%s'ƒRƒ}ƒ“ƒh‚ÍŽg‚¦‚È‚¢D", - visctrl((int) cmd_from_func(wiz_genesis))); + pline(unavailcmd, visctrl((int) cmd_from_func(wiz_genesis))); return 0; } @@ -797,11 +1032,7 @@ wiz_where(VOID_ARGS) if (wizard) (void) print_dungeon(FALSE, (schar *) 0, (xchar *) 0); else -/*JP - pline("Unavailable command '%s'.", -*/ - pline("'%s'ƒRƒ}ƒ“ƒh‚ÍŽg‚¦‚È‚¢D", - visctrl((int) cmd_from_func(wiz_where))); + pline(unavailcmd, visctrl((int) cmd_from_func(wiz_where))); return 0; } @@ -812,11 +1043,7 @@ wiz_detect(VOID_ARGS) if (wizard) (void) findit(); else -/*JP - pline("Unavailable command '%s'.", -*/ - pline("'%s'ƒRƒ}ƒ“ƒh‚ÍŽg‚¦‚È‚¢D", - visctrl((int) cmd_from_func(wiz_detect))); + pline(unavailcmd, visctrl((int) cmd_from_func(wiz_detect))); return 0; } @@ -827,26 +1054,7 @@ wiz_level_tele(VOID_ARGS) if (wizard) level_tele(); else -/*JP - pline("Unavailable command '%s'.", -*/ - pline("'%s'ƒRƒ}ƒ“ƒh‚ÍŽg‚¦‚È‚¢D", - visctrl((int) cmd_from_func(wiz_level_tele))); - return 0; -} - -/* #monpolycontrol command - choose new form for shapechangers, polymorphees */ -STATIC_PTR int -wiz_mon_polycontrol(VOID_ARGS) -{ - iflags.mon_polycontrol = !iflags.mon_polycontrol; -#if 0 /*JP*/ - pline("Monster polymorph control is %s.", - iflags.mon_polycontrol ? "on" : "off"); -#else - pline("‰ö•¨‚̕ω»§Œä: %s", - iflags.mon_polycontrol ? "ƒIƒ“" : "ƒIƒt"); -#endif + pline(unavailcmd, visctrl((int) cmd_from_func(wiz_level_tele))); return 0; } @@ -855,7 +1063,7 @@ STATIC_PTR int wiz_level_change(VOID_ARGS) { char buf[BUFSZ] = DUMMY; - int newlevel; + int newlevel = 0; int ret; /*JP @@ -913,6 +1121,11 @@ wiz_level_change(VOID_ARGS) STATIC_PTR int wiz_panic(VOID_ARGS) { + if (iflags.debug_fuzzer) { + u.uhp = u.uhpmax = 1000; + u.uen = u.uenmax = 1000; + return 0; + } /*JP if (yn("Do you want to call panic() and end your game?") == 'y') */ @@ -1019,7 +1232,7 @@ wiz_show_wmodes(VOID_ARGS) int x, y; char row[COLNO + 1]; struct rm *lev; - boolean istty = !strcmp(windowprocs.name, "tty"); + boolean istty = WINDOWPORT("tty"); win = create_nhwindow(NHW_TEXT); if (istty) @@ -1390,7 +1603,19 @@ wiz_intrinsic(VOID_ARGS) make_vomiting(newtimeout, FALSE); pline1(buf); break; + case WARN_OF_MON: + if (!Warn_of_mon) { + context.warntype.speciesidx = PM_GRID_BUG; + context.warntype.species + = &mons[context.warntype.speciesidx]; + } + goto def_feedback; + case LEVITATION: + case FLYING: + float_vs_flight(); + /*FALLTHRU*/ default: + def_feedback: pline("Timeout for %s %s %d.", propertynames[i].prop_name, oldtimeout ? "increased by" : "set to", amt); incr_itimeout(&u.uprops[p].intrinsic, amt); @@ -1402,8 +1627,7 @@ wiz_intrinsic(VOID_ARGS) free((genericptr_t) pick_list); doredraw(); } else - pline("Unavailable command '%s'.", - visctrl((int) cmd_from_func(wiz_intrinsic))); + pline(unavailcmd, visctrl((int) cmd_from_func(wiz_intrinsic))); return 0; } @@ -1524,6 +1748,7 @@ doterrain(VOID_ARGS) /* -enlightenment and conduct- */ static winid en_win = WIN_ERR; +static boolean en_via_menu = FALSE; #if 0 /*JP*/ static const char You_[] = "You ", are[] = "are ", were[] = "were ", have[] = "have ", had[] = "had ", can[] = "can ", @@ -1573,6 +1798,19 @@ static const char have_been[] = "have been ", have_never[] = "have never ", #endif static void +enlght_out(buf) +const char *buf; +{ + if (en_via_menu) { + anything any; + + any = zeroany; + add_menu(en_win, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); + } else + putstr(en_win, 0, buf); +} + +static void enlght_line(start, middle, end, ps) const char *start, *middle, *end, *ps; { @@ -1582,7 +1820,7 @@ const char *start, *middle, *end, *ps; Sprintf(buf, " %s%s%s%s.", start, middle, end, ps); */ Sprintf(buf, "%s%s%s%sD", start, middle, end, ps); - putstr(en_win, 0, buf); + enlght_out(buf); } /* format increased chance to hit or damage or defense (Protection) */ @@ -1748,6 +1986,11 @@ int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */ { char buf[BUFSZ], tmpbuf[BUFSZ]; + en_win = create_nhwindow(NHW_MENU); + en_via_menu = !final; + if (en_via_menu) + start_menu(en_win); + Strcpy(tmpbuf, plname); *tmpbuf = highc(*tmpbuf); /* same adjustment as bottom line */ /* as in background_enlightenment, when poly'd we need to use the saved @@ -1765,13 +2008,14 @@ int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */ tmpbuf); #endif - en_win = create_nhwindow(NHW_MENU); /* title */ - putstr(en_win, 0, buf); /* "Conan the Archeologist's attributes:" */ + enlght_out(buf); /* "Conan the Archeologist's attributes:" */ /* background and characteristics; ^X or end-of-game disclosure */ if (mode & BASICENLIGHTENMENT) { - /* role, race, alignment, deities */ + /* role, race, alignment, deities, dungeon level, time, experience */ background_enlightenment(mode, final); + /* hit points, energy points, armor class, gold */ + basics_enlightenment(mode, final); /* strength, dexterity, &c */ characteristics_enlightenment(mode, final); } @@ -1787,7 +2031,17 @@ int final; /* ENL_GAMEINPROGRESS:0, ENL_GAMEOVERALIVE, ENL_GAMEOVERDEAD */ /* intrinsics and other traditional enlightenment feedback */ attributes_enlightenment(mode, final); } - display_nhwindow(en_win, TRUE); + + if (!en_via_menu) { + display_nhwindow(en_win, TRUE); + } else { + menu_item *selected = 0; + + end_menu(en_win, (char *) 0); + if (select_menu(en_win, PICK_NONE, &selected) > 0) + free((genericptr_t) selected); + en_via_menu = FALSE; + } destroy_nhwindow(en_win); en_win = WIN_ERR; } @@ -1809,11 +2063,11 @@ int final; role_titl = (innategend && urole.name.f) ? urole.name.f : urole.name.m; rank_titl = rank_of(u.ulevel, Role_switch, innategend); - putstr(en_win, 0, ""); /* separator after title */ + enlght_out(""); /* separator after title */ /*JP - putstr(en_win, 0, "Background:"); + enlght_out("Background:"); */ - putstr(en_win, 0, "”wŒiî•ñ:"); + enlght_out("”wŒiî•ñ:"); /* if polymorphed, report current shape before underlying role; will be repeated as first status: "you are transformed" and also @@ -1878,7 +2132,7 @@ int final; tmpbuf, urace.adj, role_titl, rank_titl); #endif } - you_are(buf, ""); + you_are(buf, ""); /* report alignment (bypass you_are() in order to omit ending period); adverb is used to distinguish between temporary change (helm of opp. @@ -1917,7 +2171,7 @@ int final; : "", u_gname(), !final ? iru : ita); #endif - putstr(en_win, 0, buf); + enlght_out(buf); /* show the rest of this game's pantheon (finishes previous sentence) [appending "also Moloch" at the end would allow for straightforward trailing "and" on all three aligned entries but looks too verbose] */ @@ -1944,8 +2198,8 @@ int final; align_str(A_NEUTRAL), (u.ualign.type != A_CHAOTIC) ? "‚¨‚æ‚Ñ" : ""); #endif -#if 0 /*JP*/ if (u.ualign.type != A_CHAOTIC) +#if 0 /*JP*/ Sprintf(eos(buf), " %s (%s)", align_gname(A_CHAOTIC), align_str(A_CHAOTIC)); #else @@ -1958,7 +2212,7 @@ int final; #else Sprintf(eos(buf), "‚ƑΗ§‚µ‚Ä%sD", !final ? iru : ita); #endif - putstr(en_win, 0, buf); + enlght_out(buf); /* show original alignment,gender,race,role if any have been changed; giving separate message for temporary alignment change bypasses need @@ -1973,14 +2227,15 @@ int final; Sprintf(buf, "actually %s", align_str(u.ualignbase[A_CURRENT])); */ Sprintf(buf, "ŽÀÛ‚É‚Í%s", align_str(u.ualignbase[A_CURRENT])); -/*JP +#if 0 /*JP*/ you_are(buf, ""); -*/ +#else enl_msg(buf, "‚Ä‚¢‚é", "‚Ä‚¢‚½", "", ""); +#endif difalgn &= ~1; /* suppress helm from "started out " message */ } if (difgend || difalgn) { /* sex change or perm align change or both */ -#if 0 /*JP*/ +#if 0 /*JP:T*/ Sprintf(buf, " You started out %s%s%s.", difgend ? genders[flags.initgend].adj : "", (difgend && difalgn) ? " and " : "", @@ -1991,50 +2246,179 @@ int final; (difgend && difalgn) ? "‚©‚Â" : "", difalgn ? align_str(u.ualignbase[A_ORIGINAL]) : ""); #endif - putstr(en_win, 0, buf); + enlght_out(buf); } + + /* 3.6.2: dungeon level, so that ^X really has all status info as + claimed by the comment below; this reveals more information than + the basic status display, but that's one of the purposes of ^X; + similar information is revealed by #overview; the "You died in + " given by really_done() is more rudimentary than this */ + *buf = *tmpbuf = '\0'; + if (In_endgame(&u.uz)) { + int egdepth = observable_depth(&u.uz); + + (void) endgamelevelname(tmpbuf, egdepth); +#if 0 /*JP*/ + Sprintf(buf, "in the endgame, on the %s%s", + !strncmp(tmpbuf, "Plane", 5) ? "Elemental " : "", tmpbuf); +#else + Sprintf(buf, "ÅIŽŽ—û‚Ì%s", tmpbuf); +#endif + } else if (Is_knox(&u.uz)) { + /* this gives away the fact that the knox branch is only 1 level */ +/*JP + Sprintf(buf, "on the %s level", dungeons[u.uz.dnum].dname); +*/ + Sprintf(buf, "%s", dungeons[u.uz.dnum].dname); + /* TODO? maybe phrase it differently when actually inside the fort, + if we're able to determine that (not trivial) */ + } else { + char dgnbuf[QBUFSZ]; + + Strcpy(dgnbuf, dungeons[u.uz.dnum].dname); +#if 0 /*JP*/ + if (!strncmpi(dgnbuf, "The ", 4)) + *dgnbuf = lowc(*dgnbuf); +#endif +#if 0 /*JP*/ + Sprintf(tmpbuf, "level %d", + In_quest(&u.uz) ? dunlev(&u.uz) : depth(&u.uz)); +#else + if (In_quest(&u.uz)) { + Sprintf(tmpbuf, "‘æ%dŠK‘w", dunlev(&u.uz)); + } else { + Sprintf(tmpbuf, "’n‰º%dŠK", depth(&u.uz)); + } +#endif + /* TODO? maybe extend this bit to include various other automatic + annotations from the dungeon overview code */ + if (Is_rogue_level(&u.uz)) +/*JP + Strcat(tmpbuf, ", a primitive area"); +*/ + Strcat(tmpbuf, ", ’Pƒ‚Ȑ¢ŠE"); + else if (Is_bigroom(&u.uz) && !Blind) +/*JP + Strcat(tmpbuf, ", a very big room"); +*/ + Strcat(tmpbuf, ", ‚Æ‚Ä‚à‘å‚«‚È•”‰®"); +#if 0 /*JP*/ + Sprintf(buf, "in %s, on %s", dgnbuf, tmpbuf); +#else + Sprintf(buf, "%s‚Ì%s", dgnbuf, tmpbuf); +#endif + } + you_are(buf, ""); + + /* this is shown even if the 'time' option is off */ + if (moves == 1L) { +#if 0 /*JP*/ + you_have("just started your adventure", ""); +#else + enlght_line(You_, "", "–`Œ¯‚ðŠJŽn‚µ‚½‚Æ‚±‚낾", ""); +#endif + } else { + /* 'turns' grates on the nerves in this context... */ +/*JP + Sprintf(buf, "the dungeon %ld turn%s ago", moves, plur(moves)); +*/ + Sprintf(buf, "%ldƒ^[ƒ“‘O‚É–À‹{‚É“ü‚Á‚½", moves); + /* same phrasing for current and final: "entered" is unconditional */ +#if 0 /*JP*/ + enlght_line(You_, "entered ", buf, ""); +#else + enlght_line(You_, "", buf, ""); +#endif + } + if (!Upolyd) { + /* flags.showexp does not matter */ + /* experience level is already shown above */ +#if 0 /*JP*/ + Sprintf(buf, "%-1ld experience point%s", u.uexp, plur(u.uexp)); +#else + Sprintf(buf, "ŒoŒ±’l%-1ldƒ|ƒCƒ“ƒg", u.uexp); +#endif + if (wizard) { + if (u.ulevel < 30) { + int ulvl = (int) u.ulevel; + long nxtlvl = newuexp(ulvl); + /* long oldlvl = (ulvl > 1) ? newuexp(ulvl - 1) : 0; */ + +#if 0 /*JP*/ + Sprintf(eos(buf), ", %ld %s%sneeded to attain level %d", + (nxtlvl - u.uexp), (u.uexp > 0) ? "more " : "", + !final ? "" : "were ", (ulvl + 1)); +#else + Sprintf(eos(buf), "(ƒŒƒxƒ‹%d‚Ü‚Å%ldƒ|ƒCƒ“ƒg)", + (ulvl + 1), (nxtlvl - u.uexp)); +#endif + } + } + you_have(buf, ""); + } +#ifdef SCORE_ON_BOTL + if (flags.showscore) { + /* describes what's shown on status line, which is an approximation; + only show it here if player has the 'showscore' option enabled */ +#if 0 /*JP*/ + Sprintf(buf, "%ld%s", botl_score(), + !final ? "" : " before end-of-game adjustments"); + enl_msg("Your score ", "is ", "was ", buf, ""); +#else + Sprintf(buf, "%s%ld", botl_score(), + !final ? "" : "ƒQ[ƒ€I—¹Žž‚Ì’²®‘O‚Í"); + enl_msg("‚ ‚È‚½‚̃XƒRƒA‚Í", "‚Å‚ ‚é", "‚Å‚ ‚Á‚½", buf, ""); +#endif + } +#endif } -/* characteristics: expanded version of bottom line strength, dexterity, &c; - [3.6.1: now includes all status info (except things already shown in the - 'background' section), primarily so that blind players can suppress the - status line(s) altogether and use ^X feedback on demand to view HP, &c] */ +/* hit points, energy points, armor class -- essential information which + doesn't fit very well in other categories */ +/*ARGSUSED*/ STATIC_OVL void -characteristics_enlightenment(mode, final) -int mode; +basics_enlightenment(mode, final) +int mode UNUSED; int final; { + static char Power[] = "energy points (spell power)"; char buf[BUFSZ]; - int hp = Upolyd ? u.mh : u.uhp; - int hpmax = Upolyd ? u.mhmax : u.uhpmax; + int pw = u.uen, hp = (Upolyd ? u.mh : u.uhp), + pwmax = u.uenmax, hpmax = (Upolyd ? u.mhmax : u.uhpmax); - putstr(en_win, 0, ""); /* separator after background */ - putstr(en_win, 0, + enlght_out(""); /* separator after background */ /*JP - final ? "Final Characteristics:" : "Current Characteristics:"); + enlght_out("Basics:"); */ - final ? "ÅI‘®«F" : "Œ»Ý‚Ì‘®«F"); + enlght_out("Šî–{:"); if (hp < 0) hp = 0; -/*JP - Sprintf(buf, "%d hit points (max:%d)", hp, hpmax); -*/ + /* "1 out of 1" rather than "all" if max is only 1; should never happen */ +#if 0 /*JP*/ + if (hp == hpmax && hpmax > 1) + Sprintf(buf, "all %d hit points", hpmax); + else + Sprintf(buf, "%d out of %d hit point%s", hp, hpmax, plur(hpmax)); +#else Sprintf(buf, "%dƒqƒbƒgƒ|ƒCƒ“ƒg(Å‘å:%d)", hp, hpmax); +#endif you_have(buf, ""); -/*JP - Sprintf(buf, "%d magic power (max:%d)", u.uen, u.uenmax); -*/ - Sprintf(buf, "%d–‚—̓|ƒCƒ“ƒg(Å‘å:%d)", u.uen, u.uenmax); + /* low max energy is feasible, so handle couple of extra special cases */ +#if 0 /*JP*/ + if (pwmax == 0 || (pw == pwmax && pwmax == 2)) /* both: "all 2" is silly */ + Sprintf(buf, "%s %s", !pwmax ? "no" : "both", Power); + else if (pw == pwmax && pwmax > 2) + Sprintf(buf, "all %d %s", pwmax, Power); + else + Sprintf(buf, "%d out of %d %s", pw, pwmax, Power); +#else + Sprintf(buf, "%d–‚—̓|ƒCƒ“ƒg(Å‘å:%d)", pw, pwmax); +#endif you_have(buf, ""); - Sprintf(buf, "%d", u.uac); -/*JP - enl_msg("Your armor class ", "is ", "was ", buf, ""); -*/ - enl_msg("‚ ‚È‚½‚Ì–hŒä’l‚Í", "‚Å‚ ‚é", "‚Å‚ ‚Á‚½", buf, ""); - if (Upolyd) { switch (mons[u.umonnum].mlevel) { case 0: @@ -2057,42 +2441,94 @@ int final; Sprintf(buf, "HD%d", mons[u.umonnum].mlevel); break; } - } else { - /* flags.showexp does not matter */ - /* experience level is already shown in the Background section */ -#if 0 /*JP*/ - Sprintf(buf, "%-1ld experience point%s", - u.uexp, plur(u.uexp)); -#else - Sprintf(buf, "ŒoŒ±’l%-1ldƒ|ƒCƒ“ƒg", - u.uexp); -#endif + you_have(buf, ""); } - you_have(buf, ""); - /* this is shown even if the 'time' option is off */ + Sprintf(buf, "%d", u.uac); /*JP - Sprintf(buf, "the dungeon %ld turn%s ago", moves, plur(moves)); + enl_msg("Your armor class ", "is ", "was ", buf, ""); */ - Sprintf(buf, "%ldƒ^[ƒ“‘O‚É–À‹{‚É“ü‚Á‚½", moves); - /* same phrasing at end of game: "entered" is unconditional */ - enlght_line(You_, "", buf, ""); + enl_msg("‚ ‚È‚½‚Ì–hŒä’l‚Í", "‚Å‚ ‚é", "‚Å‚ ‚Á‚½", buf, ""); -#ifdef SCORE_ON_BOTL - if (flags.showscore) { - /* describes what's shown on status line, which is an approximation; - only show it here if player has the 'showscore' option enabled */ -#if 0 /*JP*/ - Sprintf(buf, "%ld%s", botl_score(), - !final ? "" : " before end-of-game adjustments"); - enl_msg("Your score ", "is ", "was ", buf, ""); + /* gold; similar to doprgold(#seegold) but without shop billing info; + same amount as shown on status line which ignores container contents */ + { +/*JP + static const char Your_wallet[] = "Your wallet "; +*/ + static const char Your_wallet[] = "‚ ‚È‚½‚̍à•z"; + long umoney = money_cnt(invent); + + if (!umoney) { +/*JP + enl_msg(Your_wallet, "is ", "was ", "empty", ""); +*/ + enl_msg(Your_wallet, "‚Å‚ ‚é", "‚Å‚¾‚Á‚½", "‚Í‹ó", ""); + } else { +#if 0 /*JP:T*/ + Sprintf(buf, "%ld %s", umoney, currency(umoney)); + enl_msg(Your_wallet, "contains ", "contained ", buf, ""); #else - Sprintf(buf, "%s%ld", botl_score(), - !final ? "" : "ƒQ[ƒ€I—¹Žž‚Ì’²®‘O‚Í"); - enl_msg("‚ ‚È‚½‚̃XƒRƒA‚Í", "‚Å‚ ‚é", "‚Å‚ ‚Á‚½", buf, ""); + Sprintf(buf, "‚É‚Í%ld%s", umoney, currency(umoney)); + enl_msg(Your_wallet, "“ü‚Á‚Ä‚¢‚é", "“ü‚Á‚Ä‚¢‚½", buf, ""); #endif + } } + + if (flags.pickup) { + char ocl[MAXOCLASSES + 1]; + +#if 0 /*JP*//*Œã‚ɉñ‚·*/ + Strcpy(buf, "on"); +#endif + oc_to_str(flags.pickup_types, ocl); +#if 0 /*JP*/ + Sprintf(eos(buf), " for %s%s%s", + *ocl ? "'" : "", *ocl ? ocl : "all types", *ocl ? "'" : ""); +#else + Sprintf(buf, "%s%s%s", + *ocl ? "'" : "", *ocl ? ocl : "‘S‚Ä‚ÌŽí—Þ", *ocl ? "'" : ""); #endif + if (flags.pickup_thrown && *ocl) /* *ocl: don't show if 'all types' */ +/*JP + Strcat(buf, " plus thrown"); +*/ + Strcat(buf, "‚ɉÁ‚¦‚Ä“Š‚°‚é‚à‚Ì"); + if (iflags.autopickup_exceptions[AP_GRAB] + || iflags.autopickup_exceptions[AP_LEAVE]) +/*JP + Strcat(buf, ", with exceptions"); +*/ + Strcat(buf, "(—áŠO‚ ‚è)"); +#if 1 /*JP*/ + Strcpy(buf, "‚ɑ΂µ‚ăIƒ“"); +#endif + + } else +/*JP + Strcpy(buf, "off"); +*/ + Strcpy(buf, "ƒIƒt"); +/*JP + enl_msg("Autopickup ", "is ", "was ", buf, ""); +*/ + enl_msg("Ž©“®E‚¢Ý’è‚Í", "‚Å‚ ‚é", "‚Å‚ ‚Á‚½", buf, ""); +} + +/* characteristics: expanded version of bottom line strength, dexterity, &c */ +STATIC_OVL void +characteristics_enlightenment(mode, final) +int mode; +int final; +{ + char buf[BUFSZ]; + + enlght_out(""); +/*JP + Sprintf(buf, "%s Characteristics:", !final ? "Current" : "Final"); +*/ + Sprintf(buf, "%s‘®«F", !final ? "Œ»Ý‚Ì" : "ÅI"); + enlght_out(buf); /* bottom line order */ one_characteristic(mode, final, A_STR); /* strength */ @@ -2231,7 +2667,7 @@ int mode; int final; { boolean magic = (mode & MAGICENLIGHTENMENT) ? TRUE : FALSE; - int cap; + int cap, wtype; char buf[BUFSZ], youtoo[BUFSZ]; boolean Riding = (u.usteed /* if hero dies while dismounting, u.usteed will still @@ -2252,11 +2688,11 @@ int final; * Status (many are abbreviated on bottom line; others are or * should be discernible to the hero hence to the player) \*/ - putstr(en_win, 0, ""); /* separator after title or characteristics */ + enlght_out(""); /* separator after title or characteristics */ /*JP - putstr(en_win, 0, final ? "Final Status:" : "Current Status:"); + enlght_out(final ? "Final Status:" : "Current Status:"); */ - putstr(en_win, 0, final ? "ÅIó‘Ô:" : "Œ»Ý‚̏ó‘Ô:"); + enlght_out(final ? "ÅIó‘Ô:" : "Œ»Ý‚̏ó‘Ô:"); Strcpy(youtoo, You_); /* not a traditional status but inherently obvious to player; more @@ -2331,7 +2767,7 @@ int final; you_are_ing(buf, from_what(WWALKING)); #endif } - if (Upolyd && (u.uundetected || youmonst.m_ap_type != M_AP_NOTHING)) + if (Upolyd && (u.uundetected || U_AP_TYPE != M_AP_NOTHING)) youhiding(TRUE, final); /* internal troubles, mostly in the order that prayer ranks them */ @@ -2636,6 +3072,7 @@ int final; */ you_are("‰×•¨‚͎ז‚‚É‚È‚ç‚È‚¢ó‘Ô", ""); } + /* report being weaponless; distinguish whether gloves are worn */ if (!uwep) { #if 0 /*JP*/ @@ -2649,7 +3086,8 @@ int final; #else enl_msg(You_, "‚¢", "‚©‚Á‚½", "•Ší‚ð‘•”õ‚µ‚Ä‚¢‚È", ""); #endif - /* two-weaponing implies a weapon (not other odd stuff) in each hand */ + /* two-weaponing implies hands (can't be polymorphed) and + a weapon or wep-tool (not other odd stuff) in each hand */ } else if (u.twoweap) { /*JP you_are("wielding two weapons at once", ""); @@ -2674,8 +3112,39 @@ int final; enl_msg(You_, "‚¢‚é", "‚¢‚½", buf, ""); #endif } + /* + * Skill with current weapon. Might help players who've never + * noticed #enhance or decided that it was pointless. + * + * TODO? Maybe merge wielding line and skill line into one sentence. + */ + if ((wtype = uwep_skill_type()) != P_NONE) { + char sklvlbuf[20]; + int sklvl = P_SKILL(wtype); + boolean hav = (sklvl != P_UNSKILLED && sklvl != P_SKILLED); + + if (sklvl == P_ISRESTRICTED) + Strcpy(sklvlbuf, "no"); + else + (void) lcase(skill_level_name(wtype, sklvlbuf)); + /* "you have no/basic/expert/master/grand-master skill with " + or "you are unskilled/skilled in " */ +#if 0 /*JP*/ + Sprintf(buf, "%s %s %s", sklvlbuf, + hav ? "skill with" : "in", skill_name(wtype)); +#else + Sprintf(buf, "%s‚Ì%sƒXƒLƒ‹", skill_name(wtype), sklvlbuf); +#endif + if (can_advance(wtype, FALSE)) + Sprintf(eos(buf), " and %s that", + !final ? "can enhance" : "could have enhanced"); + if (hav) + you_have(buf, ""); + else + you_are(buf, ""); + } /* report 'nudity' */ - if (!uarm && !uarmu && !uarmc && !uarmg && !uarmf && !uarmh) { + if (!uarm && !uarmu && !uarmc && !uarms && !uarmg && !uarmf && !uarmh) { if (u.uroleplay.nudist) #if 0 /*JP*/ enl_msg(You_, "do", "did", " not wear any armor", ""); @@ -2697,19 +3166,21 @@ attributes_enlightenment(unused_mode, final) int unused_mode UNUSED; int final; { +#if 0 /*JP*/ static NEARDATA const char if_surroundings_permitted[] = " if surroundings permitted"; +#endif int ltmp, armpro; char buf[BUFSZ]; /*\ * Attributes \*/ - putstr(en_win, 0, ""); + enlght_out(""); /*JP - putstr(en_win, 0, final ? "Final Attributes:" : "Current Attributes:"); + enlght_out(final ? "Final Attributes:" : "Current Attributes:"); */ - putstr(en_win, 0, final ? "ÅI‘®«:" : "Œ»Ý‚Ì‘®«:"); + enlght_out(final ? "ÅI‘®«:" : "Œ»Ý‚Ì‘®«:"); if (u.uevent.uhand_of_elbereth) { #if 0 /*JP*/ @@ -2819,7 +3290,11 @@ int final; /*** Vision and senses ***/ if (!Blind && (Blinded || !haseyes(youmonst.data))) +#if 0 /*JP*/ you_can("see", from_what(-BLINDED)); /* Eyes of the Overworld */ +#else /*u’´¢ŠE‚Ì–Ú‚É‚æ‚Á‚ÄŒ©‚邱‚Æ‚ª‚Å‚«‚év*/ + you_can("Œ©‚邱‚Æ‚ª", from_what(-BLINDED)); /* Eyes of the Overworld */ +#endif if (See_invisible) { if (!Blind) /*JP @@ -3032,13 +3507,23 @@ int final; long save_BLev = BLevitation; BLevitation = 0L; - if (Levitation) + if (Levitation) { + /* either trapped in the floor or inside solid rock + (or both if chained to buried iron ball and have + moved one step into solid rock somehow) */ #if 0 /*JP*/ - enl_msg(You_, "would levitate", "would have levitated", - if_surroundings_permitted, ""); + boolean trapped = (save_BLev & I_SPECIAL) != 0L, + terrain = (save_BLev & FROMOUTSIDE) != 0L; + + Sprintf(buf, "%s%s%s", + trapped ? " if not trapped" : "", + (trapped && terrain) ? " and" : "", + terrain ? if_surroundings_permitted : ""); + enl_msg(You_, "would levitate", "would have levitated", buf, ""); #else - you_are("•‚—Vó‘Ô", ""); + you_are("ó‹µ‚ª‹–‚¹‚Ε‚—V‚·‚éó‘Ô", ""); #endif + } BLevitation = save_BLev; } /* actively flying handled earlier as a status condition */ @@ -3046,19 +3531,49 @@ int final; long save_BFly = BFlying; BFlying = 0L; - if (Flying) + if (Flying) { #if 0 /*JP*/ enl_msg(You_, "would fly", "would have flown", + /* wording quibble: for past tense, "hadn't been" + would sound better than "weren't" (and + "had permitted" better than "permitted"), but + "weren't" and "permitted" are adequate so the + extra complexity to handle that isn't worth it */ Levitation - ? "if you weren't levitating" - : (save_BFly == FROMOUTSIDE) - ? if_surroundings_permitted - /* both surroundings and [latent] levitation */ - : " if circumstances permitted", + ? " if you weren't levitating" + : (save_BFly == I_SPECIAL) + /* this is an oversimpliction; being trapped + might also be blocking levitation so flight + would still be blocked after escaping trap */ + ? " if you weren't trapped" + : (save_BFly == FROMOUTSIDE) + ? if_surroundings_permitted + /* two or more of levitation, surroundings, + and being trapped in the floor */ + : " if circumstances permitted", ""); #else - you_can("”ò‚Ô‚±‚Æ‚ª", ""); + enl_msg(You_, "”ò‚Ô‚±‚Æ‚ª‚Å‚«‚é", "”ò‚Ô‚±‚Æ‚ª‚Å‚«‚½", + /* wording quibble: for past tense, "hadn't been" + would sound better than "weren't" (and + "had permitted" better than "permitted"), but + "weren't" and "permitted" are adequate so the + extra complexity to handle that isn't worth it */ + Levitation + ? "•‚—V‚µ‚Ä‚¢‚È‚¯‚ê‚Î" + : (save_BFly == I_SPECIAL) + /* this is an oversimpliction; being trapped + might also be blocking levitation so flight + would still be blocked after escaping trap */ + ? "•ß‚Ü‚Á‚Ä‚¢‚È‚¯‚ê‚Î" + : (save_BFly == FROMOUTSIDE) + ? "ó‹µ‚ª‹–‚¹‚Î" + /* two or more of levitation, surroundings, + and being trapped in the floor */ + : "Ž–î‚ª‹–‚¹‚Î", + ""); #endif + } BFlying = save_BFly; } /* actively walking on water handled earlier as a status condition */ @@ -3197,7 +3712,12 @@ int final; you_have("polymorph control", from_what(POLYMORPH_CONTROL)); */ you_have("•Ï‰»‚̐§Œä”\—Í", from_what(POLYMORPH_CONTROL)); - if (Upolyd && u.umonnum != u.ulycn) { + if (Upolyd && u.umonnum != u.ulycn + /* if we've died from turning into slime, we're polymorphed + right now but don't want to list it as a temporary attribute + [we need a more reliable way to detect this situation] */ + && !(final == ENL_GAMEOVERDEAD + && u.umonnum == PM_GREEN_SLIME && !Unchanging)) { /* foreign shape (except were-form which is handled below) */ /*JP Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname)); @@ -3301,7 +3821,7 @@ int final; */ you_have("‚³‚ç‚È‚é•s‰^", ""); if (carrying(LUCKSTONE) || stone_luck(TRUE)) { - ltmp = stone_luck(0); + ltmp = stone_luck(FALSE); if (ltmp <= 0) /*JP enl_msg("Bad luck ", "does", "did", " not time out for you", ""); @@ -3674,24 +4194,24 @@ int msgflag; /* for variant message phrasing */ Strcpy(buf, "hiding"); */ Strcpy(buf, "‰B‚ê"); - if (youmonst.m_ap_type != M_AP_NOTHING) { + if (U_AP_TYPE != M_AP_NOTHING) { /* mimic; hero is only able to mimic a strange object or gold or hallucinatory alternative to gold, so we skip the details for the hypothetical furniture and monster cases */ #if 0 /*JP*//*Œã‚ë‚ɉñ‚·*//* not used */ bp = eos(strcpy(buf, "mimicking")); #endif - if (youmonst.m_ap_type == M_AP_OBJECT) { + if (U_AP_TYPE == M_AP_OBJECT) { /*JP Sprintf(bp, " %s", an(simple_typename(youmonst.mappearance))); */ Strcpy(buf, simple_typename(youmonst.mappearance)); - } else if (youmonst.m_ap_type == M_AP_FURNITURE) { + } else if (U_AP_TYPE == M_AP_FURNITURE) { /*JP Strcpy(bp, " something"); */ Strcpy(buf, "‰½‚©"); - } else if (youmonst.m_ap_type == M_AP_MONSTER) { + } else if (U_AP_TYPE == M_AP_MONSTER) { /*JP Strcpy(bp, " someone"); */ @@ -3932,6 +4452,7 @@ int final; * N wishes (1 for an artifact) * N wishes (M for artifacts) */ +#if 0 /*JP*/ if (u.uconduct.wisharti == u.uconduct.wishes) Sprintf(eos(buf), " (%s", (u.uconduct.wisharti > 2L) ? "all " @@ -3942,6 +4463,9 @@ int final; Sprintf(eos(buf), "for %s)", (u.uconduct.wisharti == 1L) ? "an artifact" : "artifacts"); +#else + Sprintf(eos(buf), " (¹Ší‚Í%ld‰ñ)", u.uconduct.wisharti); +#endif } you_have_X(buf); @@ -3960,22 +4484,6 @@ int final; en_win = WIN_ERR; } -/* Macros for meta and ctrl modifiers: - * M and C return the meta/ctrl code for the given character; - * e.g., (C('c') is ctrl-c - */ -#ifndef M -#ifndef NHSTDC -#define M(c) (0x80 | (c)) -#else -#define M(c) ((c) - 128) -#endif /* NHSTDC */ -#endif - -#ifndef C -#define C(c) (0x1f & (c)) -#endif - /* ordered by command name */ struct ext_func_tab extcmdlist[] = { { '#', "#", "perform an extended command", @@ -4099,12 +4607,6 @@ struct ext_func_tab extcmdlist[] = { wiz_migrate_mons, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, #endif #if 0 /*JP*/ - { '\0', "monpolycontrol", "control monster polymorphs", -#else - { '\0', "monpolycontrol", "‰ö•¨‚ւ̕ω»‚𐧌䂷‚é", -#endif - wiz_mon_polycontrol, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, -#if 0 /*JP*/ { M('m'), "monster", "use monster's special ability", #else { M('m'), "monster", "‰ö•¨‚Ì“Á•Ê”\—Í‚ðŽg‚¤", @@ -4145,14 +4647,6 @@ struct ext_func_tab extcmdlist[] = { { '\0', "polyself", "•Ï‰»‚·‚é", #endif wiz_polyself, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, -#ifdef PORT_DEBUG -#if 0 /*JP*/ - { '\0', "portdebug", "wizard port debug command", -#else - { '\0', "portdebug", "ƒEƒBƒU[ƒhƒ|[ƒgƒfƒoƒbƒOƒRƒ}ƒ“ƒh", -#endif - wiz_port_debug, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, -#endif #if 0 /*JP*/ { M('p'), "pray", "pray to the gods for help", #else @@ -4213,25 +4707,33 @@ struct ext_func_tab extcmdlist[] = { { '^', "seetrap", "show the type of adjacent trap", doidtrap, IFBURIED }, { WEAPON_SYM, "seeweapon", "show the weapon currently wielded", doprwep, IFBURIED }, -#ifdef SHELL - { '!', "shell", "do a shell escape", dosh, IFBURIED | GENERALCMD }, + { '!', "shell", "do a shell escape", + dosh_core, IFBURIED | GENERALCMD +#ifndef SHELL + | CMD_NOT_AVAILABLE #endif /* SHELL */ + }, #if 0 /*JP*/ { M('s'), "sit", "sit down", dosit, AUTOCOMPLETE }, - { '\0', "stats", "show memory statistics", #else { M('s'), "sit", "À‚é", dosit, AUTOCOMPLETE }, +#endif +#if 0 /*JP*/ + { '\0', "stats", "show memory statistics", +#else { '\0', "stats", "ƒƒ‚ƒŠó‘Ô‚ðŒ©‚é", #endif wiz_show_stats, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, -#ifdef SUSPEND { C('z'), "suspend", "suspend the game", - dosuspend_core, IFBURIED | GENERALCMD }, + dosuspend_core, IFBURIED | GENERALCMD +#ifndef SUSPEND + | CMD_NOT_AVAILABLE #endif /* SUSPEND */ + }, { 'x', "swap", "swap wielded and secondary weapons", doswapweapon }, { 'T', "takeoff", "take off one piece of armor", dotakeoff }, { 'A', "takeoffall", "remove all armor", doddoremarm }, - { C('t'), "teleport", "teleport around the level", dotele, IFBURIED }, + { C('t'), "teleport", "teleport around the level", dotelecmd, IFBURIED }, #if 0 /*JP*/ { '\0', "terrain", "show map without obstructions", #else @@ -4310,17 +4812,11 @@ struct ext_func_tab extcmdlist[] = { #endif #ifdef DEBUG #if 0 /*JP*/ - { '\0', "wizdebug_bury", "wizard debug: bury objs under and around you", + { '\0', "wizbury", "bury objs under and around you", #else - { '\0', "wizdebug_bury", "ƒEƒBƒU[ƒh‚ŃoƒbƒO: •¨‚ð‚ ‚È‚½‚ÌŽü‚è‚É–„‚ß‚é", + { '\0', "wizbury", "•¨‚ð‚ ‚È‚½‚ÌŽü‚è‚É–„‚ß‚é", #endif wiz_debug_cmd_bury, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, -#if 0 /*JP*/ - { '\0', "wizdebug_traveldisplay", "wizard debug: toggle travel display", -#else - { '\0', "wizdebug_traveldisplay", "ƒEƒBƒU[ƒhƒfƒoƒbƒO: ˆÚ“®•\Ž¦‚ðØ‚è‘Ö‚¦‚é", -#endif - wiz_debug_cmd_traveldisplay, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, #endif { C('e'), "wizdetect", "reveal hidden things within a small radius", wiz_detect, IFBURIED | AUTOCOMPLETE | WIZMODECMD }, @@ -4362,6 +4858,8 @@ struct ext_func_tab extcmdlist[] = { { '\0', (char *) 0, (char *) 0, donull, 0, (char *) 0 } /* sentinel */ }; +int extcmdlist_length = SIZE(extcmdlist) - 1; + const char * key2extcmddesc(key) uchar key; @@ -4388,6 +4886,14 @@ const char *command; if (strcmp(command, extcmd->ef_txt)) continue; Cmd.commands[key] = extcmd; +#if 0 /* silently accept key binding for unavailable command (!SHELL,&c) */ + if ((extcmd->flags & CMD_NOT_AVAILABLE) != 0) { + char buf[BUFSZ]; + + Sprintf(buf, cmdnotavail, extcmd->ef_txt); + config_error_add("%s", buf); + } +#endif return TRUE; } @@ -4610,18 +5116,18 @@ STATIC_OVL int size_obj(otmp) struct obj *otmp; { - int sz = (int) sizeof(struct obj); + int sz = (int) sizeof (struct obj); if (otmp->oextra) { - sz += (int) sizeof(struct oextra); + sz += (int) sizeof (struct oextra); if (ONAME(otmp)) sz += (int) strlen(ONAME(otmp)) + 1; if (OMONST(otmp)) - sz += (int) sizeof(struct monst); + sz += size_monst(OMONST(otmp), FALSE); if (OMID(otmp)) - sz += (int) sizeof(unsigned); + sz += (int) sizeof (unsigned); if (OLONG(otmp)) - sz += (int) sizeof(long); + sz += (int) sizeof (long); if (OMAILCMD(otmp)) sz += (int) strlen(OMAILCMD(otmp)) + 1; } @@ -4794,6 +5300,7 @@ long *total_size; int idx; struct trap *tt; struct damage *sd; /* shop damage */ + struct kinfo *k; /* delayed killer */ struct cemetery *bi; /* bones info */ /* traps and engravings are output unconditionally; @@ -4859,6 +5366,20 @@ long *total_size; } count = size = 0L; + for (k = killer.next; k; k = k->next) { + ++count; + size += (long) sizeof *k; + } + if (count || size) { + *total_count += count; + *total_size += size; + Sprintf(hdrbuf, "delayed killer%s, size %ld", + plur(count), (long) sizeof (struct kinfo)); + Sprintf(buf, template, hdrbuf, count, size); + putstr(win, 0, buf); + } + + count = size = 0L; for (bi = level.bonesinfo; bi; bi = bi->next) { ++count; size += (long) sizeof *bi; @@ -4980,6 +5501,7 @@ sanity_check() timer_sanity_check(); mon_sanity_check(); light_sources_sanity_check(); + bc_sanity_check(); } #ifdef DEBUG_MIGRATING_MONS @@ -5339,14 +5861,65 @@ int NDECL((*cmd_func)); || cmd_func == doloot /* travel: pop up a menu of interesting targets in view */ || cmd_func == dotravel - /* wizard mode ^V */ - || cmd_func == wiz_level_tele + /* wizard mode ^V and ^T */ + || cmd_func == wiz_level_tele || cmd_func == dotelecmd /* 'm' prefix allowed for some extended commands */ || cmd_func == doextcmd || cmd_func == doextlist) return TRUE; return FALSE; } +char +randomkey() +{ + static int i = 0; + char c; + + switch (rn2(12)) { + default: c = '\033'; break; + case 0: c = '\n'; break; + case 1: + case 2: + case 3: + case 4: c = (char)(' ' + rn2((int)('~' - ' '))); break; + case 5: c = '\t'; break; + case 6: c = (char)('a' + rn2((int)('z' - 'a'))); break; + case 7: c = (char)('A' + rn2((int)('Z' - 'A'))); break; + case 8: c = extcmdlist[(i++) % SIZE(extcmdlist)].key; break; + case 9: c = '#'; break; + } + + return c; +} + +void +random_response(buf, sz) +char *buf; +int sz; +{ + char c; + int count = 0; + + for (;;) { + c = randomkey(); + if (c == '\n') + break; + if (c == '\033') { + count = 0; + break; + } + if (count < sz - 1) + buf[count++] = c; + } + buf[count] = '\0'; +} + +int +rnd_extcmd_idx(VOID_ARGS) +{ + return rn2(extcmdlist_length + 1) - 1; +} + int ch2spkeys(c, start, end) char c; @@ -5365,7 +5938,7 @@ rhack(cmd) register char *cmd; { int spkey; - boolean do_walk, do_rush, prefix_seen, bad_command, + boolean prefix_seen, bad_command, firsttime = (cmd == 0); iflags.menu_requested = FALSE; @@ -5396,7 +5969,7 @@ register char *cmd; } /* handle most movement commands */ - do_walk = do_rush = prefix_seen = FALSE; + prefix_seen = FALSE; context.travel = context.travel1 = 0; spkey = ch2spkeys(*cmd, NHKF_RUN, NHKF_CLICKLOOK); @@ -5404,7 +5977,7 @@ register char *cmd; case NHKF_RUSH: if (movecmd(cmd[1])) { context.run = 2; - do_rush = TRUE; + domove_attempting |= DOMOVE_RUSH; } else prefix_seen = TRUE; break; @@ -5415,7 +5988,7 @@ register char *cmd; case NHKF_RUN: if (movecmd(lowc(cmd[1]))) { context.run = 3; - do_rush = TRUE; + domove_attempting |= DOMOVE_RUSH; } else prefix_seen = TRUE; break; @@ -5431,7 +6004,7 @@ register char *cmd; case NHKF_FIGHT: if (movecmd(cmd[1])) { context.forcefight = 1; - do_walk = TRUE; + domove_attempting |= DOMOVE_WALK; } else prefix_seen = TRUE; break; @@ -5440,7 +6013,7 @@ register char *cmd; context.run = 0; context.nopick = 1; if (!u.dz) - do_walk = TRUE; + domove_attempting |= DOMOVE_WALK; else cmd[0] = cmd[1]; /* "m<" or "m>" */ } else @@ -5450,7 +6023,7 @@ register char *cmd; if (movecmd(lowc(cmd[1]))) { context.run = 1; context.nopick = 1; - do_rush = TRUE; + domove_attempting |= DOMOVE_RUSH; } else prefix_seen = TRUE; break; @@ -5473,20 +6046,20 @@ register char *cmd; context.travel1 = 1; context.run = 8; context.nopick = 1; - do_rush = TRUE; + domove_attempting |= DOMOVE_RUSH; break; } /*FALLTHRU*/ default: if (movecmd(*cmd)) { /* ordinary movement */ context.run = 0; /* only matters here if it was 8 */ - do_walk = TRUE; + domove_attempting |= DOMOVE_WALK; } else if (movecmd(Cmd.num_pad ? unmeta(*cmd) : lowc(*cmd))) { context.run = 1; - do_rush = TRUE; + domove_attempting |= DOMOVE_RUSH; } else if (movecmd(unctrl(*cmd))) { context.run = 3; - do_rush = TRUE; + domove_attempting |= DOMOVE_RUSH; } break; } @@ -5504,7 +6077,8 @@ register char *cmd; } } - if ((do_walk || do_rush) && !context.travel && !dxdy_moveok()) { + if (((domove_attempting & (DOMOVE_RUSH | DOMOVE_WALK)) != 0L) + && !context.travel && !dxdy_moveok()) { /* trying to move diagonally as a grid bug; this used to be treated by movecmd() as not being a movement attempt, but that didn't provide for any @@ -5521,13 +6095,13 @@ register char *cmd; return; } - if (do_walk) { + if ((domove_attempting & DOMOVE_WALK) != 0L) { if (multi) context.mv = TRUE; domove(); context.forcefight = 0; return; - } else if (do_rush) { + } else if ((domove_attempting & DOMOVE_RUSH) != 0L) { if (firsttime) { if (!multi) multi = max(COLNO, ROWNO); @@ -5931,9 +6505,15 @@ const char *msg; } } +#if 0 /*JP*/ Sprintf(buf, "Valid direction keys%s%s%s are:", prefixhandling ? " to " : "", prefixhandling ? dothat : "", NODIAG(u.umonnum) ? " in your current form" : ""); +#else + Sprintf(buf, "%s%s%s‚Å‚Ì—LŒø‚È•ûŒüŽw’è‚Í:", + prefixhandling ? " to " : "", prefixhandling ? dothat : "", + NODIAG(u.umonnum) ? " in your current form" : ""); +#endif putstr(win, 0, buf); show_direction_keys(win, !prefixhandling ? '.' : ' ', NODIAG(u.umonnum)); @@ -6434,9 +7014,7 @@ boolean historical; /* whether to include in message history: True => yes */ Sprintf(qbuf, "”: %ld", cnt); backspaced = FALSE; } - /* bypassing pline() keeps intermediate prompt out of - DUMPLOG message history */ - putstr(WIN_MESSAGE, 0, qbuf); + custompline(SUPPRESS_HISTORY, "%s", qbuf); mark_synch(); } } @@ -6463,7 +7041,6 @@ parse() static char in_line[COLNO]; #endif register int foo; - boolean prezero = FALSE; iflags.in_parse = TRUE; multi = 0; @@ -6483,6 +7060,12 @@ parse() alt_esc = FALSE; /* readchar() reset */ #endif + if (iflags.debug_fuzzer /* if fuzzing, override '!' and ^Z */ + && (Cmd.commands[foo & 0x0ff] + && (Cmd.commands[foo & 0x0ff]->ef_funct == dosuspend_core + || Cmd.commands[foo & 0x0ff]->ef_funct == dosh_core))) + foo = Cmd.spkeys[NHKF_ESC]; + if (foo == Cmd.spkeys[NHKF_ESC]) { /* esc cancels count (TH) */ clear_nhwindow(WIN_MESSAGE); multi = last_multi = 0; @@ -6530,8 +7113,6 @@ parse() in_line[2] = 0; } clear_nhwindow(WIN_MESSAGE); - if (prezero) - in_line[0] = Cmd.spkeys[NHKF_ESC]; iflags.in_parse = FALSE; return in_line; @@ -6595,6 +7176,8 @@ readchar() register int sym; int x = u.ux, y = u.uy, mod = 0; + if (iflags.debug_fuzzer) + return randomkey(); if (*readchar_queue) sym = *readchar_queue++; else @@ -6637,19 +7220,26 @@ readchar() return (char) sym; } +/* '_' command, #travel, via keyboard rather than mouse click */ STATIC_PTR int dotravel(VOID_ARGS) { - /* Keyboard travel command */ static char cmd[2]; coord cc; + /* [FIXME? Supporting the ability to disable traveling via mouse + click makes some sense, depending upon overall mouse usage. + Disabling '_' on a user by user basis makes no sense at all since + even if it is typed by accident, aborting when picking a target + destination is trivial. Travel via mouse predates travel via '_', + and this use of OPTION=!travel is probably just a mistake....] */ if (!flags.travelcmd) return 0; + cmd[1] = 0; cc.x = iflags.travelcc.x; cc.y = iflags.travelcc.y; - if (cc.x == -1 && cc.y == -1) { + if (cc.x == 0 && cc.y == 0) { /* No cached destination, start attempt from current position */ cc.x = u.ux; cc.y = u.uy; @@ -6686,56 +7276,6 @@ dotravel(VOID_ARGS) return 0; } -#ifdef PORT_DEBUG -extern void NDECL(win32con_debug_keystrokes); -extern void NDECL(win32con_handler_info); - -int -wiz_port_debug() -{ - int n, k; - winid win; - anything any; - int item = 'a'; - int num_menu_selections; - struct menu_selection_struct { - char *menutext; - void NDECL((*fn)); - } menu_selections[] = { -#ifdef WIN32 - { "test win32 keystrokes (tty only)", win32con_debug_keystrokes }, - { "show keystroke handler information (tty only)", - win32con_handler_info }, -#endif - { (char *) 0, (void NDECL((*))) 0 } /* array terminator */ - }; - - num_menu_selections = SIZE(menu_selections) - 1; - if (num_menu_selections > 0) { - menu_item *pick_list; - - win = create_nhwindow(NHW_MENU); - start_menu(win); - for (k = 0; k < num_menu_selections; ++k) { - any.a_int = k + 1; - add_menu(win, NO_GLYPH, &any, item++, 0, ATR_NONE, - menu_selections[k].menutext, MENU_UNSELECTED); - } - end_menu(win, "Which port debugging feature?"); - n = select_menu(win, PICK_ONE, &pick_list); - destroy_nhwindow(win); - if (n > 0) { - n = pick_list[0].item.a_int - 1; - free((genericptr_t) pick_list); - /* execute the function */ - (*menu_selections[n].fn)(); - } - } else - pline("No port-specific debug capability defined."); - return 0; -} -#endif /*PORT_DEBUG*/ - /* * Parameter validator for generic yes/no function to prevent * the core from sending too long a prompt string to the @@ -6816,8 +7356,9 @@ const char *prompt; return confirmed_ok; } -int -dosuspend_core() +/* ^Z command, #suspend */ +STATIC_PTR int +dosuspend_core(VOID_ARGS) { #ifdef SUSPEND /* Does current window system support suspend? */ @@ -6826,10 +7367,20 @@ dosuspend_core() dosuspend(); } else #endif -/*JP - Norep("Suspend command not available."); -*/ - Norep("’†’fƒRƒ}ƒ“ƒh‚Í—˜—p‚Å‚«‚Ü‚¹‚ñD"); + Norep(cmdnotavail, "#suspend"); + return 0; +} + +/* '!' command, #shell */ +STATIC_PTR int +dosh_core(VOID_ARGS) +{ +#ifdef SHELL + /* access restrictions, if any, are handled in port code */ + dosh(); +#else + Norep(cmdnotavail, "#shell"); +#endif return 0; }