This is options.c in view mode; [Download] [Up]
/* SCCS Id: @(#)options.c 3.0 89/11/15
/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
/* NetHack may be freely redistributed. See license for details. */
/* Changed for graphical version of NetHack on NextStep */
/* by Christoph Marquardt 9/4/93 */
#include "hack.h"
static boolean set_order;
static void FDECL(nmcpy, (char *, const char *, int));
void FDECL(escapes,(const char *, char *));
void
initoptions()
{
register char *opts;
flags.time = flags.nonews = flags.notombstone = flags.end_own =
flags.standout = flags.nonull = flags.ignintr = FALSE;
flags.no_rest_on_space = flags.invlet_constant = TRUE;
flags.end_top = 3;
flags.end_around = 2;
flags.female = FALSE; /* players are usually male */
flags.sortpack = TRUE;
flags.soundok = TRUE;
flags.verbose = TRUE;
flags.confirm = TRUE;
flags.safe_dog = TRUE;
flags.silent = flags.pickup = TRUE;
#ifdef TUTTI_FRUTTI
nmcpy(pl_fruit, objects[SLIME_MOLD].oc_name, PL_FSIZ);
#endif
#ifdef NEXT
flags.num_pad = TRUE;
#else
flags.num_pad = FALSE;
#endif /* NEXT */
#ifdef TEXTCOLOR
flags.use_color = TRUE;
#endif
#ifdef MSDOS
#ifdef DECRAINBOW
flags.DECRainbow = FALSE;
#endif
#ifdef DGK
flags.IBMBIOS =
#ifdef TOS
TRUE; /* BIOS might as well always be on for TOS */
#endif
flags.rawio = FALSE;
#endif
read_config_file();
#endif /* MSDOS */
#ifdef MACOS
flags.standout = TRUE;
flags.end_around = 2; /* Mac display routines don't scroll */
flags.end_top = 4;
read_config_file();
#endif
if(opts = getenv("NETHACKOPTIONS"))
parseoptions(opts,TRUE);
#ifdef TUTTI_FRUTTI
(void)fruitadd(pl_fruit);
objects[SLIME_MOLD].oc_name = "\033";
/* Put something untypable in there */
/* We cannot just use NULL because that marks the end of objects */
#endif
}
static void
nmcpy(dest, src, maxlen)
char *dest;
const char *src;
int maxlen;
{
int count;
for(count = 1; count < maxlen; count++) {
if(*src == ',' || *src == '\0') break; /*exit on \0 terminator*/
*dest++ = *src++;
}
*dest = 0;
}
/*
* escapes: escape expansion for showsyms. C-style escapes understood include
* \n, \b, \t, \r, \xnnn (hex), \onnn (octal), \nnn (decimal). The ^-prefix
* for control characters is also understood, and \[mM] followed by any of the
* previous forms or by a character has the effect of 'meta'-ing the value (so
* that the alternate character set will be enabled).
*/
void
escapes(cp, tp)
const char *cp;
char *tp;
{
while (*cp)
{
int cval = 0, meta = 0;
if (*cp == '\\' && index("mM", cp[1])) {
meta = 1;
cp += 2;
}
if (*cp == '\\' && index("0123456789xXoO", cp[1]))
{
const char *dp, *hex = "00112233445566778899aAbBcCdDeEfF";
int dcount = 0;
cp++;
if (*cp == 'x' || *cp == 'X')
for (++cp; (dp = index(hex, *cp)) && (dcount++ < 2); cp++)
cval = (cval * 16) + (dp - hex) / 2;
else if (*cp == 'o' || *cp == 'O')
for (++cp; (index("01234567",*cp)) && (dcount++ < 3); cp++)
cval = (cval * 8) + (*cp - '0');
else
for (; (index("0123456789",*cp)) && (dcount++ < 3); cp++)
cval = (cval * 10) + (*cp - '0');
}
else if (*cp == '\\') /* C-style character escapes */
{
switch (*++cp)
{
case '\\': cval = '\\'; break;
case 'n': cval = '\n'; break;
case 't': cval = '\t'; break;
case 'b': cval = '\b'; break;
case 'r': cval = '\r'; break;
default: cval = *cp;
}
cp++;
}
else if (*cp == '^') /* expand control-character syntax */
{
cval = (*++cp & 0x1f);
cp++;
}
else
cval = *cp++;
if (meta)
cval |= 0x80;
*tp++ = cval;
}
*tp = '\0';
}
void
assign_graphics(graph_ints,glth)
register unsigned int *graph_ints;
register int glth;
{
register int i;
if (glth > MAXPCHARS) glth = MAXPCHARS; /* sanity check */
for (i = 0; i < glth; i++)
showsyms[i] = graph_ints[i];
for (i = glth; i < MAXPCHARS; i++)
showsyms[i] = defsyms[i];
}
void
parseoptions(opts, from_env)
register char *opts;
boolean from_env;
{
#ifndef MACOS
register char *op;
unsigned num;
boolean negated;
if(op = index(opts, ',')) {
*op++ = 0;
parseoptions(op, from_env);
}
if(!*opts) return;
negated = FALSE;
while((*opts == '!') || !strncmp(opts, "no", 2)) {
if(*opts == '!') opts++; else opts += 2;
negated = !negated;
}
#ifndef MSDOS
if (!strncmp(opts, "stan", 4)) {
flags.standout = !negated;
return;
}
if (!strncmp(opts, "null", 4)) {
flags.nonull = negated;
return;
}
#endif
if (!strncmp(opts, "ign", 3)) {
flags.ignintr = !negated;
return;
}
if (!strncmp(opts, "tomb", 4)) {
flags.notombstone = negated;
return;
}
#ifdef NEWS
if (!strncmp(opts, "news", 4)) {
flags.nonews = negated;
return;
}
#endif
if (!strncmp(opts, "conf", 4)) {
flags.confirm = !negated;
return;
}
if (!strncmp(opts, "safe", 4)) {
flags.safe_dog = !negated;
return;
}
if (!strncmp(opts, "sil", 3)) {
flags.silent = !negated;
return;
}
if (!strncmp(opts, "verb", 4)) {
flags.verbose = !negated;
return;
}
if (!strncmp(opts, "pick", 4)) {
flags.pickup = !negated;
return;
}
if (!strncmp(opts, "num", 3)) {
flags.num_pad = !negated;
return;
}
#ifdef TEXTCOLOR
if (!strncmp(opts, "col", 3)) {
flags.use_color = !negated;
return;
}
#endif
#ifdef DGK
if (!strncmp(opts, "IBM", 3)) {
flags.IBMBIOS = !negated;
return;
}
if (!strncmp(opts, "raw", 3)) {
if (from_env)
flags.rawio = !negated;
else
pline("\"rawio\" settable only from %s.", configfile);
return;
}
#ifdef DECRAINBOW
if (!strncmp(opts, "DEC", 3)) {
flags.DECRainbow = !negated;
return;
}
#endif /* DECRAINBOW */
#endif
if (!strncmp(opts, "sort", 4)) {
flags.sortpack = !negated;
return;
}
/*
* the order to list the pack
*/
if (!strncmp(opts, "pack", 4)) {
register char *sp, *tmp;
int tmpend;
op = index(opts,':');
if(!op) goto bad;
op++; /* skip : */
/* Missing characters in new order are filled in at the end
* from inv_order.
*/
for (sp = op; *sp; sp++)
if (!index(inv_order, *sp))
goto bad; /* bad char in order */
else if (index(sp + 1, *sp))
goto bad; /* dup char in order */
tmp = (char *) alloc((unsigned)(strlen(inv_order)+1));
Strcpy(tmp, op);
for (sp = inv_order, tmpend = strlen(tmp); *sp; sp++)
if (!index(tmp, *sp)) {
tmp[tmpend++] = *sp;
tmp[tmpend] = 0;
}
Strcpy(inv_order, tmp);
free((genericptr_t)tmp);
set_order = TRUE;
return;
}
if (!strncmp(opts, "time", 4)) {
flags.time = !negated;
flags.botl = 1;
return;
}
if (!strncmp(opts, "rest", 4)) {
flags.no_rest_on_space = negated;
return;
}
if (!strncmp(opts, "fix", 3)) {
flags.invlet_constant = !negated;
if(!from_env && flags.invlet_constant) reassign ();
return;
}
if (!strncmp(opts, "male", 4)) {
if(!from_env && flags.female != negated)
pline("That is not anatomically possible.");
else
flags.female = negated;
return;
}
if (!strncmp(opts, "fem", 3)) {
if(!from_env && flags.female == negated)
pline("That is not anatomically possible.");
else
flags.female = !negated;
return;
}
/* name:string */
if (!strncmp(opts, "name", 4)) {
if(!from_env) {
#ifdef MSDOS
pline("\"name\" settable only from %s.", configfile);
#else
pline("The playername can be set only from NETHACKOPTIONS.");
#endif
return;
}
op = index(opts,':');
if(!op) goto bad;
nmcpy(plname, op+1, sizeof(plname)-1);
return;
}
/* graphics:string */
if (!strncmp(opts, "gr", 2)) {
unsigned int translate[MAXPCHARS+1];
int i, lth;
if(!from_env) {
#ifdef MSDOS
pline("\"graphics\" settable only from %s.", configfile);
#else
pline("The graphics string can be set only from NETHACKOPTIONS.");
#endif
return;
}
op = index(opts,':');
if(!op)
goto bad;
else
opts = op + 1;
escapes(opts, opts);
lth = strlen(opts);
if(lth > MAXPCHARS) lth = MAXPCHARS;
/* match the form obtained from PC configuration files */
for(i = 0; i < lth; i++)
translate[i] = opts[i];
assign_graphics(translate,lth);
return;
}
/* endgame:5t[op] 5a[round] o[wn] */
if (!strncmp(opts, "end", 3)) {
op = index(opts,':');
if(!op) goto bad;
op++;
while(*op) {
num = 1;
if(digit(*op)) {
num = atoi(op);
while(digit(*op)) op++;
} else if(*op == '!') {
negated = !negated;
op++;
}
while(*op == ' ') op++;
switch(*op) {
case 't':
flags.end_top = num;
break;
case 'a':
flags.end_around = num;
break;
case 'o':
flags.end_own = !negated;
break;
default:
goto bad;
}
while(letter(*++op) || *op == ' ') ;
if(*op == '/') op++;
}
return;
}
if (!strncmp(opts, "dog", 3)) {
if(!from_env) {
#ifdef MSDOS
pline("\"dogname\" settable only from %s.", configfile);
#else
Your("dog's name can be set only from NETHACKOPTIONS.");
#endif
return;
}
op = index(opts, ':');
if (!op) goto bad;
nmcpy(dogname, ++op, 62);
return;
}
if (!strncmp(opts, "cat", 3)) {
if(!from_env) {
#ifdef MSDOS
pline("\"catname\" settable only from %s.", configfile);
#else
Your("cat's name can be set only from NETHACKOPTIONS.");
#endif
return;
}
op = index(opts, ':');
if (!op) goto bad;
nmcpy(catname, ++op, 62);
return;
}
#ifdef TUTTI_FRUTTI
if (!strncmp(opts, "fr", 2)) {
op = index(opts, ':');
if (!op++) goto bad;
if (!from_env) {
struct fruit *f;
int numfruits = 0;
for(f=ffruit; f; f=f->nextf) {
if (!strcmp(op, f->fname)) goto goodfruit;
numfruits++;
}
if (numfruits >= 100) {
pline("Doing that so many times isn't very fruitful.");
return;
}
}
goodfruit:
nmcpy(pl_fruit, op, PL_FSIZ);
if (!from_env)
(void)fruitadd(pl_fruit);
/* If from_env, then initoptions is allowed to do it instead
* of here (initoptions always has to do it even if there's
* no fruit option at all. Also, we don't want people
* setting multiple fruits in their options.)
*/
return;
}
#endif
bad:
if(!from_env) {
if(!strncmp(opts, "h", 1) ||
!strncmp(opts, "?", 1)) {
option_help();
return;
}
pline("Unknown option: %s. Enter \"O?\" for help.", opts);
return;
}
#ifdef MSDOS
# ifdef AMIGA_WBENCH
if(ami_wbench_badopt(opts))
# endif
Printf("Bad syntax in OPTIONS in %s: %s.", configfile, opts);
#else
Printf("Bad syntax in NETHACKOPTIONS: %s.", opts);
(void) puts("Use for example:");
(void) puts(
"NETHACKOPTIONS=\"!rest_on_space,notombstone,endgame:own/5 topscorers/4 around me\""
);
#endif
getret();
#endif /* MACOS */
}
int
doset()
{
#ifdef MACOS
#define OPTIONS "Nethack prefs"
#define OK_BUTTON 1
#define SAVE_BUTTON 2
#define CANCEL_BUTTON 3
#define MIN_CHECKBOX 4
#define EXPLORE_BOX 4
#define FEM_BOX 5
#define NEWS_BOX 6
#define FIXINV_BOX 7
#define TOMB_BOX 8
#define TIME_BOX 9
#define VERBOSE_BOX 10
#define SILENT_BOX 11
#define AUTOZOOM_BOX 12
#define INVERSE_BOX 13
#define SORT_BOX 14
#define COLOR_BOX 15
#define PICKUP_BOX 16
#define CONFIRM_BOX 17
#define SAFE_BOX 18
#define REST_SPACE_BOX 19
#define MAX_CHECKBOX 19
#define PLAYER_NAME 20
#define CAT_NAME 21
#define DOG_NAME 22
#define FRUIT_NAME 23
#define PACKORDER 24
#define END_TOP 26
#define END_AROUND 27
#define FRUIT_TEXT 35
#define PACK_TEXT 34
#define ITEMTEXT(item,text) {GetDItem(optionDlg,item,&type,&ItemHndl,&box); \
(void)CtoPstr(text); \
SetIText(ItemHndl,text);\
(void)PtoCstr(text);}
#define HIDEITEM(item) {GetDItem(optionDlg,item,&type,&ItemHndl,&box); \
HideControl(ItemHndl);\
SetDItem(optionDlg,item,type+128,ItemHndl,&box);}
#define HIDETEXT(item) {GetDItem(optionDlg,item,&type,&ItemHndl,&box);\
SetDItem(optionDlg,item,128+statText,ItemHndl,&box);\
SetIText(ItemHndl,"\0");}
#define SHOWITEM(item) {GetDItem(optionDlg,item,&type,&ItemHndl,&box);\
SetDItem(optionDlg,item,type-128,ItemHndl,&box);\
ShowControl(ItemHndl);}
#define GETTEXT(item,maxsize) {GetDItem(optionDlg,item,&type,&ItemHndl,&box);\
GetIText (ItemHndl, &tmp_name);\
tmp_name[tmp_name[0]+1] = 0;\
if (tmp_name[0] > maxsize)\
tmp_name[0] = maxsize;}
static boolean *flag_ptrs[20] = {0, 0, 0, 0, &flags.explore,
&flags.female, &flags.nonews,&flags.invlet_constant,
&flags.notombstone, &flags.time, &flags.verbose,
&flags.silent, 0, &flags.standout, &flags.sortpack,
#ifdef TEXTCOLOR
&flags.use_color,
#else
0,
#endif
&flags.pickup, &flags.confirm,
&flags.safe_dog, &flags.no_rest_on_space};
extern short macflags;
short dlgItem, type;
Rect box;
extern WindowPtr HackWindow;
Handle ItemHndl;
unsigned num;
char *op;
char tmp_name[256];
char savename[PL_NSIZ];
char savedog[63];
char savecat[63];
char savefruit[PL_FSIZ];
char saveorder[20];
DialogRecord dlgR;
DialogPtr optionDlg;
DialogTHndl th, centreDlgBox();
boolean done = FALSE;
short savemacflags = macflags;
struct flag saveflags;
register char *sp, *tmp;
SetCursor(&ARROW_CURSOR);
BlockMove(&flags, &saveflags, sizeof(struct flag));
th = centreDlgBox(130, FALSE);
optionDlg = GetNewDialog(130, (Ptr)&dlgR, (WindowPtr)-1);
/* set initial values of text items */
nmcpy(savename,plname,sizeof(plname)-1);
ITEMTEXT(PLAYER_NAME,plname);
if(*dogname){
nmcpy(savedog,dogname,62);
ITEMTEXT(DOG_NAME,dogname);
}
if(*catname){
nmcpy(savecat,catname,62);
ITEMTEXT(CAT_NAME,catname);
}
#ifdef TUTTI_FRUTTI
if(*pl_fruit){
nmcpy(savefruit,pl_fruit,PL_FSIZ);
ITEMTEXT(FRUIT_NAME,pl_fruit);
}
#else
HIDETEXT(FRUIT_NAME);
HIDETEXT(FRUIT_TEXT);
#endif
nmcpy(saveorder,inv_order,strlen(inv_order)+1);
ITEMTEXT(PACKORDER,inv_order);
/* set initial values of record items */
Sprintf(tmp_name,"%u",flags.end_top);
ITEMTEXT(END_TOP,tmp_name);
Sprintf(tmp_name,"%u",flags.end_around);
ITEMTEXT(END_AROUND,tmp_name);
/* set initial values of checkboxes */
for(dlgItem = MIN_CHECKBOX; dlgItem <= MAX_CHECKBOX; dlgItem++) {
GetDItem(optionDlg, dlgItem, &type, &ItemHndl, &box);
switch (dlgItem){
case NEWS_BOX:
#ifndef NEWS
HIDEITEM(NEWS_BOX);
break;
#endif
case TOMB_BOX:
case REST_SPACE_BOX:
SetCtlValue(ItemHndl,!(*(flag_ptrs[dlgItem])));
break;
case AUTOZOOM_BOX:
SetCtlValue(ItemHndl,macflags & fZoomOnContextSwitch);
break;
#ifndef TEXTCOLOR
case COLOR_BOX:
HIDEITEM(COLOR_BOX);
break;
#endif
default:
SetCtlValue(ItemHndl,*(flag_ptrs[dlgItem]));
}
}
SelIText(optionDlg, PLAYER_NAME, 0, 32767);
ShowWindow(optionDlg);
GetDItem(optionDlg, OK, &type, &ItemHndl, &box);
SetPort (optionDlg);
PenSize(3, 3);
InsetRect (&box, -4, -4);
FrameRoundRect (&box, 16, 16);
while(!done) {
ModalDialog((ProcPtr)0, &dlgItem);
GetDItem(optionDlg, dlgItem, &type, &ItemHndl, &box);
if (dlgItem >= MIN_CHECKBOX && dlgItem <= MAX_CHECKBOX) {
SetCtlValue(ItemHndl, ! GetCtlValue (ItemHndl));
if (dlgItem != AUTOZOOM_BOX)
*(flag_ptrs[dlgItem]) = !*(flag_ptrs[dlgItem]);
else
macflags ^= fZoomOnContextSwitch;
}
else switch(dlgItem){
case SAVE_BUTTON:
GETTEXT(PLAYER_NAME,PL_NSIZ-1);
strncpy(plname, tmp_name, tmp_name[0]+1);
(void)PtoCstr (plname);
GETTEXT(DOG_NAME,62);
strncpy(dogname, tmp_name, tmp_name[0]+1);
(void)PtoCstr (dogname);
GETTEXT(CAT_NAME,62);
strncpy(catname, tmp_name, tmp_name[0]+1);
(void)PtoCstr (catname);
#ifdef TUTTI_FRUTTI
GETTEXT(FRUIT_NAME,PL_FSIZ-1);
strncpy(pl_fruit, tmp_name, tmp_name[0]+1);
(void)PtoCstr (pl_fruit);
#endif
GETTEXT(PACKORDER,19);
op = tmp_name+1;
/* Missing characters in new order are filled in at the end
* from inv_order.
*/
for (sp = op; *sp; sp++)
if ((!index(inv_order, *sp))||(index(sp+1, *sp))){
for(tmp = sp; *tmp;tmp++)
tmp[0]=tmp[1];
sp--;
} /* bad or duplicate char in order - remove it*/
tmp = (char *) alloc((unsigned)(strlen(inv_order)+1));
Strcpy(tmp, op);
for (sp = inv_order, num = strlen(tmp); *sp; sp++)
if (!index(tmp, *sp)) {
tmp[num++] = *sp;
tmp[num] = 0;
}
Strcpy(inv_order, tmp);
free((genericptr_t)tmp);
GETTEXT(END_TOP,5);
op = tmp_name+1;
while(*op) {
num = 1;
if(digit(*op)) {
num = atoi(op);
while(digit(*op)) op++;
} else op++;
}
flags.end_top=num;
GETTEXT(END_AROUND,5);
op = tmp_name+1;
while(*op) {
num = 1;
if(digit(*op)) {
num = atoi(op);
while(digit(*op)) op++;
} else op++;
}
flags.end_around = num;
write_opts();
nmcpy(dogname,savedog,62);
nmcpy(catname,savecat,62);
nmcpy(plname,savename,sizeof(plname)-1);
#ifdef TUTTI_FRUTTI
nmcpy(pl_fruit,savefruit,PL_FSIZ-1);
#endif
nmcpy(inv_order,saveorder,strlen(inv_order)+1);
case CANCEL_BUTTON:
flags = saveflags;
macflags = savemacflags;
done = TRUE;
break;
case OK_BUTTON:
GETTEXT(END_TOP,5);
op = tmp_name+1;
while(*op) {
num = 1;
if(digit(*op)) {
num = atoi(op);
while(digit(*op)) op++;
} else op++;
}
flags.end_top=num;
GETTEXT(END_AROUND,5);
op = tmp_name+1;
while(*op) {
num = 1;
if(digit(*op)) {
num = atoi(op);
while(digit(*op)) op++;
} else op++;
}
flags.end_around = num;
#ifdef TUTTI_FRUTTI
GETTEXT(FRUIT_NAME,PL_FSIZ-1);
(void)PtoCstr (tmp_name);
(void)fruitadd(tmp_name);
nmcpy(pl_fruit,tmp_name,PL_FSIZ-1);
#endif
nmcpy(dogname,savedog,62);
nmcpy(catname,savecat,62);
nmcpy(plname,savename,sizeof(plname)-1);
GETTEXT(PACKORDER,19);
op = tmp_name+1;
/* Missing characters in new order are filled in at the end
* from inv_order.
*/
for (sp = op; *sp; sp++)
if ((!index(inv_order, *sp))||(index(sp+1, *sp))){
for (tmp = sp; *tmp;tmp++)
tmp[0]=tmp[1];
sp--;
} /* bad or duplicate char in order - remove it*/
tmp = (char *) alloc((unsigned)(strlen(inv_order)+1));
Strcpy(tmp, op);
for (sp = inv_order, num = strlen(tmp); *sp; sp++)
if (!index(tmp, *sp)) {
tmp[num++] = *sp;
tmp[num] = 0;
}
Strcpy(inv_order, tmp);
free((genericptr_t)tmp);
flags.female = saveflags.female;
flags.explore = saveflags.explore;
done = TRUE;
break;
default:;
}
}
HideWindow(optionDlg);
DisposDialog (optionDlg);
SetPort (HackWindow);
return 0;
#else
char buf[BUFSZ];
pline("What options do you want to set? ");
getlin(buf);
if(!buf[0] || buf[0] == '\033') {
#ifdef MSDOS
Strcpy(buf,"OPTIONS=");
#ifdef DGK
if (flags.rawio) Strcat(buf,"rawio,");
if (flags.IBMBIOS) Strcat(buf,"IBM_BIOS,");
#endif /* DGK */
#ifdef DECRAINBOW
if (flags.DECRainbow) Strcat(buf,"DEC_Rainbow,");
#endif /* DECRAINBOW */
#else /* MSDOS */
Strcpy(buf,"NETHACKOPTIONS=");
if(flags.standout) Strcat(buf,"standout,");
if(flags.nonull) Strcat(buf,"nonull,");
#endif /* MSDOS */
if(flags.ignintr) Strcat(buf,"ignintr,");
if(flags.num_pad) Strcat(buf,"number_pad,");
#ifdef NEWS
if(flags.nonews) Strcat(buf,"nonews,");
#endif
if(flags.notombstone) Strcat(buf,"notombstone,");
Strcat(buf, flags.female ? "female," : "male,");
if(flags.no_rest_on_space) Strcat(buf,"!rest_on_space,");
if (flags.invlet_constant) Strcat(buf,"fixinv,");
if (flags.sortpack) Strcat(buf,"sortpack,");
if (set_order){
Strcat(buf, "packorder: ");
Strcat(buf, inv_order);
Strcat(buf, ",");
}
#ifdef TEXTCOLOR
if (flags.use_color) Strcat(buf, "color,");
#endif
if (flags.confirm) Strcat(buf,"confirm,");
if (flags.safe_dog) Strcat(buf,"safe_pet,");
if (flags.pickup) Strcat(buf,"pickup,");
if (flags.silent) Strcat(buf,"silent,");
if (flags.time) Strcat(buf,"time,");
if (flags.verbose) Strcat(buf,"verbose,");
#ifdef TUTTI_FRUTTI
Sprintf(eos(buf), "fruit:%s,", pl_fruit);
#endif
if(flags.end_top != 3 || flags.end_around != 2 || flags.end_own){
Sprintf(eos(buf), "endgame: %u top scores/%u around me",
flags.end_top, flags.end_around);
if(flags.end_own) Strcat(buf, "/own scores");
} else {
register char *eop = eos(buf);
if(*--eop == ',') *eop = 0;
}
pline(buf);
} else {
clrlin();
parseoptions(buf, FALSE);
}
return 0;
#endif /* MACOS */
}
int
dotogglepickup() {
flags.pickup = !flags.pickup;
pline("Pickup: %s.", flags.pickup ? "ON" : "OFF");
return 0;
}
#define Page_line(x) if(page_line(x)) goto quit
#define Next_opt(x) if (next_opt(x)) goto quit
void
option_help() {
char buf[BUFSZ];
set_pager(0);
Sprintf(buf, " NetHack Options Help:");
if(page_line("") || page_line(buf) || page_line("")) goto quit;
#ifdef MSDOS
Sprintf(buf, "To set options use OPTIONS=<options> in %s;", configfile);
Page_line(buf);
#else
Page_line("To set options use `NETHACKOPTIONS=\"<options>\"' in your environment;");
#endif
Page_line("or press \"O\" while playing, and type your <options> at the prompt.");
Page_line("In either case, <options> is a list of options separated by commas.");
Page_line("");
Page_line("Boolean options (which can be negated by prefixing them with '!' or \"no\"):");
#ifdef MSDOS
# ifdef DECRAINBOW
Next_opt("DEC_Rainbow, ");
# endif
Next_opt("IBM_BIOS, ");
#endif
#ifdef TEXTCOLOR
Next_opt("color, ");
#endif
Next_opt("confirm, ");
Next_opt("(fe)male, "); Next_opt("fixinv, ");
#ifdef UNIX
Next_opt("ignintr, ");
#endif
#ifdef NEWS
Next_opt("news, ");
#endif
#ifdef UNIX
Next_opt("null, ");
#endif
Next_opt("number_pad, ");
Next_opt("pickup, ");
#ifdef MSDOS
Next_opt("rawio, ");
#endif
Next_opt("rest_on_space, "); Next_opt("safe_pet, ");
Next_opt("silent, "); Next_opt("sortpack, ");
#ifdef UNIX
Next_opt("standout, ");
#endif
Next_opt("time, "); Next_opt("tombstone, ");
Next_opt("and verbose.");
Next_opt("");
Page_line("Compound options:");
Page_line("`name' - your character's name (e.g., name:Merlin-W),");
Page_line("`dogname' - the name of your (first) dog (e.g., dogname:Fang),");
Page_line("`packorder' - the inventory order of the items in your pack");
Sprintf(buf, " (currently, packorder:%s ),", inv_order);
Page_line(buf);
#ifdef TUTTI_FRUTTI
Page_line("`fruit' - the name of a fruit you enjoy eating,");
#endif
Page_line("`endgame' - the parts of the score list you wish to see,");
Page_line("`graphics' - defines the symbols to use in drawing the dungeon map.");
Page_line("");
Page_line("Some of the options can be set only before the game is started. You will");
Page_line("be so informed, if you attempt to set them while in the game.");
set_pager(1);
return;
quit:
(void) next_opt("\033");
set_pager(2);
return;
}
/*
* prints the next boolean option, on the same line if possible, on a new
* line if not. End with next_opt(""). Note that next_opt("\033") may be
* used to abort.
*/
int
next_opt(str)
const char *str;
{
static char buf[121];
static int i = 0;
int r = 0;
if (*str == '\033') {
i = 0; buf[0] = 0; return 0;
}
i += strlen(str);
if (i > min(CO - 2, 120) || !*str) {
r = page_line(buf);
buf[0] = 0;
i = strlen(str);
}
if (*str)
Strcat(buf, str);
else
(void) page_line(str); /* always returns 0 on "" */
return r;
}
#ifdef TUTTI_FRUTTI
/* Returns the fid of the fruit type; if that type already exists, it
* returns the fid of that one; if it does not exist, it adds a new fruit
* type to the chain and returns the new one.
*/
int
fruitadd(str)
char *str;
{
register int i,j;
register struct fruit *f;
#ifdef __GNULINT__
struct fruit *lastf = 0;
#else
struct fruit *lastf;
#endif
int highest_fruit_id = 0;
char buf[PL_FSIZ];
boolean user_specified = (str == pl_fruit);
/* if not user-specified, then it's a fruit name for a fruit on
* a bones level...
*/
/* Note: every fruit has an id (spe for fruit objects) of at least
* 1; 0 is an error.
*/
if (user_specified) {
/* disallow naming after other foods (since it'd be impossible
* to tell the difference)
*/
boolean found = FALSE;
for(i = bases[j=letindex(FOOD_SYM)]; i < bases[j+1]; i++) {
if (!strcmp(objects[i].oc_name, pl_fruit)) {
found = TRUE;
break;
}
}
if (found ||
(!strncmp(buf, "tin of ", 7) && name_to_mon(buf+7) > -1) ||
!strcmp(buf, "empty tin") ||
!strcmp(buf, "tin of spinach") ||
((!strncmp(eos(buf)-6," corpse",7) ||
!strncmp(eos(buf)-3, " egg",4))
&& name_to_mon(buf) > -1))
{
Strcpy(buf, pl_fruit);
Strcpy(pl_fruit, "candied ");
nmcpy(pl_fruit+8, buf, PL_FSIZ-8);
}
}
for(f=ffruit; f; f = f->nextf) {
lastf = f;
if(f->fid > highest_fruit_id) highest_fruit_id = f->fid;
if(!strncmp(str, f->fname, PL_FSIZ))
goto nonew;
}
/* if adding another fruit would overflow spe, use a random
fruit instead... we've got a lot to choose from. */
if (highest_fruit_id >= 127) return rnd(127);
highest_fruit_id++;
f = newfruit();
if (ffruit) lastf->nextf = f;
else ffruit = f;
Strcpy(f->fname, str);
f->fid = highest_fruit_id;
f->nextf = 0;
nonew:
if (user_specified) current_fruit = highest_fruit_id;
return f->fid;
}
#endif
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.