Source:NetHack 2.3e/options.c
Jump to navigation
Jump to search
Below is the full text to options.c from the source code of NetHack 2.3e.
Warning! This is the source code from an old release. For newer releases, see Source code
Screenshots and source code from Hack are used under the CWI license.
1. /* SCCS Id: @(#)options.c 2.3 87/12/12 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include "config.h" 5. #include "hack.h" 6. extern char *eos(); 7. #ifdef SORTING 8. static boolean set_order; 9. #endif 10. 11. initoptions() 12. { 13. register char *opts; 14. extern char *getenv(); 15. 16. flags.time = flags.nonews = flags.notombstone = flags.end_own = 17. flags.standout = flags.nonull = FALSE; 18. flags.no_rest_on_space = TRUE; 19. flags.invlet_constant = TRUE; 20. flags.end_top = 5; 21. flags.end_around = 4; 22. flags.female = FALSE; /* players are usually male */ 23. #ifdef SORTING 24. flags.sortpack = TRUE; 25. #endif 26. #ifdef SAFE_ATTACK 27. flags.confirm = TRUE; 28. #endif 29. #ifdef DGKMOD 30. flags.silent = flags.pickup = TRUE; 31. #endif 32. #ifdef DGK 33. flags.IBMBIOS = flags.DECRainbow = flags.rawio = FALSE; 34. read_config_file(); 35. #endif 36. #ifdef HACKOPTIONS 37. if(opts = getenv("HACKOPTIONS")) 38. parseoptions(opts,TRUE); 39. #endif 40. } 41. 42. parseoptions(opts, from_env) 43. register char *opts; 44. boolean from_env; 45. { 46. register char *op,*op2; 47. unsigned num; 48. boolean negated; 49. 50. if(op = index(opts, ',')) { 51. *op++ = 0; 52. parseoptions(op, from_env); 53. } 54. if(op = index(opts, ' ')) { 55. op2 = op; 56. while(*op++) 57. if(*op != ' ') *op2++ = *op; 58. } 59. if(!*opts) return; 60. negated = FALSE; 61. while((*opts == '!') || !strncmp(opts, "no", 2)) { 62. if(*opts == '!') opts++; else opts += 2; 63. negated = !negated; 64. } 65. 66. #ifndef DGK 67. if(!strncmp(opts,"standout",4)) { 68. flags.standout = !negated; 69. return; 70. } 71. 72. if(!strncmp(opts,"null",4)) { 73. flags.nonull = negated; 74. return; 75. } 76. 77. if(!strncmp(opts,"tombstone",4)) { 78. flags.notombstone = negated; 79. return; 80. } 81. 82. if(!strncmp(opts,"news",4)) { 83. flags.nonews = negated; 84. return; 85. } 86. #endif 87. 88. #ifdef SAFE_ATTACK 89. if (!strncmp(opts, "conf", 4)) { 90. flags.confirm = !negated; 91. return; 92. } 93. 94. #endif 95. #ifdef DGKMOD 96. if (!strncmp(opts, "sile", 4)) { 97. flags.silent = !negated; 98. return; 99. } 100. 101. if (!strncmp(opts, "pick", 4)) { 102. flags.pickup = !negated; 103. return; 104. } 105. #endif 106. #ifdef DGK 107. if (!strncmp(opts, "IBMB", 4)) { 108. flags.IBMBIOS = !negated; 109. return; 110. } 111. 112. if (!strncmp(opts, "rawi", 4)) { 113. if (from_env) 114. flags.rawio = !negated; 115. else 116. pline("'rawio' only settable from %s.", configfile); 117. return; 118. } 119. 120. if (!strncmp(opts, "DECR", 4)) { 121. flags.DECRainbow = !negated; 122. return; 123. } 124. #endif 125. 126. #ifdef SORTING 127. if (!strncmp(opts, "sort", 4)) { 128. flags.sortpack = !negated; 129. return; 130. } 131. 132. /* 133. * the order to list the pack 134. */ 135. if (!strncmp(opts,"packorder",4)) { 136. register char *sp, *tmp; 137. extern char inv_order[]; 138. int tmpend; 139. 140. op = index(opts,':'); 141. if(!op) goto bad; 142. op++; /* skip : */ 143. 144. /* Missing characters in new order are filled in at the end 145. * from inv_order. 146. */ 147. for (sp = op; *sp; sp++) 148. if (!index(inv_order, *sp)) 149. goto bad; /* bad char in order */ 150. else if (index(sp + 1, *sp)) 151. goto bad; /* dup char in order */ 152. tmp = (char *) alloc((unsigned)(strlen(inv_order)+1)); 153. (void) strcpy(tmp, op); 154. for (sp = inv_order, tmpend = strlen(tmp); *sp; sp++) 155. if (!index(tmp, *sp)) { 156. tmp[tmpend++] = *sp; 157. tmp[tmpend] = 0; 158. } 159. (void) strcpy(inv_order, tmp); 160. free(tmp); 161. set_order = TRUE; 162. return; 163. } 164. #endif 165. 166. if(!strncmp(opts,"time",4)) { 167. flags.time = !negated; 168. flags.botl = 1; 169. return; 170. } 171. 172. if(!strncmp(opts,"restonspace",4)) { 173. flags.no_rest_on_space = negated; 174. return; 175. } 176. 177. if(!strncmp(opts,"fixinv",4)) { 178. flags.invlet_constant = !negated; 179. if(!from_env && flags.invlet_constant) reassign (); 180. return; 181. } 182. 183. if(!strncmp(opts,"male",4)) { 184. #ifdef KAA 185. if(!from_env && flags.female != negated) 186. pline("That is not anatomically possible."); 187. else 188. #endif 189. flags.female = negated; 190. return; 191. } 192. if(!strncmp(opts,"female",6)) { 193. #ifdef KAA 194. if(!from_env && flags.female == negated) 195. pline("That is not anatomically possible."); 196. else 197. #endif 198. flags.female = !negated; 199. return; 200. } 201. 202. /* name:string */ 203. if(!strncmp(opts,"name",4)) { 204. extern char plname[PL_NSIZ]; 205. if(!from_env) { 206. #ifdef DGK 207. pline("'name' only settable from %s.", configfile); 208. #else 209. pline("The playername can be set only from HACKOPTIONS."); 210. #endif 211. return; 212. } 213. op = index(opts,':'); 214. if(!op) goto bad; 215. nmcpy(plname, op+1, sizeof(plname)-1); 216. return; 217. } 218. 219. #ifdef GRAPHICS 220. /* graphics:string */ 221. if(!strncmp(opts,"graphics",4)) { 222. if(!from_env) { 223. #ifdef DGK 224. pline("'graphics' only settable from %s.", configfile); 225. #else 226. pline("The graphics string can be set only from HACKOPTIONS."); 227. #endif 228. return; 229. } 230. op = index(opts,':'); 231. if(!op) 232. goto bad; 233. else 234. opts = op + 1; 235. /* 236. * You could have problems here if you configure FOUNTAINS, SPIDERS, NEWCLASS 237. * or SINKS in or out and forget to change the tail entries in your graphics 238. * string. 239. */ 240. #define SETPCHAR(f, n) showsyms.f = (strlen(opts) > n) ? opts[n] : defsyms.f 241. SETPCHAR(stone, 0); 242. SETPCHAR(vwall, 1); 243. SETPCHAR(hwall, 2); 244. SETPCHAR(tlcorn, 3); 245. SETPCHAR(trcorn, 4); 246. SETPCHAR(blcorn, 5); 247. SETPCHAR(brcorn, 6); 248. SETPCHAR(door, 7); 249. SETPCHAR(room, 8); 250. SETPCHAR(corr, 9); 251. SETPCHAR(upstair, 10); 252. SETPCHAR(dnstair, 11); 253. SETPCHAR(trap, 12); 254. #ifdef FOUNTAINS 255. SETPCHAR(pool, 13); 256. SETPCHAR(fountain, 14); 257. #endif 258. #ifdef NEWCLASS 259. SETPCHAR(throne, 15); 260. #endif 261. #ifdef SPIDERS 262. SETPCHAR(web, 16); 263. #endif 264. #ifdef SINKS 265. SETPCHAR(sink, 17); 266. #endif 267. #undef SETPCHAR 268. return; 269. } 270. #endif /* GRAPHICS */ 271. 272. /* endgame:5t[op] 5a[round] o[wn] */ 273. if(!strncmp(opts,"endgame",3)) { 274. op = index(opts,':'); 275. if(!op) goto bad; 276. op++; 277. while(*op) { 278. num = 1; 279. if(digit(*op)) { 280. num = atoi(op); 281. while(digit(*op)) op++; 282. } else 283. if(*op == '!') { 284. negated = !negated; 285. op++; 286. } 287. switch(*op) { 288. case 't': 289. flags.end_top = num; 290. break; 291. case 'a': 292. flags.end_around = num; 293. break; 294. case 'o': 295. flags.end_own = !negated; 296. break; 297. default: 298. goto bad; 299. } 300. while(letter(*++op)) ; 301. if(*op == '/') op++; 302. } 303. return; 304. } 305. #ifdef DOGNAME 306. if(!strncmp(opts, "dogname", 3)) { 307. extern char dogname[]; 308. op = index(opts, ':'); 309. if (!op) goto bad; 310. nmcpy(dogname, ++op, 62); 311. return; 312. } 313. #endif /* DOGNAME */ 314. bad: 315. if(!from_env) { 316. if(!strncmp(opts, "help", 4)) { 317. option_help(); 318. return; 319. } 320. pline("Bad option: %s. Type `O help<cr>' for help.", opts); 321. return; 322. } 323. #ifdef DGK 324. printf("Bad syntax in OPTIONS in %s.", configfile); 325. #else 326. puts("Bad syntax in HACKOPTIONS."); 327. puts("Use for example:"); 328. puts( 329. "HACKOPTIONS=\"!restonspace,notombstone,endgame:own/5 topscorers/4 around me\"" 330. ); 331. #endif 332. getret(); 333. } 334. 335. doset() 336. { 337. char buf[BUFSZ]; 338. #ifdef SORTING 339. extern char inv_order[]; 340. #endif 341. 342. pline("What options do you want to set? "); 343. getlin(buf); 344. if(!buf[0] || buf[0] == '\033') { 345. #ifdef DGK 346. (void) strcpy(buf,"OPTIONS="); 347. #else 348. (void) strcpy(buf,"HACKOPTIONS="); 349. (void) strcat(buf, flags.female ? "female," : "male,"); 350. if(flags.standout) (void) strcat(buf,"standout,"); 351. if(flags.nonull) (void) strcat(buf,"nonull,"); 352. if(flags.nonews) (void) strcat(buf,"nonews,"); 353. if(flags.notombstone) (void) strcat(buf,"notombstone,"); 354. if(flags.no_rest_on_space) (void) strcat(buf,"!rest_on_space,"); 355. #endif 356. #ifdef SORTING 357. if (flags.sortpack) (void) strcat(buf,"sortpack,"); 358. if (set_order){ 359. (void) strcat(buf, "packorder: "); 360. (void) strcat(buf, inv_order); 361. (void) strcat(buf, ","); 362. } 363. #endif 364. #ifdef SAFE_ATTACK 365. if (flags.confirm) (void) strcat(buf,"confirm,"); 366. #endif 367. #ifdef DGKMOD 368. if (flags.pickup) (void) strcat(buf,"pickup,"); 369. if (flags.silent) (void) strcat(buf,"silent,"); 370. #endif 371. #ifdef DGK 372. if (flags.rawio) (void) strcat(buf,"rawio,"); 373. if (flags.IBMBIOS) (void) strcat(buf,"IBMBIOS,"); 374. if (flags.DECRainbow) (void) strcat(buf,"DECRainbow,"); 375. #endif 376. if(flags.time) (void) strcat(buf,"time,"); 377. if(flags.end_top != 5 || flags.end_around != 4 || flags.end_own){ 378. (void) sprintf(eos(buf), "endgame: %u topscores/%u around me", 379. flags.end_top, flags.end_around); 380. if(flags.end_own) (void) strcat(buf, "/own scores"); 381. } else { 382. register char *eop = eos(buf); 383. if(*--eop == ',') *eop = 0; 384. } 385. pline(buf); 386. } else 387. parseoptions(buf, FALSE); 388. 389. return(0); 390. } 391. 392. #ifdef DGKMOD 393. dotogglepickup() { 394. flags.pickup = !flags.pickup; 395. pline("Pickup: %s.", flags.pickup ? "ON" : "OFF"); 396. return (0); 397. } 398. #endif 399. 400. nmcpy(dest, source, maxlen) 401. char *dest, *source; 402. int maxlen; 403. { 404. char *cs, *cd; 405. int count; 406. 407. cd = dest; 408. cs = source; 409. for(count = 1; count < maxlen; count++) { 410. if(*cs == ',') break; 411. *cd++ = *cs++; 412. } 413. *cd = 0; 414. } 415. 416. #ifdef SORTING 417. char *packorder = 418. # ifdef SPELLS 419. "\")[%?+/=!(*0"; 420. # else 421. "\")[%?/=!(*0"; 422. # endif 423. #endif 424. #define Page_line(x) if(page_line(x)) goto quit 425. 426. option_help() { 427. char buf[BUFSZ]; 428. 429. set_pager(0); 430. (void) sprintf(buf, " Net%s Options Help:", 431. #ifndef QUEST 432. "Hack"); 433. #else 434. "Quest"); 435. #endif 436. if(page_line("") || page_line(buf) || page_line("")) goto quit; 437. 438. #ifdef DGK 439. (void) sprintf(buf, "To set options use OPTIONS=<options> in %s", configfile); 440. Page_line(buf); 441. #else 442. Page_line("To set options use `HACKOPTIONS=\"<options>\"' in your environment"); 443. #endif 444. 445. Page_line("or give the command \"O\" followed by the line <options> while playing."); 446. Page_line("Here <options> is a list of options separated by commas."); 447. Page_line(""); 448. 449. #ifdef DGK 450. Page_line("Boolean options are confirm, pickup, rawio, silent, sortpack, time, IBMBIOS,"); 451. Page_line("and DECRainbow. These can be negated by prefixing them with '!' or \"no\"."); 452. #else 453. Page_line("Boolean options are rest_on_space, news, time, null tombstone, and (fe)male,"); 454. Page_line("These can be negated by prefixing them with '!' or \"no\"."); 455. #endif 456. Page_line(""); 457. 458. Page_line("The compound options are `name', (eg. name:Merlin-W,),"); 459. #ifdef DOGNAME 460. Page_line("`dogname', the name of your (first) dog (eg. dogname:Fang,),"); 461. #endif 462. 463. #ifdef SORTING 464. Page_line("`packorder'; the order that items should appear in your pack"); 465. (void)sprintf(buf, "(the default is: packorder:%s ), ", packorder); 466. Page_line(buf); 467. #endif 468. 469. #ifdef GRAPHICS 470. Page_line("`endgame', and `graphics'."); 471. #else 472. Page_line("and `endgame'."); 473. #endif 474. Page_line(""); 475. 476. Page_line("The `endgame' option is followed by a description of which parts of"); 477. Page_line("the scorelist you wish to see. You might for example say:"); 478. Page_line(""); 479. Page_line("\"endgame:own scores/5 top scores/4 around my score\"."); 480. 481. set_pager(1); 482. return; 483. quit: 484. set_pager(2); 485. return; 486. }