build - Significantly improve parallel buildworld times
[dragonfly.git] / games / hack / hack.options.c
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 }