xref: /dragonfly/games/hack/hack.options.c (revision 8a7bdfea)
1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.options.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.options.c,v 1.5 1999/11/16 02:57:08 billf Exp $ */
4 /* $DragonFly: src/games/hack/hack.options.c,v 1.3 2006/08/21 19:45:32 pavalos Exp $ */
5 
6 #include "hack.h"
7 
8 static void	parseoptions(char *, bool);
9 
10 void
11 initoptions(void)
12 {
13 	char *opts;
14 
15 	flags.time = flags.nonews = flags.notombstone = flags.end_own =
16 	flags.standout = flags.nonull = FALSE;
17 	flags.no_rest_on_space = TRUE;
18 	flags.invlet_constant = TRUE;
19 	flags.end_top = 5;
20 	flags.end_around = 4;
21 	flags.female = FALSE;			/* players are usually male */
22 
23 	if((opts = getenv("HACKOPTIONS")))
24 		parseoptions(opts,TRUE);
25 }
26 
27 static void
28 parseoptions(char *opts, bool from_env)
29 {
30 	char *op,*op2;
31 	unsigned num;
32 	boolean negated;
33 
34 	if((op = index(opts, ','))) {
35 		*op++ = 0;
36 		parseoptions(op, from_env);
37 	}
38 	if((op = index(opts, ' '))) {
39 		op2 = op;
40 		while(*op++)
41 			if(*op != ' ') *op2++ = *op;
42 	}
43 	if(!*opts) return;
44 	negated = FALSE;
45 	while((*opts == '!') || !strncmp(opts, "no", 2)) {
46 		if(*opts == '!') opts++; else opts += 2;
47 		negated = !negated;
48 	}
49 
50 	if(!strncmp(opts,"standout",8)) {
51 		flags.standout = !negated;
52 		return;
53 	}
54 
55 	if(!strncmp(opts,"null",3)) {
56 		flags.nonull = negated;
57 		return;
58 	}
59 
60 	if(!strncmp(opts,"tombstone",4)) {
61 		flags.notombstone = negated;
62 		return;
63 	}
64 
65 	if(!strncmp(opts,"news",4)) {
66 		flags.nonews = negated;
67 		return;
68 	}
69 
70 	if(!strncmp(opts,"time",4)) {
71 		flags.time = !negated;
72 		flags.botl = 1;
73 		return;
74 	}
75 
76 	if(!strncmp(opts,"restonspace",4)) {
77 		flags.no_rest_on_space = negated;
78 		return;
79 	}
80 
81 	if(!strncmp(opts,"fixinv",4)) {
82 		if(from_env)
83 			flags.invlet_constant = !negated;
84 		else
85 			pline("The fixinvlet option must be in HACKOPTIONS.");
86 		return;
87 	}
88 
89 	if(!strncmp(opts,"male",4)) {
90 		flags.female = negated;
91 		return;
92 	}
93 	if(!strncmp(opts,"female",6)) {
94 		flags.female = !negated;
95 		return;
96 	}
97 
98 	/* name:string */
99 	if(!strncmp(opts,"name",4)) {
100 		if(!from_env) {
101 		  pline("The playername can be set only from HACKOPTIONS.");
102 		  return;
103 		}
104 		op = index(opts,':');
105 		if(!op) goto bad;
106 		strncpy(plname, op+1, sizeof(plname)-1);
107 		return;
108 	}
109 
110 	/* endgame:5t[op] 5a[round] o[wn] */
111 	if(!strncmp(opts,"endgame",3)) {
112 		op = index(opts,':');
113 		if(!op) goto bad;
114 		op++;
115 		while(*op) {
116 			num = 1;
117 			if(digit(*op)) {
118 				num = atoi(op);
119 				while(digit(*op)) op++;
120 			} else
121 			if(*op == '!') {
122 				negated = !negated;
123 				op++;
124 			}
125 			switch(*op) {
126 			case 't':
127 				flags.end_top = num;
128 				break;
129 			case 'a':
130 				flags.end_around = num;
131 				break;
132 			case 'o':
133 				flags.end_own = !negated;
134 				break;
135 			default:
136 				goto bad;
137 			}
138 			while(letter(*++op)) ;
139 			if(*op == '/') op++;
140 		}
141 		return;
142 	}
143 bad:
144 	if(!from_env) {
145 		if(!strncmp(opts, "help", 4)) {
146 			pline("%s%s%s",
147 "To set options use `HACKOPTIONS=\"<options>\"' in your environment, or ",
148 "give the command 'o' followed by the line `<options>' while playing. ",
149 "Here <options> is a list of <option>s separated by commas." );
150 			pline("%s%s%s",
151 "Simple (boolean) options are rest_on_space, news, time, ",
152 "null, tombstone, (fe)male. ",
153 "These can be negated by prefixing them with '!' or \"no\"." );
154 			pline("%s",
155 "A string option is name, as in HACKOPTIONS=\"name:Merlin-W\"." );
156 			pline("%s%s%s",
157 "A compound option is endgame; it is followed by a description of what ",
158 "parts of the scorelist you want to see. You might for example say: ",
159 "`endgame:own scores/5 top scores/4 around my score'." );
160 			return;
161 		}
162 		pline("Bad option: %s.", opts);
163 		pline("Type `o help<cr>' for help.");
164 		return;
165 	}
166 	puts("Bad syntax in HACKOPTIONS.");
167 	puts("Use for example:");
168 	puts(
169 "HACKOPTIONS=\"!restonspace,notombstone,endgame:own/5 topscorers/4 around me\""
170 	);
171 	getret();
172 }
173 
174 int
175 doset(void)
176 {
177 	char buf[BUFSZ];
178 
179 	pline("What options do you want to set? ");
180 	getlin(buf);
181 	if(!buf[0] || buf[0] == '\033') {
182 	    strcpy(buf,"HACKOPTIONS=");
183 	    strcat(buf, flags.female ? "female," : "male,");
184 	    if(flags.standout) strcat(buf,"standout,");
185 	    if(flags.nonull) strcat(buf,"nonull,");
186 	    if(flags.nonews) strcat(buf,"nonews,");
187 	    if(flags.time) strcat(buf,"time,");
188 	    if(flags.notombstone) strcat(buf,"notombstone,");
189 	    if(flags.no_rest_on_space)
190 		strcat(buf,"!rest_on_space,");
191 	    if(flags.end_top != 5 || flags.end_around != 4 || flags.end_own){
192 		sprintf(eos(buf), "endgame: %u topscores/%u around me",
193 			flags.end_top, flags.end_around);
194 		if(flags.end_own) strcat(buf, "/own scores");
195 	    } else {
196 		char *eop = eos(buf);
197 		if(*--eop == ',') *eop = 0;
198 	    }
199 	    pline(buf);
200 	} else
201 	    parseoptions(buf, FALSE);
202 
203 	return(0);
204 }
205