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