Source:NetHack 2.3e/options.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to options.c from the source code of NetHack 2.3e.

Warning! This is the source code from an old release. For newer releases, see Source code

Screenshots and source code from Hack are used under the CWI license.

1.    /*	SCCS Id: @(#)options.c	2.3	87/12/12
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    
4.    #include "config.h"
5.    #include "hack.h"
6.    extern char *eos();
7.    #ifdef SORTING
8.    static boolean set_order;
9.    #endif
10.   
11.   initoptions()
12.   {
13.   	register char *opts;
14.   	extern char *getenv();
15.   
16.   	flags.time = flags.nonews = flags.notombstone = flags.end_own =
17.   	flags.standout = flags.nonull = FALSE;
18.   	flags.no_rest_on_space = TRUE;
19.   	flags.invlet_constant = TRUE;
20.   	flags.end_top = 5;
21.   	flags.end_around = 4;
22.   	flags.female = FALSE;			/* players are usually male */
23.   #ifdef SORTING
24.   	flags.sortpack = TRUE;
25.   #endif
26.   #ifdef SAFE_ATTACK
27.   	flags.confirm = TRUE;
28.   #endif
29.   #ifdef DGKMOD
30.   	flags.silent = 	flags.pickup = TRUE;
31.   #endif
32.   #ifdef DGK
33.   	flags.IBMBIOS = flags.DECRainbow = flags.rawio = FALSE;
34.   	read_config_file();
35.   #endif
36.   #ifdef HACKOPTIONS
37.   	if(opts = getenv("HACKOPTIONS"))
38.   		parseoptions(opts,TRUE);
39.   #endif
40.   }
41.   
42.   parseoptions(opts, from_env)
43.   register char *opts;
44.   boolean from_env;
45.   {
46.   	register char *op,*op2;
47.   	unsigned num;
48.   	boolean negated;
49.   
50.   	if(op = index(opts, ',')) {
51.   		*op++ = 0;
52.   		parseoptions(op, from_env);
53.   	}
54.   	if(op = index(opts, ' ')) {
55.   		op2 = op;
56.   		while(*op++)
57.   			if(*op != ' ') *op2++ = *op;
58.   	}
59.   	if(!*opts) return;
60.   	negated = FALSE;
61.   	while((*opts == '!') || !strncmp(opts, "no", 2)) {
62.   		if(*opts == '!') opts++; else opts += 2;
63.   		negated = !negated;
64.   	}
65.   	
66.   #ifndef DGK
67.   	if(!strncmp(opts,"standout",4)) {
68.   		flags.standout = !negated;
69.   		return;
70.   	}
71.   
72.   	if(!strncmp(opts,"null",4)) {
73.   		flags.nonull = negated;
74.   		return;
75.   	}
76.   
77.   	if(!strncmp(opts,"tombstone",4)) {
78.   		flags.notombstone = negated;
79.   		return;
80.   	}
81.   
82.   	if(!strncmp(opts,"news",4)) {
83.   		flags.nonews = negated;
84.   		return;
85.   	}
86.   #endif
87.   
88.   #ifdef SAFE_ATTACK
89.   	if (!strncmp(opts, "conf", 4)) {
90.   		flags.confirm = !negated;
91.   		return;
92.   	}
93.   
94.   #endif
95.   #ifdef DGKMOD
96.   	if (!strncmp(opts, "sile", 4)) {
97.   		flags.silent = !negated;
98.   		return;
99.   	}
100.  
101.  	if (!strncmp(opts, "pick", 4)) {
102.  		flags.pickup = !negated;
103.  		return;
104.  	}
105.  #endif
106.  #ifdef DGK
107.  	if (!strncmp(opts, "IBMB", 4)) {
108.  		flags.IBMBIOS = !negated;
109.  		return;
110.  	}
111.  
112.  	if (!strncmp(opts, "rawi", 4)) {
113.  		if (from_env)
114.  			flags.rawio = !negated;
115.  		else
116.  			pline("'rawio' only settable from %s.", configfile);
117.  		return;
118.  	}
119.  
120.  	if (!strncmp(opts, "DECR", 4)) {
121.  		flags.DECRainbow = !negated;
122.  		return;
123.  	}
124.  #endif
125.  
126.  #ifdef SORTING
127.  	if (!strncmp(opts, "sort", 4)) {
128.  		flags.sortpack = !negated;
129.  		return;
130.  	}
131.  
132.  	/*
133.  	 * the order to list the pack
134.  	 */
135.  	if (!strncmp(opts,"packorder",4)) {
136.  		register char	*sp, *tmp;
137.  		extern char	inv_order[];
138.  		int tmpend;
139.  
140.  		op = index(opts,':');
141.  		if(!op) goto bad;
142.  		op++;			/* skip : */
143.  
144.  		/* Missing characters in new order are filled in at the end 
145.  		 * from inv_order.
146.  		 */
147.  		for (sp = op; *sp; sp++)
148.  			if (!index(inv_order, *sp))
149.  				goto bad;		/* bad char in order */
150.  			else if (index(sp + 1, *sp))
151.  				goto bad;		/* dup char in order */
152.  		tmp = (char *) alloc((unsigned)(strlen(inv_order)+1));
153.  		(void) strcpy(tmp, op);
154.  		for (sp = inv_order, tmpend = strlen(tmp); *sp; sp++)
155.  			if (!index(tmp, *sp)) {
156.  				tmp[tmpend++] = *sp;
157.  				tmp[tmpend] = 0;
158.  			}
159.  		(void) strcpy(inv_order, tmp);
160.  		free(tmp);
161.  		set_order = TRUE;
162.  		return;
163.  	}
164.  #endif
165.  
166.  	if(!strncmp(opts,"time",4)) {
167.  		flags.time = !negated;
168.  		flags.botl = 1;
169.  		return;
170.  	}
171.  
172.  	if(!strncmp(opts,"restonspace",4)) {
173.  		flags.no_rest_on_space = negated;
174.  		return;
175.  	}
176.  
177.  	if(!strncmp(opts,"fixinv",4)) {
178.  		flags.invlet_constant = !negated;
179.  		if(!from_env && flags.invlet_constant) reassign ();
180.  		return;
181.  	}
182.  
183.  	if(!strncmp(opts,"male",4)) {
184.  #ifdef KAA
185.  		if(!from_env && flags.female != negated)
186.  			pline("That is not anatomically possible.");
187.  		else
188.  #endif
189.  			flags.female = negated;
190.  		return;
191.  	}
192.  	if(!strncmp(opts,"female",6)) {
193.  #ifdef KAA
194.  		if(!from_env && flags.female == negated)
195.  			pline("That is not anatomically possible.");
196.  		else
197.  #endif
198.  			flags.female = !negated;
199.  		return;
200.  	}
201.  
202.  	/* name:string */
203.  	if(!strncmp(opts,"name",4)) {
204.  		extern char plname[PL_NSIZ];
205.  		if(!from_env) {
206.  #ifdef DGK
207.  		  pline("'name' only settable from %s.", configfile);
208.  #else
209.  		  pline("The playername can be set only from HACKOPTIONS.");
210.  #endif
211.  		  return;
212.  		}
213.  		op = index(opts,':');
214.  		if(!op) goto bad;
215.  		nmcpy(plname, op+1, sizeof(plname)-1);
216.  		return;
217.  	}
218.  
219.  #ifdef GRAPHICS
220.  	/* graphics:string */
221.  	if(!strncmp(opts,"graphics",4)) {
222.  		if(!from_env) {
223.  #ifdef DGK
224.  		  pline("'graphics' only settable from %s.", configfile);
225.  #else
226.  		  pline("The graphics string can be set only from HACKOPTIONS.");
227.  #endif
228.  		  return;
229.  		}
230.  		op = index(opts,':');
231.  		if(!op)
232.  		    goto bad;
233.  		else
234.  		    opts = op + 1;
235.  /*
236.   * You could have problems here if you configure FOUNTAINS, SPIDERS, NEWCLASS
237.   * or SINKS in or out and forget to change the tail entries in your graphics
238.   * string.
239.   */
240.  #define SETPCHAR(f, n)	showsyms.f = (strlen(opts) > n) ? opts[n] : defsyms.f
241.  		SETPCHAR(stone, 0);
242.  		SETPCHAR(vwall, 1);
243.  		SETPCHAR(hwall, 2);
244.  		SETPCHAR(tlcorn, 3);
245.  		SETPCHAR(trcorn, 4);
246.  		SETPCHAR(blcorn, 5);
247.  		SETPCHAR(brcorn, 6);
248.  		SETPCHAR(door, 7);
249.  		SETPCHAR(room, 8);
250.  		SETPCHAR(corr, 9);
251.  		SETPCHAR(upstair, 10);
252.  		SETPCHAR(dnstair, 11);
253.  		SETPCHAR(trap, 12);
254.  #ifdef FOUNTAINS
255.  		SETPCHAR(pool, 13);
256.  		SETPCHAR(fountain, 14);
257.  #endif
258.  #ifdef NEWCLASS
259.  		SETPCHAR(throne, 15);
260.  #endif
261.  #ifdef SPIDERS
262.  		SETPCHAR(web, 16);
263.  #endif
264.  #ifdef SINKS
265.  		SETPCHAR(sink, 17);
266.  #endif
267.  #undef SETPCHAR
268.  		return;
269.  	}
270.  #endif /* GRAPHICS */
271.  
272.  	/* endgame:5t[op] 5a[round] o[wn] */
273.  	if(!strncmp(opts,"endgame",3)) {
274.  		op = index(opts,':');
275.  		if(!op) goto bad;
276.  		op++;
277.  		while(*op) {
278.  			num = 1;
279.  			if(digit(*op)) {
280.  				num = atoi(op);
281.  				while(digit(*op)) op++;
282.  			} else
283.  			if(*op == '!') {
284.  				negated = !negated;
285.  				op++;
286.  			}
287.  			switch(*op) {
288.  			case 't':
289.  				flags.end_top = num;
290.  				break;
291.  			case 'a':
292.  				flags.end_around = num;
293.  				break;
294.  			case 'o':
295.  				flags.end_own = !negated;
296.  				break;
297.  			default:
298.  				goto bad;
299.  			}
300.  			while(letter(*++op)) ;
301.  			if(*op == '/') op++;
302.  		}
303.  		return;
304.  	}
305.  #ifdef	DOGNAME
306.  	if(!strncmp(opts, "dogname", 3)) {
307.  		extern char dogname[];
308.  		op = index(opts, ':');
309.  		if (!op) goto bad;
310.  		nmcpy(dogname, ++op, 62);
311.  		return;
312.  	}
313.  #endif	/* DOGNAME */
314.  bad:
315.  	if(!from_env) {
316.  		if(!strncmp(opts, "help", 4)) {
317.  			option_help();
318.  			return;
319.  		}
320.  		pline("Bad option: %s.  Type `O help<cr>' for help.", opts);
321.  		return;
322.  	}
323.  #ifdef DGK
324.  	printf("Bad syntax in OPTIONS in %s.", configfile);
325.  #else
326.  	puts("Bad syntax in HACKOPTIONS.");
327.  	puts("Use for example:");
328.  	puts(
329.  "HACKOPTIONS=\"!restonspace,notombstone,endgame:own/5 topscorers/4 around me\""
330.  	);
331.  #endif
332.  	getret();
333.  }
334.  
335.  doset()
336.  {
337.  	char buf[BUFSZ];
338.  #ifdef SORTING
339.  	extern char inv_order[];
340.  #endif
341.  
342.  	pline("What options do you want to set? ");
343.  	getlin(buf);
344.  	if(!buf[0] || buf[0] == '\033') {
345.  #ifdef DGK
346.  	    (void) strcpy(buf,"OPTIONS=");
347.  #else
348.  	    (void) strcpy(buf,"HACKOPTIONS=");
349.  	    (void) strcat(buf, flags.female ? "female," : "male,");
350.  	    if(flags.standout) (void) strcat(buf,"standout,");
351.  	    if(flags.nonull) (void) strcat(buf,"nonull,");
352.  	    if(flags.nonews) (void) strcat(buf,"nonews,");
353.  	    if(flags.notombstone) (void) strcat(buf,"notombstone,");
354.  	    if(flags.no_rest_on_space)	(void) strcat(buf,"!rest_on_space,");
355.  #endif
356.  #ifdef SORTING
357.  	    if (flags.sortpack) (void) strcat(buf,"sortpack,");
358.  	    if (set_order){
359.  		(void) strcat(buf, "packorder: ");
360.  		(void) strcat(buf, inv_order);
361.  		(void) strcat(buf, ",");
362.  	    }
363.  #endif
364.  #ifdef SAFE_ATTACK
365.  	    if (flags.confirm) (void) strcat(buf,"confirm,");
366.  #endif
367.  #ifdef DGKMOD
368.  	    if (flags.pickup) (void) strcat(buf,"pickup,");
369.  	    if (flags.silent) (void) strcat(buf,"silent,");
370.  #endif
371.  #ifdef DGK
372.  	    if (flags.rawio) (void) strcat(buf,"rawio,");
373.  	    if (flags.IBMBIOS) (void) strcat(buf,"IBMBIOS,");
374.  	    if (flags.DECRainbow) (void) strcat(buf,"DECRainbow,");
375.  #endif
376.  	    if(flags.time) (void) strcat(buf,"time,");
377.  	    if(flags.end_top != 5 || flags.end_around != 4 || flags.end_own){
378.  		(void) sprintf(eos(buf), "endgame: %u topscores/%u around me",
379.  			flags.end_top, flags.end_around);
380.  		if(flags.end_own) (void) strcat(buf, "/own scores");
381.  	    } else {
382.  		register char *eop = eos(buf);
383.  		if(*--eop == ',') *eop = 0;
384.  	    }
385.  	    pline(buf);
386.  	} else
387.  	    parseoptions(buf, FALSE);
388.  
389.  	return(0);
390.  }
391.  
392.  #ifdef DGKMOD
393.  dotogglepickup() {
394.  	flags.pickup = !flags.pickup;
395.  	pline("Pickup: %s.", flags.pickup ? "ON" : "OFF");
396.  	return (0);
397.  }
398.  #endif
399.  
400.  nmcpy(dest, source, maxlen)
401.  	char	*dest, *source;
402.  	int	maxlen;
403.  {
404.  	char	*cs, *cd;
405.  	int	count;
406.  
407.  	cd = dest;
408.  	cs = source;
409.  	for(count = 1; count < maxlen; count++) {
410.  		if(*cs == ',') break;
411.  		*cd++ = *cs++;
412.  	}
413.  	*cd = 0;
414.  }
415.  
416.  #ifdef SORTING
417.  char	*packorder =
418.  # ifdef SPELLS
419.  			"\")[%?+/=!(*0";
420.  # else
421.  			"\")[%?/=!(*0";
422.  # endif
423.  #endif
424.  #define Page_line(x)	if(page_line(x)) goto quit
425.  
426.  option_help() {
427.  	char	buf[BUFSZ];
428.  
429.  	set_pager(0);
430.  	(void) sprintf(buf, "        Net%s Options Help:",
431.  #ifndef QUEST
432.  			"Hack");
433.  #else
434.  			"Quest");
435.  #endif
436.  	if(page_line("") || page_line(buf) || page_line(""))	 goto quit;
437.  
438.  #ifdef DGK
439.  	(void) sprintf(buf, "To set options use OPTIONS=<options> in %s", configfile);
440.  	Page_line(buf);
441.  #else
442.  	Page_line("To set options use `HACKOPTIONS=\"<options>\"' in your environment");
443.  #endif
444.  
445.  	Page_line("or give the command \"O\" followed by the line <options> while playing.");
446.  	Page_line("Here <options> is a list of options separated by commas.");
447.  	Page_line("");
448.  
449.  #ifdef DGK
450.  	Page_line("Boolean options are confirm, pickup, rawio, silent, sortpack, time, IBMBIOS,");
451.  	Page_line("and DECRainbow.  These can be negated by prefixing them with '!' or \"no\".");
452.  #else
453.  	Page_line("Boolean options are rest_on_space, news, time, null tombstone, and (fe)male,");
454.  	Page_line("These can be negated by prefixing them with '!' or \"no\".");
455.  #endif
456.  	Page_line("");
457.  
458.  	Page_line("The compound options are `name', (eg. name:Merlin-W,),");
459.  #ifdef	DOGNAME
460.  	Page_line("`dogname', the name of your (first) dog (eg. dogname:Fang,),");
461.  #endif
462.  
463.  #ifdef SORTING
464.  	Page_line("`packorder'; the order that items should appear in your pack");
465.  	(void)sprintf(buf, "(the default is:  packorder:%s ), ", packorder);
466.  	Page_line(buf);
467.  #endif
468.  
469.  #ifdef GRAPHICS
470.  	Page_line("`endgame', and `graphics'.");
471.  #else
472.  	Page_line("and `endgame'.");
473.  #endif
474.  	Page_line("");
475.  
476.  	Page_line("The `endgame' option is followed by a description of which parts of");
477.  	Page_line("the scorelist you wish to see.  You might for example say:");
478.  	Page_line("");
479.  	Page_line("\"endgame:own scores/5 top scores/4 around my score\".");
480.  
481.  	set_pager(1);
482.  	return;
483.  quit:
484.  	set_pager(2);
485.  	return;
486.  }