diff --git a/dat/opthelp b/dat/opthelp index 7ec3f58a6..f059ddabc 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -202,6 +202,7 @@ objects like dungeon, but for object symbols default: ])[="(%!?+/$*`0_. pettype your preferred type of pet (cat or dog), if your character class uses both types; or none for no pet [RANDOM] +playmode normal play or non-scoring explore mode or debug mode [normal] race Your starting race (e.g., race:Human, race:Elf). [RANDOM] role Your starting role (e.g., role:Barbarian, role:Valk). Although you can specify just the first letter(s), it will diff --git a/doc/Guidebook.mn b/doc/Guidebook.mn index ec3517888..130fb57f1 100644 --- a/doc/Guidebook.mn +++ b/doc/Guidebook.mn @@ -1983,6 +1983,15 @@ compile time option AUTOPICKUP_EXCEPTIONS included, you may be able to use configuration file lines to further refine .op autopickup behavior. +.lp playmode +Values are `normal', `explore', or `debug'. +Allows selection of explore mode (also known as discovery mode) or debug +mode (also known as wizard mode) instead of normal play. +Debug mode might only be allowed for someone logged in under a particular +user name (on multi-user systems) or specifying a particular character +name (on single-user systems) or it might be disabled entirely. Requesting +it when not allowed or not possible results in explore mode instead. +Default is normal play. .lp prayconfirm Prompt for confirmation before praying (default on). .lp pushweapon diff --git a/doc/Guidebook.tex b/doc/Guidebook.tex index 24de88b10..4c17158d9 100644 --- a/doc/Guidebook.tex +++ b/doc/Guidebook.tex @@ -31,7 +31,7 @@ \begin{document} % % input file: guidebook.mn -% $Revision: 1.101 $ $Date: 2006/07/15 03:25:04 $ +% $Revision: 1.102 $ $Date: 2007/02/14 01:44:46 $ % %.ds h0 " %.ds h1 %.ds h2 \% @@ -2457,6 +2457,16 @@ compile time option AUTOPICKUP\_EXCEPTIONS included, you may be able to use ``{\it autopickup\_exception\/}'' configuration file lines to further refine ``{\it autopickup\/}'' behavior. %.lp +\item[\ib{playmode}] +Values are {\it normal\/}, {\it explore\/}, or {\it debug\/}. +Allows selection of explore mode (also known as discovery mode) or debug +mode (also known as wizard mode) instead of normal play. +Debug mode might only be allowed for someone logged in under a particular +user name (on multi-user systems) or specifying a particular character +name (on single-user systems) or it might be disabled entirely. Requesting +it when not allowed or not possible results in explore mode instead. +Default is normal play. +%.lp \item[\ib{prayconfirm}] Prompt for confirmation before praying (default on). %.lp diff --git a/doc/fixes35.0 b/doc/fixes35.0 index 710179113..766c64376 100644 --- a/doc/fixes35.0 +++ b/doc/fixes35.0 @@ -282,6 +282,7 @@ all stackable weapons are capable of being thrown/shot for multi-shot volleys worm teeth and crysknives have become stackable improved container interface acid can destroy iron bars +OPTIONS=playmode:normal|explore|debug to choose mode without command-line Platform- and/or Interface-Specific New Features diff --git a/sys/share/pcmain.c b/sys/share/pcmain.c index 7b12a0985..4f1f9537f 100644 --- a/sys/share/pcmain.c +++ b/sys/share/pcmain.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)pcmain.c 3.5 2006/07/08 */ +/* SCCS Id: @(#)pcmain.c 3.5 2007/02/14 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -66,6 +66,8 @@ extern int redirect_stdout; /* from sys/share/pcsys.c */ extern void NDECL(mswin_destroy_reg); #endif +STATIC_DCL void NDECL(set_playmode); + #ifdef EXEPATH STATIC_DCL char *FDECL(exepath,(char *)); #endif @@ -342,20 +344,7 @@ char *argv[]; plnamesuffix(); /* strip suffix from name; calls askname() */ /* again if suffix was whole name */ /* accepts any suffix */ -#ifdef WIZARD - if (wizard) { -# ifdef KR1ED - if(!strcmp(plname, WIZARD_NAME)) -# else - if(!strcmp(plname, WIZARD)) -# endif - Strcpy(plname, "wizard"); - else { - wizard = FALSE; - discover = TRUE; - } - } -#endif /* WIZARD */ + set_playmode(); /* sets plname to "wizard" for wizard mode */ #if defined(PC_LOCKING) /* 3.3.0 added this to support detection of multiple games * under the same plname on the same machine in a windowed @@ -519,17 +508,10 @@ char *argv[]; } break; case 'D': -#ifdef WIZARD - /* If they don't have a valid wizard name, it'll be - * changed to discover later. Cannot check for - * validity of the name right now--it might have a - * character class suffix, for instance. - */ - wizard = TRUE; + wizard = TRUE, discover = FALSE; break; -#endif case 'X': - discover = TRUE; + discover = TRUE, wizard = FALSE; break; #ifdef NEWS case 'n': @@ -716,6 +698,37 @@ port_help() # endif /* MSDOS || WIN32 */ #endif /* PORT_HELP */ +/* for KR1ED config, WIZARD is 0 or 1 and WIZARD_NAME is a string; + for usual config, WIZARD is the string; forcing WIZARD_NAME to match it + eliminates conditional testing for which one to use in string ops */ +#ifndef KR1ED +# undef WIZARD_NAME +# define WIZARD_NAME WIZARD +#endif + +/* validate wizard mode if player has requested access to it */ +STATIC_OVL void +set_playmode() +{ + if (wizard) { +#ifdef WIZARD + if (strcmp(plname, WIZARD_NAME)) wizard = FALSE; +#else + wizard = FALSE; +#endif + + if (!wizard) { + discover = TRUE; +#ifdef WIZARD + } else { + discover = FALSE; /* paranoia */ + Strcpy(plname, "wizard"); +#endif + } + } + /* don't need to do anything special for explore mode or normal play */ +} + #ifdef EXEPATH # ifdef __DJGPP__ #define PATH_SEPARATOR '/' diff --git a/sys/unix/unixmain.c b/sys/unix/unixmain.c index 18f1fea18..c94921a68 100644 --- a/sys/unix/unixmain.c +++ b/sys/unix/unixmain.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)unixmain.c 3.5 2007/01/08 */ +/* SCCS Id: @(#)unixmain.c 3.5 2007/02/14 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -39,10 +39,9 @@ extern void NDECL(check_linux_console); extern void NDECL(init_linux_cons); #endif +static void NDECL(set_playmode); static void NDECL(wd_message); -#ifdef WIZARD static boolean wiz_error_flag = FALSE; -#endif int main(argc,argv) @@ -176,11 +175,9 @@ char *argv[]; #ifdef MAIL getmailstatus(); #endif -#ifdef WIZARD - if (wizard) - Strcpy(plname, "wizard"); - else -#endif + + /* wizard mode access is deferred until here */ + set_playmode(); /* sets plname to "wizard" for wizard mode */ if(!*plname || !strncmp(plname, "player", 4) || !strncmp(plname, "games", 4)) { askname(); @@ -299,38 +296,10 @@ char *argv[]; argc--; switch(argv[0][1]){ case 'D': -#ifdef WIZARD - { - char *user; - int uid; - struct passwd *pw = (struct passwd *)0; - - uid = getuid(); - user = getlogin(); - if (user) { - pw = getpwnam(user); - if (pw && (pw->pw_uid != uid)) pw = 0; - } - if (pw == 0) { - user = nh_getenv("USER"); - if (user) { - pw = getpwnam(user); - if (pw && (pw->pw_uid != uid)) pw = 0; - } - if (pw == 0) { - pw = getpwuid(uid); - } - } - if (pw && !strcmp(pw->pw_name,WIZARD)) { - wizard = TRUE; - break; - } - } - /* otherwise fall thru to discover */ - wiz_error_flag = TRUE; -#endif + wizard = TRUE, discover = FALSE; + break; case 'X': - discover = TRUE; + discover = TRUE, wizard = FALSE; break; #ifdef NEWS case 'n': @@ -538,22 +507,71 @@ port_help() } #endif +/* for KR1ED config, WIZARD is 0 or 1 and WIZARD_NAME is a string; + for usual config, WIZARD is the string; forcing WIZARD_NAME to match it + eliminates conditional testing for which one to use in string ops */ +#ifndef KR1ED +# undef WIZARD_NAME +# define WIZARD_NAME WIZARD +#endif + +/* validate wizard mode if player has requested access to it */ +static void +set_playmode() +{ + if (wizard) { +#ifdef WIZARD + char *user; + int uid; + struct passwd *pw = (struct passwd *)0; + + uid = getuid(); + user = getlogin(); + if (user) { + pw = getpwnam(user); + if (pw && (pw->pw_uid != uid)) pw = 0; + } + if (pw == 0) { + user = nh_getenv("USER"); + if (user) { + pw = getpwnam(user); + if (pw && (pw->pw_uid != uid)) pw = 0; + } + if (pw == 0) { + pw = getpwuid(uid); + } + } + if (!pw || strcmp(pw->pw_name, WIZARD_NAME)) wizard = FALSE; +#else /* !WIZARD */ + wizard = FALSE; +#endif /* ?WIZARD */ + + if (!wizard) { + discover = wiz_error_flag = TRUE; +#ifdef WIZARD + } else { + discover = FALSE; /* paranoia */ + Strcpy(plname, "wizard"); +#endif + } + } + /* don't need to do anything special for explore mode or normal play */ +} + static void wd_message() { -#ifdef WIZARD if (wiz_error_flag) { +#ifdef WIZARD pline("Only user \"%s\" may access debug (wizard) mode.", -# ifndef KR1ED - WIZARD); -# else - WIZARD_NAME); -# endif - pline("Entering discovery mode instead."); - } else + WIZARD_NAME); +#else + pline("Debug mode is not available."); #endif - if (discover) - You("are in non-scoring discovery mode."); + pline("Entering explore/discovery mode instead."); + wizard = 0, discover = 1; /* (paranoia) */ + } else if (discover) + You("are in non-scoring explore/discovery mode."); } /* diff --git a/sys/vms/vmsmain.c b/sys/vms/vmsmain.c index 379464535..0c1f3f067 100644 --- a/sys/vms/vmsmain.c +++ b/sys/vms/vmsmain.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)vmsmain.c 3.5 2006/04/01 */ +/* SCCS Id: @(#)vmsmain.c 3.5 2007/02/14 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ /* main.c - VMS NetHack */ @@ -22,10 +22,9 @@ static vms_handler_type FDECL(vms_handler, (genericptr_t,genericptr_t)); #include /* system service status codes */ #endif +static void NDECL(set_playmode); static void NDECL(wd_message); -#ifdef WIZARD static boolean wiz_error_flag = FALSE; -#endif int main(argc,argv) @@ -126,11 +125,8 @@ char *argv[]; process_options(argc, argv); /* command line options */ -#ifdef WIZARD - if (wizard) - Strcpy(plname, "wizard"); - else -#endif + /* wizard mode access is deferred until here */ + set_playmode(); /* sets plname to "wizard" for wizard mode */ if (!*plname || !strncmpi(plname, "games", 4) || !strcmpi(plname, "nethack")) askname(); @@ -239,17 +235,11 @@ char *argv[]; argc--; switch(argv[0][1]){ case 'D': -#ifdef WIZARD - if(!strcmpi(nh_getenv("USER"), WIZARD_NAME)) { - wizard = TRUE; - break; - } - /* otherwise fall thru to discover */ - wiz_error_flag = TRUE; -#endif /* WIZARD */ + wizard = TRUE, discover = FALSE; + break; case 'X': case 'x': - discover = TRUE; + discover = TRUE, wizard = FALSE; break; #ifdef NEWS case 'n': @@ -449,18 +439,47 @@ port_help() } #endif /* PORT_HELP */ +/* for KR1ED config, WIZARD is 0 or 1 and WIZARD_NAME is a string; + for usual config, WIZARD is the string and vmsconf.h forces WIZARD_NAME + to match it, avoiding need to test which one to use in string ops */ + +/* validate wizard mode if player has requested access to it */ +static void +set_playmode() +{ + if (wizard) { +#ifdef WIZARD + if (strcmpi(nh_getenv("USER"), WIZARD_NAME)) wizard = FALSE; +#else + wizard = FALSE; +#endif + + if (!wizard) { + discover = wiz_error_flag = TRUE; +#ifdef WIZARD + } else { + discover = FALSE; /* paranoia */ + Strcpy(plname, "wizard"); +#endif + } + } + /* don't need to do anything special for explore mode or normal play */ +} + static void wd_message() { -#ifdef WIZARD if (wiz_error_flag) { +#ifdef WIZARD pline("Only user \"%s\" may access debug (wizard) mode.", - WIZARD_NAME); - pline("Entering discovery mode instead."); - } else + WIZARD_NAME); +#else + pline("Debug mode is not available."); #endif - if (discover) - You("are in non-scoring discovery mode."); + pline("Entering explore/discovery mode instead."); + wizard = 0, discover = 1; /* (paranoia) */ + } else if (discover) + You("are in non-scoring explore/discovery mode."); } /*vmsmain.c*/