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