Initial import from FreeBSD RELENG_4:
[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
5 #include <stdlib.h>
6 #include "config.h"
7 #include "hack.h"
8 extern char *eos();
9
10 initoptions()
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 parseoptions(opts, from_env)
27 char *opts;
28 boolean 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                 extern char plname[PL_NSIZ];
101                 if(!from_env) {
102                   pline("The playername can be set only from HACKOPTIONS.");
103                   return;
104                 }
105                 op = index(opts,':');
106                 if(!op) goto bad;
107                 (void) strncpy(plname, op+1, sizeof(plname)-1);
108                 return;
109         }
110
111         /* endgame:5t[op] 5a[round] o[wn] */
112         if(!strncmp(opts,"endgame",3)) {
113                 op = index(opts,':');
114                 if(!op) goto bad;
115                 op++;
116                 while(*op) {
117                         num = 1;
118                         if(digit(*op)) {
119                                 num = atoi(op);
120                                 while(digit(*op)) op++;
121                         } else
122                         if(*op == '!') {
123                                 negated = !negated;
124                                 op++;
125                         }
126                         switch(*op) {
127                         case 't':
128                                 flags.end_top = num;
129                                 break;
130                         case 'a':
131                                 flags.end_around = num;
132                                 break;
133                         case 'o':
134                                 flags.end_own = !negated;
135                                 break;
136                         default:
137                                 goto bad;
138                         }
139                         while(letter(*++op)) ;
140                         if(*op == '/') op++;
141                 }
142                 return;
143         }
144 bad:
145         if(!from_env) {
146                 if(!strncmp(opts, "help", 4)) {
147                         pline("%s%s%s",
148 "To set options use `HACKOPTIONS=\"<options>\"' in your environment, or ",
149 "give the command 'o' followed by the line `<options>' while playing. ",
150 "Here <options> is a list of <option>s separated by commas." );
151                         pline("%s%s%s",
152 "Simple (boolean) options are rest_on_space, news, time, ",
153 "null, tombstone, (fe)male. ",
154 "These can be negated by prefixing them with '!' or \"no\"." );
155                         pline("%s",
156 "A string option is name, as in HACKOPTIONS=\"name:Merlin-W\"." );
157                         pline("%s%s%s",
158 "A compound option is endgame; it is followed by a description of what ",
159 "parts of the scorelist you want to see. You might for example say: ",
160 "`endgame:own scores/5 top scores/4 around my score'." );
161                         return;
162                 }
163                 pline("Bad option: %s.", opts);
164                 pline("Type `o help<cr>' for help.");
165                 return;
166         }
167         puts("Bad syntax in HACKOPTIONS.");
168         puts("Use for example:");
169         puts(
170 "HACKOPTIONS=\"!restonspace,notombstone,endgame:own/5 topscorers/4 around me\""
171         );
172         getret();
173 }
174
175 doset()
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             (void) strcpy(buf,"HACKOPTIONS=");
183             (void) strcat(buf, flags.female ? "female," : "male,");
184             if(flags.standout) (void) strcat(buf,"standout,");
185             if(flags.nonull) (void) strcat(buf,"nonull,");
186             if(flags.nonews) (void) strcat(buf,"nonews,");
187             if(flags.time) (void) strcat(buf,"time,");
188             if(flags.notombstone) (void) strcat(buf,"notombstone,");
189             if(flags.no_rest_on_space)
190                 (void) strcat(buf,"!rest_on_space,");
191             if(flags.end_top != 5 || flags.end_around != 4 || flags.end_own){
192                 (void) sprintf(eos(buf), "endgame: %u topscores/%u around me",
193                         flags.end_top, flags.end_around);
194                 if(flags.end_own) (void) 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 }