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