Source:NetHack 3.3.0/cmd.c

Below is the full text to cmd.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/cmd.c#line123 ]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

1.   /*	SCCS Id: @(#)cmd.c	3.3	1999/10/31	*/ 2.   /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3.    /* NetHack may be freely redistributed. See license for details. */ 4.     5.    #include "hack.h"  6.    #include "func_tab.h"  7.    /* #define DEBUG */	/* uncomment for debugging */ 8.    9.    /*  10.    * Some systems may have getchar return EOF for various reasons, and 11.   * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs. 12.   */  13.   #if defined(SYSV) || defined(DGUX) || defined(HPUX) 14.  #define NR_OF_EOFS	20 15.  #endif 16.   17.   #ifdef DEBUG 18.  /*  19.    * only one "wiz_debug_cmd" routine should be available (in whatever  20.    * module you are trying to debug) or things are going to get rather 21.   * hard to link :-)  22.    */  23.   extern void NDECL(wiz_debug_cmd);  24.   #endif  25.    26.   #ifdef DUMB	/* stuff commented out in extern.h, but needed here */  27.   extern int NDECL(doapply); /**/  28.   extern int NDECL(dorub); /**/  29.   extern int NDECL(dojump); /**/  30.   extern int NDECL(doextlist); /**/  31.   extern int NDECL(dodrop); /**/  32.   extern int NDECL(doddrop); /**/  33.   extern int NDECL(dodown); /**/  34.   extern int NDECL(doup); /**/  35.   extern int NDECL(donull); /**/  36.   extern int NDECL(dowipe); /**/  37.   extern int NDECL(do_mname); /**/  38.   extern int NDECL(ddocall); /**/  39.   extern int NDECL(dotakeoff); /**/  40.   extern int NDECL(doremring); /**/  41.   extern int NDECL(dowear); /**/  42.   extern int NDECL(doputon); /**/  43.   extern int NDECL(doddoremarm); /**/  44.   extern int NDECL(dokick); /**/  45.   extern int NDECL(dofire); /**/ 46.  extern int NDECL(dothrow); /**/ 47.  extern int NDECL(doeat); /**/ 48.  extern int NDECL(done2); /**/ 49.  extern int NDECL(doengrave); /**/ 50.  extern int NDECL(dopickup); /**/ 51.  extern int NDECL(ddoinv); /**/ 52.  extern int NDECL(dotypeinv); /**/ 53.  extern int NDECL(dolook); /**/ 54.  extern int NDECL(doprgold); /**/ 55.  extern int NDECL(doprwep); /**/ 56.  extern int NDECL(doprarm); /**/ 57.  extern int NDECL(doprring); /**/ 58.  extern int NDECL(dopramulet); /**/ 59.  extern int NDECL(doprtool); /**/ 60.  extern int NDECL(dosuspend); /**/ 61.  extern int NDECL(doforce); /**/ 62.  extern int NDECL(doopen); /**/ 63.  extern int NDECL(doclose); /**/ 64.  extern int NDECL(dosh); /**/ 65.  extern int NDECL(dodiscovered); /**/ 66.  extern int NDECL(doset); /**/ 67.  extern int NDECL(dotogglepickup); /**/ 68.  extern int NDECL(dowhatis); /**/ 69.  extern int NDECL(doquickwhatis); /**/ 70.  extern int NDECL(dowhatdoes); /**/ 71.  extern int NDECL(dohelp); /**/ 72.  extern int NDECL(dohistory); /**/ 73.  extern int NDECL(doloot); /**/ 74.  extern int NDECL(dodrink); /**/ 75.  extern int NDECL(dodip); /**/ 76.  extern int NDECL(dosacrifice); /**/ 77.  extern int NDECL(dopray); /**/ 78.  extern int NDECL(doturn); /**/ 79.  extern int NDECL(doredraw); /**/ 80.  extern int NDECL(doread); /**/ 81.  extern int NDECL(dosave); /**/ 82.  extern int NDECL(dosearch); /**/ 83.  extern int NDECL(doidtrap); /**/ 84.  extern int NDECL(dopay); /**/ 85.  extern int NDECL(dosit); /**/ 86.  extern int NDECL(dotalk); /**/ 87.  extern int NDECL(docast); /**/ 88.  extern int NDECL(dovspell); /**/ 89.  extern int NDECL(dotele); /**/ 90.  extern int NDECL(dountrap); /**/ 91.  extern int NDECL(doversion); /**/ 92.  extern int NDECL(doextversion); /**/ 93.  extern int NDECL(doswapweapon); /**/ 94.  extern int NDECL(dowield); /**/ 95.  extern int NDECL(dowieldquiver); /**/ 96.  extern int NDECL(dozap); /**/ 97.  extern int NDECL(doorganize); /**/ 98.  #endif /* DUMB */ 99.   100.  #ifdef OVL1 101. static int NDECL((*timed_occ_fn)); 102. #endif /* OVL1 */ 103.  104.  STATIC_PTR int NDECL(doprev_message); 105. STATIC_PTR int NDECL(timed_occupation); 106. STATIC_PTR int NDECL(doextcmd); 107. STATIC_PTR int NDECL(domonability); 108. # ifdef WIZARD 109. STATIC_PTR int NDECL(wiz_wish); 110. STATIC_PTR int NDECL(wiz_identify); 111. STATIC_PTR int NDECL(wiz_map); 112. STATIC_PTR int NDECL(wiz_genesis); 113. STATIC_PTR int NDECL(wiz_where); 114. STATIC_PTR int NDECL(wiz_detect); 115. STATIC_PTR int NDECL(wiz_level_tele); 116. STATIC_PTR int NDECL(wiz_show_seenv); 117. STATIC_PTR int NDECL(wiz_show_vision); 118. STATIC_PTR int NDECL(wiz_show_wmodes); 119. #ifdef __BORLANDC__ 120. extern void FDECL(show_borlandc_stats, (winid)); 121. #endif 122. STATIC_DCL void FDECL(count_obj, (struct obj *, long *, long *, BOOLEAN_P, BOOLEAN_P)); 123. STATIC_DCL void FDECL(obj_chain, (winid, const char *, struct obj *, long *, long *)); 124. STATIC_DCL void FDECL(mon_invent_chain, (winid, const char *, struct monst *, long *, long *)); 125. STATIC_DCL void FDECL(mon_chain, (winid, const char *, struct monst *, long *, long *)); 126. STATIC_DCL void FDECL(contained, (winid, const char *, long *, long *)); 127. STATIC_PTR int NDECL(wiz_show_stats); 128. # endif 129. STATIC_PTR int NDECL(enter_explore_mode); 130. STATIC_PTR int NDECL(wiz_attributes); 131. STATIC_PTR int NDECL(doconduct); /**/ 132.  133.  #ifdef OVLB 134. STATIC_DCL void FDECL(enlght_line, (const char *,const char *,const char *)); 135. #ifdef UNIX 136. static void NDECL(end_of_input); 137. #endif 138. #endif /* OVLB */ 139.  140.  STATIC_DCL char *NDECL(parse); 141.  142.  #ifdef OVL1 143.  144.  STATIC_PTR int 145. doprev_message 146. {  147.      return nh_doprev_message; 148. }  149.   150.  /* Count down by decrementing multi */ 151. STATIC_PTR int 152. timed_occupation 153. {  154.  	(*timed_occ_fn); 155. 	if (multi > 0) 156. 		multi--; 157. 	return multi > 0; 158. }  159.   160.  /* If you have moved since initially setting some occupations, they 161.  * now shouldn't be able to restart. 162.  *  163.   * The basic rule is that if you are carrying it, you can continue 164.  * since it is with you. If you are acting on something at a distance, 165.  * your orientation to it must have changed when you moved. 166.  *  167.   * The exception to this is taking off items, since they can be taken 168.  * off in a number of ways in the intervening time, screwing up ordering. 169.  *  170.   *	Currently:	Take off all armor. 171.  *			Picking Locks / Forcing Chests. 172.  *			Setting traps. 173.  */  174.  void 175. reset_occupations 176. {  177.  	reset_remarm; 178. 	reset_pick; 179. 	reset_trapset; 180. }  181.   182.  /* If a time is given, use it to timeout this function, otherwise the 183.  * function times out by its own means. 184.  */  185.  void 186. set_occupation(fn, txt, xtime) 187. int NDECL((*fn)); 188. const char *txt; 189. int xtime; 190. {  191.  	if (xtime) { 192. 		occupation = timed_occupation; 193. 		timed_occ_fn = fn; 194. 	} else 195. 		occupation = fn; 196. 	occtxt = txt; 197. 	occtime = 0; 198. 	return; 199. }  200.   201.  #ifdef REDO 202.  203.  static char NDECL(popch); 204.  205.  /* Provide a means to redo the last command. The flag `in_doagain' is set 206.  * to true while redoing the command. This flag is tested in commands that 207.  * require additional input (like `throw' which requires a thing and a  208.   * direction), and the input prompt is not shown. Also, while in_doagain is 209. * TRUE, no keystrokes can be saved into the saveq. 210.  */  211.  #define BSIZE 20 212. static char pushq[BSIZE], saveq[BSIZE]; 213. static NEARDATA int phead, ptail, shead, stail; 214.  215.  static char 216. popch { 217. 	/* If occupied, return '\0', letting tgetch know a character should 218. 	 * be read from the keyboard. If the character read is not the 219. 	 * ABORT character (as checked in pcmain.c), that character will be  220. * pushed back on the pushq. 221. 	 */  222.  	if (occupation) return '\0'; 223. 	if (in_doagain) return(char)((shead != stail) ? saveq[stail++] : '\0'); 224. 	else		return(char)((phead != ptail) ? pushq[ptail++] : '\0'); 225. }  226.   227.  char 228. pgetchar {		/* curtesy of aeb@cwi.nl */ 229. 	register int ch; 230.  231.  	if(!(ch = popch)) 232. 		ch = nhgetch; 233. 	return((char)ch); 234. }  235.   236.  /* A ch == 0 resets the pushq */ 237. void 238. pushch(ch) 239. char ch; 240. {  241.  	if (!ch) 242. 		phead = ptail = 0; 243. 	if (phead < BSIZE) 244. 		pushq[phead++] = ch; 245. 	return; 246. }  247.   248.  /* A ch == 0 resets the saveq. Only save keystrokes when not 249.  * replaying a previous command. 250.  */  251.  void 252. savech(ch) 253. char ch; 254. {  255.  	if (!in_doagain) { 256. 		if (!ch) 257. 			phead = ptail = shead = stail = 0; 258. 		else if (shead < BSIZE) 259. 			saveq[shead++] = ch; 260. 	}  261.  	return; 262. }  263.  #endif /* REDO */ 264.  265.  #endif /* OVL1 */ 266. #ifdef OVLB 267.  268.  STATIC_PTR int 269. doextcmd	/* here after # - now read a full-word command */ 270. {  271.  	int idx, retval; 272.  273.  	/* keep repeating until we don't run help or quit */ 274. 	do { 275. 	    idx = get_ext_cmd; 276. 	    if (idx < 0) return 0;	/* quit */ 277.  278.  	    retval = (*extcmdlist[idx].ef_funct); 279. 	} while (extcmdlist[idx].ef_funct == doextlist); 280.  281.  	return retval; 282. }  283.   284.  int 285. doextlist	/* here after #? - now list all full-word commands */ 286. {  287.  	register const struct ext_func_tab *efp; 288. 	char	 buf[BUFSZ]; 289. 	winid datawin; 290.  291.  	datawin = create_nhwindow(NHW_TEXT); 292. 	putstr(datawin, 0, ""); 293. 	putstr(datawin, 0, "            Extended Commands List"); 294. 	putstr(datawin, 0, ""); 295. 	putstr(datawin, 0, "    Press '#', then type:"); 296. 	putstr(datawin, 0, ""); 297.  298.  	for(efp = extcmdlist; efp->ef_txt; efp++) { 299. 		Sprintf(buf, "    %-14s  - %s.", efp->ef_txt, efp->ef_desc); 300. 		putstr(datawin, 0, buf); 301. 	}  302.  	display_nhwindow(datawin, FALSE); 303. 	destroy_nhwindow(datawin); 304. 	return 0; 305. }  306.   307.  #ifdef TTY_GRAPHICS 308. #define MAX_EXT_CMD 40		/* Change if we ever have > 40 ext cmds */ 309. /*  310.   * This is currently used only by the tty port and is  311. * controlled via runtime option 'extmenu' 312.  */  313.  int 314. extcmd_via_menu	/* here after # - now show pick-list of possible commands */ 315. {  316.      const struct ext_func_tab *efp; 317.     menu_item *pick_list = (menu_item *)0; 318.     winid win; 319.     anything any; 320.     const struct ext_func_tab *choices[MAX_EXT_CMD]; 321.     char buf[BUFSZ]; 322.     char cbuf[QBUFSZ], prompt[QBUFSZ], fmtstr[20]; 323.     int i, n, nchoices, acount; 324.     int ret,  biggest; 325.     int accelerator, prevaccelerator; 326.     int  matchlevel = 0; 327.  328.      ret = 0; 329.     cbuf[0] = '\0'; 330.     biggest = 0; 331.     while (!ret) { 332. 	    i = n = 0; 333. 	    accelerator = 0; 334. 	    any.a_void = 0; 335. 	    /* populate choices */ 336. 	    for(efp = extcmdlist; efp->ef_txt; efp++) { 337. 		if (!matchlevel || !strncmp(efp->ef_txt, cbuf, matchlevel)) { 338. 			choices[i++] = efp; 339. 			if ((int)strlen(efp->ef_desc) > biggest) { 340. 				biggest = strlen(efp->ef_desc); 341. 				Sprintf(fmtstr,"%%-%ds", biggest + 15); 342. 			}  343.  #ifdef DEBUG 344. 			if (i >= MAX_EXT_CMD - 2) { 345. 			    impossible("Exceeded %d extended commands in doextcmd menu",  346.  					MAX_EXT_CMD - 2); 347. 			    return 0; 348. 			}  349.  #endif 350. 		}  351.  	    }  352.  	    choices[i] = (struct ext_func_tab *)0; 353. 	    nchoices = i;  354. /* if we're down to one, we have our selection so get out of here */ 355. 	    if (nchoices == 1) { 356. 		for (i = 0; extcmdlist[i].ef_txt != (char *)0; i++) 357. 			if (!strncmpi(extcmdlist[i].ef_txt, cbuf, matchlevel)) { 358. 				ret = i;  359. break; 360. 			}  361.  		break; 362. 	    }  363.   364.  	    /* otherwise... */ 365.  	    win = create_nhwindow(NHW_MENU); 366. 	    start_menu(win); 367. 	    prevaccelerator = 0; 368. 	    acount = 0; 369. 	    for(i = 0; choices[i]; ++i) { 370. 		accelerator = choices[i]->ef_txt[matchlevel]; 371. 		if (accelerator != prevaccelerator || nchoices < (ROWNO - 3)) { 372. 		    if (acount) { 373.  			/* flush the extended commands for that letter already in buf */ 374. 			Sprintf(buf, fmtstr, prompt); 375. 			any.a_char = prevaccelerator; 376. 			add_menu(win, NO_GLYPH, &any, any.a_char, 0,  377.  					ATR_NONE, buf, FALSE); 378. 			acount = 0; 379. 		    }  380.  		}  381.  		prevaccelerator = accelerator; 382. 		if (!acount || nchoices < (ROWNO - 3)) { 383. 		    Sprintf(prompt, "%s [%s]", choices[i]->ef_txt,  384.  				choices[i]->ef_desc); 385. 		} else if (acount == 1) { 386. 		    Sprintf(prompt, "%s or %s", choices[i-1]->ef_txt,  387.  				choices[i]->ef_txt); 388. 		} else { 389. 		    Strcat(prompt," or "); 390. 		    Strcat(prompt, choices[i]->ef_txt); 391. 		}  392.  		++acount; 393. 	    }  394.  	    if (acount) { 395. 		/* flush buf */ 396. 		Sprintf(buf, fmtstr, prompt); 397. 		any.a_char = prevaccelerator; 398. 		add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE, buf, FALSE); 399. 	    }  400.  	    Sprintf(prompt, "Extended Command: %s", cbuf); 401. 	    end_menu(win, prompt); 402. 	    n = select_menu(win, PICK_ONE, &pick_list); 403. 	    destroy_nhwindow(win); 404. 	    if (n==1) { 405. 		if (matchlevel > (QBUFSZ - 2)) { 406. 			free((genericptr_t)pick_list); 407. #ifdef DEBUG 408. 			impossible("Too many characters (%d) entered in extcmd_via_menu",  409.  				matchlevel); 410. #endif 411. 			ret = -1; 412. 		} else { 413. 			cbuf[matchlevel++] = pick_list[0].item.a_char; 414. 			cbuf[matchlevel] = '\0'; 415. 			free((genericptr_t)pick_list); 416. 		}  417.  	    } else { 418. 		if (matchlevel) { 419. 			ret = 0; 420. 			matchlevel = 0; 421. 		} else 422. 			ret = -1; 423. 	    }  424.      }  425.      return ret; 426. }  427.  #endif 428.  429.  STATIC_PTR int 430. domonability 431. {  432.  	if (can_breathe(youmonst.data)) return dobreathe; 433. 	else if (attacktype(youmonst.data, AT_SPIT)) return dospit; 434. 	else if (youmonst.data->mlet == S_NYMPH) return doremove; 435. 	else if (youmonst.data->mlet == S_UMBER) return doconfuse; 436. 	else if (is_were(youmonst.data)) return dosummon; 437. 	else if (webmaker(youmonst.data)) return dospinweb; 438. 	else if (is_hider(youmonst.data)) return dohide; 439. 	else if (is_mind_flayer(youmonst.data)) return domindblast; 440. 	else if (u.umonnum == PM_GREMLIN) { 441. 	    if(IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 442. 		if (split_mon(&youmonst, (struct monst *)0)) 443. 		    dryup(u.ux, u.uy); 444. 	    } else pline("There is no fountain here."); 445. 	} else if (is_unicorn(youmonst.data)) { 446. 	    use_unicorn_horn((struct obj *)0); 447. 	    return 1; 448. 	} else if (youmonst.data->msound == MS_SHRIEK) { 449. 	    You("shriek."); 450. 	    if(u.uburied) 451. 		pline("Unfortunately sound does not carry well through rock."); 452. 	    else aggravate; 453. 	} else if (Upolyd) 454. 		pline("Any special ability you may have is purely reflexive."); 455. 	else You("don't have a special ability in your normal form!"); 456. 	return 0; 457. }  458.   459.  STATIC_PTR int 460. enter_explore_mode 461. {  462.  	if(!discover && !wizard) { 463. 		pline("Beware!  From explore mode there will be no return to normal game."); 464. 		if (yn("Do you want to enter explore mode?") == 'y') { 465. 			clear_nhwindow(WIN_MESSAGE); 466. 			You("are now in non-scoring explore mode."); 467. 			discover = TRUE; 468. 		}  469.  		else { 470. 			clear_nhwindow(WIN_MESSAGE); 471. 			pline("Resuming normal game."); 472. 		}  473.  	}  474.  	return 0; 475. }  476.   477.  #ifdef WIZARD 478. STATIC_PTR int 479. wiz_wish	/* Unlimited wishes for debug mode by Paul Polderman */ 480. {  481.  	if (wizard) { 482. 	    boolean save_verbose = flags.verbose; 483.  484.  	    flags.verbose = FALSE; 485. 	    makewish; 486. 	    flags.verbose = save_verbose; 487. 	    (void) encumber_msg; 488. 	} else 489. 	    pline("Unavailable command '^W'."); 490. 	return 0; 491. }  492.   493.  STATIC_PTR int 494. wiz_identify 495. {  496.  	if (wizard)	identify_pack(0); 497. 	else		pline("Unavailable command '^I'."); 498. 	return 0; 499. }  500.   501.  /* reveal the level map and any traps on it */ 502. STATIC_PTR int 503. wiz_map 504. {  505.  	if (wizard) { 506. 	    struct trap *t; 507.  508.  	    for (t = ftrap; t != 0; t = t->ntrap) { 509. 		t->tseen = 1; 510. 		map_trap(t, TRUE); 511. 	    }  512.  	    do_mapping; 513. 	} else 514. 	    pline("Unavailable command '^F'."); 515. 	return 0; 516. }  517.   518.  STATIC_PTR int 519. wiz_genesis 520. {  521.  	if (wizard)	(void) create_particular; 522. 	else		pline("Unavailable command '^G'."); 523. 	return 0; 524. }  525.   526.  STATIC_PTR int 527. wiz_where 528. {  529.  	if (wizard) print_dungeon; 530. 	else	    pline("Unavailable command '^O'."); 531. 	return 0; 532. }  533.   534.  STATIC_PTR int 535. wiz_detect 536. {  537.  	if(wizard)  (void) findit; 538. 	else	    pline("Unavailable command '^E'."); 539. 	return 0; 540. }  541.   542.  STATIC_PTR int 543. wiz_level_tele 544. {  545.  	if (wizard)	level_tele; 546. 	else		pline("Unavailable command '^V'."); 547. 	return 0; 548. }  549.   550.  STATIC_PTR int 551. wiz_show_seenv 552. {  553.  	winid win; 554. 	int x, y, v, startx, stopx, curx; 555. 	char row[COLNO+1]; 556.  557.  	win = create_nhwindow(NHW_TEXT); 558. 	/*  559.  	 * Each seenv description takes up 2 characters, so center 560. 	 * the seenv display around the hero. 561. 	 */  562.  	startx = max(1, u.ux-(COLNO/4)); 563. 	stopx = min(startx+(COLNO/2), COLNO); 564. 	/* can't have a line exactly 80 chars long */ 565. 	if (stopx - startx == COLNO/2) startx++; 566.  567.  	for (y = 0; y < ROWNO; y++) { 568. 	    for (x = startx, curx = 0; x < stopx; x++, curx += 2) { 569. 		if (x == u.ux && y == u.uy) { 570. 		    row[curx] = row[curx+1] = '@'; 571. 		} else { 572. 		    v = levl[x][y].seenv & 0xff; 573. 		    if (v == 0) 574. 			row[curx] = row[curx+1] = ' '; 575. 		    else 576. 			Sprintf(&row[curx], "%02x", v); 577. 		}  578.  	    }  579.  	    /* remove trailing spaces */ 580. 	    for (x = curx-1; x >= 0; x--) 581. 		if (row[x] != ' ') break; 582. 	    row[x+1] = '\0'; 583.  584.  	    putstr(win, 0, row); 585. 	}  586.  	display_nhwindow(win, TRUE); 587. 	destroy_nhwindow(win); 588. 	return 0; 589. }  590.   591.  STATIC_PTR int 592. wiz_show_vision 593. {  594.  	winid win; 595. 	int x, y, v;  596. char row[COLNO+1]; 597.  598.  	win = create_nhwindow(NHW_TEXT); 599. 	Sprintf(row, "Flags: 0x%x could see, 0x%x in sight, 0x%x temp lit",  600.  		COULD_SEE, IN_SIGHT, TEMP_LIT); 601. 	putstr(win, 0, row); 602. 	putstr(win, 0, ""); 603. 	for (y = 0; y < ROWNO; y++) { 604. 	    for (x = 1; x < COLNO; x++) { 605. 		if (x == u.ux && y == u.uy) 606. 		    row[x] = '@'; 607. 		else { 608. 		    v = viz_array[y][x]; /* data access should be hidden */ 609. 		    if (v == 0) 610. 			row[x] = ' '; 611. 		    else 612. 			row[x] = '0' + viz_array[y][x]; 613. 		}  614.  	    }  615.  	    /* remove trailing spaces */ 616. 	    for (x = COLNO-1; x >= 1; x--) 617. 		if (row[x] != ' ') break; 618. 	    row[x+1] = '\0'; 619.  620.  	    putstr(win, 0, &row[1]); 621. 	}  622.  	display_nhwindow(win, TRUE); 623. 	destroy_nhwindow(win); 624. 	return 0; 625. }  626.   627.  STATIC_PTR int 628. wiz_show_wmodes 629. {  630.  	winid win; 631. 	int x,y; 632. 	char row[COLNO+1]; 633. 	struct rm *lev; 634.  635.  	win = create_nhwindow(NHW_TEXT); 636. 	for (y = 0; y < ROWNO; y++) { 637. 	    for (x = 0; x < COLNO; x++) { 638. 		lev = &levl[x][y]; 639. 		if (x == u.ux && y == u.uy) 640. 		    row[x] = '@'; 641. 		if (IS_WALL(lev->typ) || lev->typ == SDOOR) 642. 		    row[x] = '0' + (lev->wall_info & WM_MASK); 643. 		else if (lev->typ == CORR) 644. 		    row[x] = '#'; 645. 		else if (IS_ROOM(lev->typ) || IS_DOOR(lev->typ)) 646. 		    row[x] = '.'; 647. 		else 648. 		    row[x] = 'x'; 649. 	    }  650.  	    row[COLNO] = '\0'; 651. 	    putstr(win, 0, row); 652. 	}  653.  	display_nhwindow(win, TRUE); 654. 	destroy_nhwindow(win); 655. 	return 0; 656. }  657.   658.  #endif /* WIZARD */ 659.  660.   661.  /* -enlightenment and conduct- */ 662. static winid en_win; 663. static const char 664. 	*You_ = "You ", 665. 	*are  = "are ",  *were  = "were ", 666. 	*have = "have ", *had   = "had ", 667. 	*can  = "can ",  *could = "could "; 668. static const char 669. 	*have_been  = "have been ", 670. 	*have_never = "have never ", *never = "never "; 671.  672.  #define enl_msg(prefix,present,past,suffix) \ 673. 			enlght_line(prefix, final ? past : present, suffix) 674. #define you_are(attr)	enl_msg(You_,are,were,attr) 675. #define you_have(attr)	enl_msg(You_,have,had,attr) 676. #define you_can(attr)	enl_msg(You_,can,could,attr) 677. #define you_have_been(goodthing) enl_msg(You_,have_been,were,goodthing) 678. #define you_have_never(badthing) enl_msg(You_,have_never,never,badthing) 679. #define you_have_X(something)	enl_msg(You_,have,(const char *)"",something) 680.  681.  static void 682. enlght_line(start, middle, end) 683. const char *start, *middle, *end; 684. {  685.  	char buf[BUFSZ]; 686.  687.  	Sprintf(buf, "%s%s%s.", start, middle, end); 688. 	putstr(en_win, 0, buf); 689. }  690.   691.  void 692. enlightenment(final) 693. int final;	/* 0 => still in progress; 1 => over, survived; 2 => dead */ 694. {  695.  	int ltmp; 696. 	char buf[BUFSZ]; 697.  698.  	en_win = create_nhwindow(NHW_MENU); 699. 	putstr(en_win, 0, final ? "Final Attributes:" : "Current Attributes:"); 700. 	putstr(en_win, 0, ""); 701.  702.  #ifdef ELBERETH 703. 	if (u.uevent.uhand_of_elbereth) { 704. 	    static const char *hofe_titles[3] = { 705. 				"the Hand of Elbereth", 706. 				"the Envoy of Balance", 707. 				"the Glory of Arioch" 708. 	    };  709.  	    you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1]); 710. 	}  711.  #endif 712.  713.  	/* note: piousness 20 matches MIN_QUEST_ALIGN (quest.h) */ 714. 	if (u.ualign.record >= 20)	you_are("piously aligned"); 715. 	else if (u.ualign.record > 13)	you_are("devoutly aligned"); 716. 	else if (u.ualign.record > 8)	you_are("fervently aligned"); 717. 	else if (u.ualign.record > 3)	you_are("stridently aligned"); 718. 	else if (u.ualign.record == 3)	you_are("aligned"); 719. 	else if (u.ualign.record > 0)	you_are("haltingly aligned"); 720. 	else if (u.ualign.record == 0)	you_are("nominally aligned"); 721. 	else if (u.ualign.record >= -3)	you_have("strayed"); 722. 	else if (u.ualign.record >= -8)	you_have("sinned"); 723. 	else you_have("transgressed"); 724. #ifdef WIZARD 725. 	if (wizard) { 726. 		Sprintf(buf, " %d", u.ualign.record); 727. 		enl_msg("Your alignment ", "is", "was", buf); 728. 	}  729.  #endif 730.  731.  	/*** Resistances to troubles ***/ 732. 	if (Fire_resistance) you_are("fire resistant"); 733. 	if (Cold_resistance) you_are("cold resistant"); 734. 	if (Sleep_resistance) you_are("sleep resistant"); 735. 	if (Disint_resistance) you_are("disintegration-resistant"); 736. 	if (Shock_resistance) you_are("shock resistant"); 737. 	if (Poison_resistance) you_are("poison resistant"); 738. 	if (Drain_resistance) you_are("level-drain resistant"); 739. 	if (Sick_resistance) you_are("immune to sickness"); 740. 	if (Antimagic) you_are("magic-protected"); 741. 	if (Acid_resistance) you_are("acid resistant"); 742. 	if (Stone_resistance) 743. 		you_are("petrification resistant"); 744. 	if (Invulnerable) you_are("invulnerable"); 745.  746.  	/*** Troubles ***/ 747. 	if (Halluc_resistance) 748. 		enl_msg("You resist", "", "ed", " hallucinations"); 749. 	if (final) { 750. 		if (Hallucination) you_are("hallucinating"); 751. 		if (Stunned) you_are("stunned"); 752. 		if (Confusion) you_are("confused"); 753. 		if (Blinded) you_are("blinded"); 754. 		if (Sick) { 755. 			if (u.usick_type & SICK_VOMITABLE) 756. 				you_are("sick from food poisoning"); 757. 			if (u.usick_type & SICK_NONVOMITABLE) 758. 				you_are("sick from illness"); 759. 		}  760.  	}  761.  	if (Stoned) you_are("turning to stone"); 762. 	if (Strangled) you_are((u.uburied) ? "buried" : "being strangled"); 763. 	if (Glib) { 764. 		Sprintf(buf, "slippery %s", makeplural(body_part(FINGER))); 765. 		you_have(buf); 766. 	}  767.  	if (Slimed) you_are("turning into slime"); 768. 	if (Fumbling) enl_msg("You fumble", "", "d", ""); 769. 	if (Wounded_legs) { 770. 		Sprintf(buf, "wounded %s", makeplural(body_part(LEG))); 771. 		you_have(buf); 772. 	}  773.  	if (Hunger) enl_msg("You hunger", "", "ed", " rapidly"); 774.  775.  	/*** Vision and senses ***/ 776. 	if (See_invisible) enl_msg(You_, "see", "saw", " invisible"); 777. 	if (Blind_telepat) you_are("telepathic"); 778. 	if (Warning) you_are("warned"); 779. 	if (Undead_warning) you_are("warned of undead"); 780. 	if (Searching) you_have("automatic searching"); 781. 	if (Clairvoyant) you_are("clairvoyant"); 782. 	if (Infravision) you_have("infravision"); 783. 	if (Detect_monsters) you_are("sensing the presence of monsters"); 784.  785.  	/*** Appearance and behavior ***/ 786. 	if (Adornment) you_are("adorned"); 787. 	if (Invisible) you_are("invisible"); 788. 	else if (Invis) you_are("invisible to others"); 789. 	/* ordinarily "visible" is redundant; this is a special case for 790. 	   the situation when invisibility would be an expected attribute */ 791. 	else if ((HInvis || EInvis || pm_invisible(youmonst.data)) && BInvis) 792. 	    you_are("visible"); 793. 	if (Displaced) you_are("displaced"); 794. 	if (Stealth) you_are("stealthy"); 795. 	if (Aggravate_monster) enl_msg("You aggravate", "", "d", " monsters"); 796. 	if (Conflict) enl_msg("You cause", "", "d", " conflict"); 797.  798.  	/*** Transportation ***/ 799. 	if (Jumping) you_can("jump"); 800. 	if (Teleportation) you_can("teleport"); 801. 	if (Teleport_control) you_have("teleport control"); 802. 	if (Lev_at_will) you_are("levitating, at will"); 803. 	else if (Levitation) you_are("levitating");	/* without control */ 804. 	else if (Flying) you_can("fly"); 805. 	if (Wwalking) you_can("walk on water"); 806. 	if (Swimming) you_can("swim"); 807. 	if (Breathless) you_can("survive without air"); 808. 	else if (Amphibious) you_can("breathe water"); 809. 	if (Passes_walls) you_can("walk through walls"); 810.  811.  	/*** Physical attributes ***/ 812. 	if (Slow_digestion) you_have("slower digestion"); 813. 	if (Regeneration) enl_msg("You regenerate", "", "d", ""); 814. 	if (Protection) you_are("protected"); 815. 	if (Protection_from_shape_changers) 816. 		you_are("protected from shape changers"); 817. 	if (Polymorph) you_are("polymorphing"); 818. 	if (Polymorph_control) you_have("polymorph control"); 819. 	if (u.ulycn >= LOW_PM) { 820. 		Strcpy(buf, an(mons[u.ulycn].mname)); 821. 		you_are(buf); 822. 	}  823.  	if (Upolyd) { 824. 	    if (u.ulycn >= LOW_PM) Strcpy(buf, "in beast form"); 825. 	    else Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname)); 826. #ifdef WIZARD 827. 	    if (wizard) Sprintf(eos(buf), " (%d)", u.mtimedone); 828. #endif 829. 	    you_are(buf); 830. 	}  831.  	if (Unchanging) you_can("not change from your current form"); 832. 	if (Fast) you_are(Very_fast ? "very fast" : "fast"); 833. 	if (Reflecting) you_have("reflection"); 834. 	if (Free_action) you_have("free action"); 835. 	if (Fixed_abil) you_have("fixed abilities"); 836. 	if (Lifesaved) 837. 		enl_msg("Your life ", "will be", "would have been", " saved"); 838.  839.  	/*** Miscellany ***/ 840. 	if (Luck) { 841. 	    ltmp = abs((int)Luck); 842. 	    Sprintf(buf, "%s%slucky",  843.  		    ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "",  844.  		    Luck < 0 ? "un" : ""); 845. #ifdef WIZARD 846. 	    if (wizard) Sprintf(eos(buf), " (%d)", Luck); 847. #endif 848. 	    you_are(buf); 849. 	}  850.  #ifdef WIZARD 851. 	 else if (wizard) enl_msg("Your luck ", "is", "was", " zero"); 852. #endif 853. 	if (u.moreluck > 0) you_have("extra luck"); 854. 	else if (u.moreluck < 0) you_have("reduced luck"); 855. 	if (carrying(LUCKSTONE) || stone_luck(TRUE)) { 856. 	    ltmp = stone_luck(FALSE); 857. 	    if (ltmp <= 0) 858. 		enl_msg("Bad luck ", "does", "did", " not time out for you"); 859. 	    if (ltmp >= 0) 860. 		enl_msg("Good luck ", "does", "did", " not time out for you"); 861. 	}  862.   863.  	if (u.ugangr) { 864. 	    Sprintf(buf, " %sangry with you",  865.  		    u.ugangr > 6 ? "extremely " : u.ugangr > 3 ? "very " : ""); 866. #ifdef WIZARD 867. 	    if (wizard) Sprintf(eos(buf), " (%d)", u.ugangr); 868. #endif 869. 	    enl_msg(u_gname, " is", " was", buf); 870. 	} else 871. 	    /*  872.  	     * We need to suppress this when the game is over, because death 873. 	     * can change the value calculated by can_pray, potentially 874. 	     * resulting in a false claim that you could have prayed safely. 875. 	     */  876.  	  if (!final) { 877. #if 0 878. 	    /* "can [not] safely pray" vs "could [not] have safely prayed" */ 879. 	    Sprintf(buf, "%s%ssafely pray%s", can_pray(FALSE) ? "" : "not ",  880.  		    final ? "have " : "", final ? "ed" : ""); 881. #else 882. 	    Sprintf(buf, "%ssafely pray", can_pray(FALSE) ? "" : "not "); 883. #endif 884. #ifdef WIZARD 885. 	    if (wizard) Sprintf(eos(buf), " (%d)", u.ublesscnt); 886. #endif 887. 	    you_can(buf); 888. 	}  889.   890.      {  891.  	const char *p; 892.  893.  	buf[0] = '\0'; 894. 	if (final < 2) {    /* still in progress, or quit/escaped/ascended */ 895. 	    p = "survived after being killed "; 896. 	    switch (u.umortality) { 897. 	    case 0:  p = !final ? (char *)0 : "survived"; break; 898. 	    case 1:  Strcpy(buf, "once");  break; 899. 	    case 2:  Strcpy(buf, "twice");  break; 900. 	    case 3:  Strcpy(buf, "thrice");  break; 901. 	    default: Sprintf(buf, "%d times", u.umortality); 902. 		     break; 903. 	    }  904.  	} else {		/* game ended in character's death */ 905. 	    p = "are dead"; 906. 	    switch (u.umortality) { 907. 	    case 0:  impossible("dead without dying?"); 908. 	    case 1:  break;			/* just "are dead" */ 909. 	    default: Sprintf(buf, " (%d%s time!)", u.umortality,  910.  			     ordin(u.umortality)); 911. 		     break; 912. 	    }  913.  	}  914.  	if (p) enl_msg(You_, "have been killed ", p, buf); 915.     }  916.   917.  	display_nhwindow(en_win, TRUE); 918. 	destroy_nhwindow(en_win); 919. 	return; 920. }  921.   922.  STATIC_PTR int 923. wiz_attributes 924. {  925.  	if (wizard || discover) 926. 		enlightenment(0); 927. 	else 928. 		pline("Unavailable command '^X'."); 929. 	return 0; 930. }  931.   932.  /* KMH, #conduct 933.  * (shares enlightenment's tense handling) 934.  */  935.  STATIC_PTR int 936. doconduct 937. {  938.  	show_conduct(0); 939. 	return 0; 940. }  941.   942.  void 943. show_conduct(final) 944. int final; 945. {  946.  	char buf[BUFSZ]; 947. 	int ngenocided; 948.  949.  	/* Create the conduct window */ 950. 	en_win = create_nhwindow(NHW_MENU); 951. 	putstr(en_win, 0, "Voluntary challenges:"); 952. 	putstr(en_win, 0, ""); 953.  954.  	if (!u.uconduct.food) 955. 	    enl_msg(You_, "have gone", "went", " without food"); 956. 	    /* But beverages are okay */ 957. 	else if (!u.uconduct.flesh) 958. 	    you_have_been("a strict vegan"); 959. 	else if (!u.uconduct.meat) 960. 	    you_have_been("vegetarian"); 961.  962.  	if (!u.uconduct.gnostic) 963. 	    you_have_been("an atheist"); 964.  965.  	if (!u.uconduct.weaphit) 966. 	    you_have_never("hit with a wielded weapon"); 967. #ifdef WIZARD 968. 	else if (wizard) { 969. 	    Sprintf(buf, "used a wielded weapon %ld time%s",  970.  		    u.uconduct.weaphit, plur(u.uconduct.weaphit)); 971. 	    you_have_X(buf); 972. 	}  973.  #endif 974. 	if (!u.uconduct.killer) 975. 	    you_have_been("a pacifist"); 976.  977.  	if (!u.uconduct.literate) 978. 	    you_have_been("illiterate"); 979. #ifdef WIZARD 980. 	else if (wizard) { 981. 	    Sprintf(buf, "read items or engraved %ld time%s",  982.  		    u.uconduct.literate, plur(u.uconduct.literate)); 983. 	    you_have_X(buf); 984. 	}  985.  #endif 986.  987.  	ngenocided = num_genocides; 988. 	if (ngenocided == 0) { 989. 	    you_have_never("genocided any monsters"); 990. 	} else { 991. 	    Sprintf(buf, "genocided %d type%s of monster%s",  992.  		    ngenocided, plur(ngenocided), plur(ngenocided)); 993. 	    you_have_X(buf); 994. 	}  995.   996.  	if (!u.uconduct.polypiles) 997. 	    you_have_never("polymorphed an object"); 998. #ifdef WIZARD 999. 	else if (wizard) { 1000. 	   Sprintf(buf, "polymorphed %ld item%s",  1001. 		    u.uconduct.polypiles, plur(u.uconduct.polypiles)); 1002. 	   you_have_X(buf); 1003. 	} 1004. #endif 1005. 1006. 	if (!u.uconduct.polyselfs) 1007. 	   you_have_never("changed form"); 1008. #ifdef WIZARD 1009. 	else if (wizard) { 1010. 	   Sprintf(buf, "changed form %ld time%s",  1011. 		    u.uconduct.polyselfs, plur(u.uconduct.polyselfs)); 1012. 	   you_have_X(buf); 1013. 	} 1014. #endif 1015. 1016. 	if (!u.uconduct.wishes) 1017. 	   you_have_X("used no wishes"); 1018. 	else { 1019. 	   Sprintf(buf, "used %ld wish%s",  1020. 		    u.uconduct.wishes, (u.uconduct.wishes > 1L) ? "es" : ""); 1021. 	   you_have_X(buf); 1022. 1023. 	    if (!u.uconduct.wisharti) 1024. 		enl_msg(You_, "have not wished", "did not wish", 1025. 			" for any artifacts"); 1026. 	} 1027.  1028. 	/* Pop up the window and wait for a key */ 1029. 	display_nhwindow(en_win, TRUE); 1030. 	destroy_nhwindow(en_win); 1031. } 1032.  1033. #endif /* OVLB */ 1034. #ifdef OVL1 1035. 1036. #ifndef M  1037. # ifndef NHSTDC 1038. # define M(c)		(0x80 | (c)) 1039. # else 1040. # define M(c)		((c) - 128) 1041. # endif /* NHSTDC */ 1042. #endif 1043. #ifndef C 1044. #define C(c)		(0x1f & (c)) 1045. #endif 1046. 1047. static const struct func_tab cmdlist[] = { 1048. 	{C('d'), FALSE, dokick}, /* "D" is for door!...? Msg is in dokick.c */ 1049. #ifdef WIZARD 1050. 	{C('e'), TRUE, wiz_detect}, 1051. 	{C('f'), TRUE, wiz_map}, 1052. 	{C('g'), TRUE, wiz_genesis}, 1053. 	{C('i'), TRUE, wiz_identify}, 1054. #endif 1055. 	{C('l'), TRUE, doredraw}, /* if number_pad is set */ 1056. #ifdef WIZARD 1057. 	{C('o'), TRUE, wiz_where}, 1058. #endif 1059. 	{C('p'), TRUE, doprev_message}, 1060. 	{C('r'), TRUE, doredraw}, 1061. 	{C('t'), TRUE, dotele}, 1062. #ifdef WIZARD 1063. 	{C('v'), TRUE, wiz_level_tele}, 1064. 	{C('w'), TRUE, wiz_wish}, 1065. #endif 1066. 	{C('x'), TRUE, wiz_attributes}, 1067. #ifdef SUSPEND 1068. 	{C('z'), TRUE, dosuspend}, 1069. #endif 1070. 	{'a', FALSE, doapply}, 1071. 	{'A', FALSE, doddoremarm}, 1072. 	{M('a'), TRUE, doorganize}, 1073. /*	'b', 'B' : go sw */ 1074. 	{'c', FALSE, doclose}, 1075. 	{'C', TRUE, do_mname}, 1076. 	{M('c'), TRUE, dotalk}, 1077. 	{'d', FALSE, dodrop}, 1078. 	{'D', FALSE, doddrop}, 1079. 	{M('d'), FALSE, dodip}, 1080. 	{'e', FALSE, doeat}, 1081. 	{'E', FALSE, doengrave}, 1082. 	{M('e'), TRUE, enhance_weapon_skill}, 1083. 	{'f', FALSE, dofire}, 1084. /*	'F' : fight (one time) */ 1085. 	{M('f'), FALSE, doforce}, 1086. /*	'g', 'G' : multiple go */ 1087. /*	'h', 'H' : go west */ 1088. 	{'h', TRUE, dohelp}, /* if number_pad is set */ 1089. 	{'i', TRUE, ddoinv}, 1090. 	{'I', TRUE, dotypeinv},		/* Robert Viduya */ 1091. 	{M('i'), TRUE, doinvoke}, 1092. /*	'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */ 1093. 	{'j', FALSE, dojump}, /* if number_pad is on */ 1094. 	{M('j'), FALSE, dojump}, 1095. 	{'k', FALSE, dokick}, /* if number_pad is on */ 1096. 	{'l', FALSE, doloot}, /* if number_pad is on */ 1097. 	{M('l'), FALSE, doloot}, 1098. /*	'n' prefixes a count if number_pad is on */ 1099. 	{M('m'), TRUE, domonability}, 1100. 	{'N', TRUE, ddocall}, /* if number_pad is on */ 1101. 	{M('n'), TRUE, ddocall}, 1102. 	{M('N'), TRUE, ddocall}, 1103. 	{'o', FALSE, doopen}, 1104. 	{'O', TRUE, doset}, 1105. 	{M('o'), FALSE, dosacrifice}, 1106. 	{'p', FALSE, dopay}, 1107. 	{'P', FALSE, doputon}, 1108. 	{M('p'), TRUE, dopray}, 1109. 	{'q', FALSE, dodrink}, 1110. 	{'Q', FALSE, dowieldquiver}, 1111. 	{M('q'), TRUE, done2}, 1112. 	{'r', FALSE, doread}, 1113. 	{'R', FALSE, doremring}, 1114. 	{M('r'), FALSE, dorub}, 1115. 	{'s', TRUE, dosearch, "searching"}, 1116. 	{'S', TRUE, dosave}, 1117. 	{M('s'), FALSE, dosit}, 1118. 	{'t', FALSE, dothrow}, 1119. 	{'T', FALSE, dotakeoff}, 1120. 	{M('t'), TRUE, doturn}, 1121. /*	'u', 'U' : go ne */ 1122. 	{'u', FALSE, dountrap}, /* if number_pad is on */ 1123. 	{M('u'), FALSE, dountrap}, 1124. 	{'v', TRUE, doversion}, 1125. 	{'V', TRUE, dohistory}, 1126. 	{M('v'), TRUE, doextversion}, 1127. 	{'w', FALSE, dowield}, 1128. 	{'W', FALSE, dowear}, 1129. 	{M('w'), FALSE, dowipe}, 1130. 	{'x', FALSE, doswapweapon}, 1131. 	{'X', TRUE, enter_explore_mode}, 1132. /*	'y', 'Y' : go nw */ 1133. 	{'z', FALSE, dozap}, 1134. 	{'Z', TRUE, docast}, 1135. 	{'<', FALSE, doup}, 1136. 	{'>', FALSE, dodown}, 1137. 	{'/', TRUE, dowhatis}, 1138. 	{'&', TRUE, dowhatdoes}, 1139. 	{'?', TRUE, dohelp}, 1140. 	{M('?'), TRUE, doextlist}, 1141. #ifdef SHELL 1142. 	{'!', TRUE, dosh}, 1143. #endif 1144. 	{'.', TRUE, donull, "waiting"}, 1145. 	{' ', TRUE, donull, "waiting"}, 1146. 	{',', FALSE, dopickup}, 1147. 	{':', TRUE, dolook}, 1148. 	{';', TRUE, doquickwhatis}, 1149. 	{'^', TRUE, doidtrap}, 1150. 	{'\\', TRUE, dodiscovered},		/* Robert Viduya */ 1151. 	{'@', TRUE, dotogglepickup}, 1152. 	{WEAPON_SYM, TRUE, doprwep}, 1153. 	{ARMOR_SYM, TRUE, doprarm}, 1154. 	{RING_SYM, TRUE, doprring}, 1155. 	{AMULET_SYM, TRUE, dopramulet}, 1156. 	{TOOL_SYM, TRUE, doprtool}, 1157. 	{'*', TRUE, doprinuse},	/* inventory of all equipment in use */ 1158. 	{GOLD_SYM, TRUE, doprgold}, 1159. 	{SPBOOK_SYM, TRUE, dovspell},			/* Mike Stephenson */ 1160. 	{'#', TRUE, doextcmd}, 1161. 	{0,0,0,0} 1162. };  1163.  1164. struct ext_func_tab extcmdlist[] = { 1165. 	{"adjust", "adjust inventory letters", doorganize, TRUE}, 1166. 	{"chat", "talk to someone", dotalk, TRUE},	/* converse? */ 1167. 	{"conduct", "list which challenges you have adhered to", doconduct, TRUE}, 1168. 	{"dip", "dip an object into something", dodip, FALSE}, 1169. 	{"enhance", "advance or check weapons skills", enhance_weapon_skill, 1170. 							TRUE}, 1171. 	{"force", "force a lock", doforce, FALSE}, 1172. 	{"invoke", "invoke an object's powers", doinvoke, TRUE}, 1173. 	{"jump", "jump to a location", dojump, FALSE}, 1174. 	{"loot", "loot a box on the floor", doloot, FALSE}, 1175. 	{"monster", "use a monster's special ability", domonability, TRUE}, 1176. 	{"name", "name an item or type of object", ddocall, TRUE}, 1177. 	{"offer", "offer a sacrifice to the gods", dosacrifice, FALSE}, 1178. 	{"pray", "pray to the gods for help", dopray, TRUE}, 1179. 	{"quit", "exit without saving current game", done2, TRUE}, 1180. #ifdef STEED 1181. 	{"ride", "ride (or stop riding) a monster", doride, FALSE}, 1182. #endif 1183. 	{"rub", "rub a lamp", dorub, FALSE}, 1184. 	{"sit", "sit down", dosit, FALSE}, 1185. 	{"turn", "turn undead", doturn, TRUE}, 1186. 	{"twoweapon", "toggle two-weapon combat", dotwoweapon, FALSE}, 1187. 	{"untrap", "untrap something", dountrap, FALSE}, 1188. 	{"version", "list compile time options for this version of NetHack", 1189. 		doextversion, TRUE}, 1190. 	{"wipe", "wipe off your face", dowipe, FALSE}, 1191. 	{"?", "get this list of extended commands", doextlist, TRUE}, 1192. #if defined(WIZARD) 1193. 	/* 1194. 	 * There must be a blank entry here for every entry in the table 1195. 	 * below. 1196. 	 */ 1197. 	{(char *)0, (char *)0, donull, TRUE}, 1198. 	{(char *)0, (char *)0, donull, TRUE}, 1199. 	{(char *)0, (char *)0, donull, TRUE}, 1200. 	{(char *)0, (char *)0, donull, TRUE}, 1201. 	{(char *)0, (char *)0, donull, TRUE}, 1202. #ifdef DEBUG 1203. 	{(char *)0, (char *)0, donull, TRUE}, 1204. #endif 1205. 	{(char *)0, (char *)0, donull, TRUE}, 1206. #endif 1207. 	{(char *)0, (char *)0, donull, TRUE}	/* sentinel */ 1208. }; 1209.  1210. #if defined(WIZARD) 1211. static const struct ext_func_tab debug_extcmdlist[] = { 1212. 	{"light sources", "show mobile light sources", wiz_light_sources, TRUE}, 1213. 	{"seenv", "show seen vectors", wiz_show_seenv, TRUE}, 1214. 	{"stats", "show memory statistics", wiz_show_stats, TRUE}, 1215. 	{"timeout", "look at timeout queue", wiz_timeout_queue, TRUE}, 1216. 	{"vision", "show vision array", wiz_show_vision, TRUE}, 1217. #ifdef DEBUG 1218. 	{"wizdebug", "wizard debug command", wiz_debug_cmd, TRUE}, 1219. #endif 1220. 	{"wmode", "show wall modes", wiz_show_wmodes, TRUE}, 1221. 	{(char *)0, (char *)0, donull, TRUE} 1222. }; 1223.  1224. /*  1225.  * Insert debug commands into the extended command list. This function 1226. * assumes that the last entry will be the help entry. 1227. *  1228.  * You must add entries in ext_func_tab every time you add one to the 1229. * debug_extcmdlist. 1230. */  1231. void 1232. add_debug_extended_commands 1233. { 1234. 	int i, j, k, n;  1235. 1236. 	/* count the # of help entries */ 1237. 	for (n = 0; extcmdlist[n].ef_txt[0] != '?'; n++) 1238. 	   ;  1239.  1240. 	for (i = 0; debug_extcmdlist[i].ef_txt; i++) { 1241. 	   for (j = 0; j < n; j++) 1242. 		if (strcmp(debug_extcmdlist[i].ef_txt, extcmdlist[j].ef_txt) < 0) break; 1243. 1244. 	    /* insert i'th debug entry into extcmdlist[j], pushing down  */ 1245. 	   for (k = n; k >= j; --k) 1246. 		extcmdlist[k+1] = extcmdlist[k]; 1247. 	   extcmdlist[j] = debug_extcmdlist[i]; 1248. 	   n++;	/* now an extra entry */ 1249. 	} 1250. }  1251.  1252.  1253. static const char *template = "%-18s %4ld  %6ld"; 1254. static const char *count_str = "                  count  bytes"; 1255. static const char *separator = "-- - --"; 1256. 1257. STATIC_OVL void 1258. count_obj(chain, total_count, total_size, top, recurse) 1259. 	struct obj *chain; 1260. 	long *total_count; 1261. 	long *total_size; 1262. 	boolean top; 1263. 	boolean recurse; 1264. { 1265. 	long count, size; 1266. 	struct obj *obj; 1267. 1268. 	for (count = size = 0, obj = chain; obj; obj = obj->nobj) { 1269. 	   if (top) { 1270. 		count++; 1271. 		size += sizeof(struct obj) + obj->oxlth + obj->onamelth; 1272. 	   }  1273. 	    if (recurse && obj->cobj) 1274. 		count_obj(obj->cobj, total_count, total_size, TRUE, TRUE); 1275. 	} 1276. 	*total_count += count; 1277. 	*total_size += size; 1278. } 1279.  1280. STATIC_OVL void 1281. obj_chain(win, src, chain, total_count, total_size) 1282. 	winid win; 1283. 	const char *src; 1284. 	struct obj *chain; 1285. 	long *total_count; 1286. 	long *total_size; 1287. { 1288. 	char buf[BUFSZ]; 1289. 	long count = 0, size = 0; 1290. 1291. 	count_obj(chain, &count, &size, TRUE, FALSE); 1292. 	*total_count += count; 1293. 	*total_size += size; 1294. 	Sprintf(buf, template, src, count, size); 1295. 	putstr(win, 0, buf); 1296. } 1297.  1298. STATIC_OVL void 1299. mon_invent_chain(win, src, chain, total_count, total_size) 1300. 	winid win; 1301. 	const char *src; 1302. 	struct monst *chain; 1303. 	long *total_count; 1304. 	long *total_size; 1305. { 1306. 	char buf[BUFSZ]; 1307. 	long count = 0, size = 0; 1308. 	struct monst *mon; 1309. 1310. 	for (mon = chain; mon; mon = mon->nmon) 1311. 	   count_obj(mon->minvent, &count, &size, TRUE, FALSE); 1312. 	*total_count += count; 1313. 	*total_size += size; 1314. 	Sprintf(buf, template, src, count, size); 1315. 	putstr(win, 0, buf); 1316. } 1317.  1318. STATIC_OVL void 1319. contained(win, src, total_count, total_size) 1320. 	winid win; 1321. 	const char *src; 1322. 	long *total_count; 1323. 	long *total_size; 1324. { 1325. 	char buf[BUFSZ]; 1326. 	long count = 0, size = 0; 1327. 	struct monst *mon; 1328. 1329. 	count_obj(invent, &count, &size, FALSE, TRUE); 1330. 	count_obj(fobj, &count, &size, FALSE, TRUE); 1331. 	count_obj(level.buriedobjlist, &count, &size, FALSE, TRUE); 1332. 	count_obj(migrating_objs, &count, &size, FALSE, TRUE); 1333. 	for (mon = fmon; mon; mon = mon->nmon) 1334. 	   count_obj(mon->minvent, &count, &size, FALSE, TRUE); 1335. 	for (mon = migrating_mons; mon; mon = mon->nmon) 1336. 	   count_obj(mon->minvent, &count, &size, FALSE, TRUE); 1337. 1338. 	*total_count += count; *total_size += size; 1339. 1340. 	Sprintf(buf, template, src, count, size); 1341. 	putstr(win, 0, buf); 1342. } 1343.  1344. STATIC_OVL void 1345. mon_chain(win, src, chain, total_count, total_size) 1346. 	winid win; 1347. 	const char *src; 1348. 	struct monst *chain; 1349. 	long *total_count; 1350. 	long *total_size; 1351. { 1352. 	char buf[BUFSZ]; 1353. 	long count, size; 1354. 	struct monst *mon; 1355. 1356. 	for (count = size = 0, mon = chain; mon; mon = mon->nmon) { 1357. 	   count++; 1358. 	   size += sizeof(struct monst) + mon->mxlth + mon->mnamelth; 1359. 	} 1360. 	*total_count += count; 1361. 	*total_size += size; 1362. 	Sprintf(buf, template, src, count, size); 1363. 	putstr(win, 0, buf); 1364. } 1365.  1366. /*  1367.  * Display memory usage of all monsters and objects on the level. 1368. */  1369. static int 1370. wiz_show_stats 1371. { 1372. 	char buf[BUFSZ]; 1373. 	winid win; 1374. 	long total_obj_size = 0, total_obj_count = 0; 1375. 	long total_mon_size = 0, total_mon_count = 0; 1376. 1377. 	win = create_nhwindow(NHW_TEXT); 1378. 	putstr(win, 0, "Current memory statistics:"); 1379. 	putstr(win, 0, ""); 1380. 	Sprintf(buf, "Objects, size %d", (int) sizeof(struct obj)); 1381. 	putstr(win, 0, buf); 1382. 	putstr(win, 0, ""); 1383. 	putstr(win, 0, count_str); 1384. 1385. 	obj_chain(win, "invent", invent, &total_obj_count, &total_obj_size); 1386. 	obj_chain(win, "fobj", fobj, &total_obj_count, &total_obj_size); 1387. 	obj_chain(win, "buried", level.buriedobjlist, 1388. 				&total_obj_count, &total_obj_size); 1389. 	obj_chain(win, "migrating obj", migrating_objs, 1390. 				&total_obj_count, &total_obj_size); 1391. 	mon_invent_chain(win, "minvent", fmon, 1392. 				&total_obj_count,&total_obj_size); 1393. 	mon_invent_chain(win, "migrating minvent", migrating_mons, 1394. 				&total_obj_count, &total_obj_size); 1395. 1396. 	contained(win, "contained",  1397. 				&total_obj_count, &total_obj_size); 1398. 1399. 	putstr(win, 0, separator); 1400. 	Sprintf(buf, template, "Total", total_obj_count, total_obj_size); 1401. 	putstr(win, 0, buf); 1402. 1403. 	putstr(win, 0, ""); 1404. 	putstr(win, 0, ""); 1405. 	Sprintf(buf, "Monsters, size %d", (int) sizeof(struct monst)); 1406. 	putstr(win, 0, buf); 1407. 	putstr(win, 0, ""); 1408. 1409. 	mon_chain(win, "fmon", fmon,  1410. 				&total_mon_count, &total_mon_size); 1411. 	mon_chain(win, "migrating", migrating_mons, 1412. 				&total_mon_count, &total_mon_size); 1413. 1414. 	putstr(win, 0, separator); 1415. 	Sprintf(buf, template, "Total", total_mon_count, total_mon_size); 1416. 	putstr(win, 0, buf); 1417. 1418. #ifdef __BORLANDC__ 1419. 	show_borlandc_stats(win); 1420. #endif 1421. 1422. 	display_nhwindow(win, FALSE); 1423. 	destroy_nhwindow(win); 1424. 	return 0; 1425. } 1426.  1427. void 1428. sanity_check 1429. { 1430. 	obj_sanity_check; 1431. 	timer_sanity_check; 1432. } 1433.  1434. #endif /* WIZARD */ 1435. 1436. #define unctrl(c)	((c) <= C('z') ? (0x60 | (c)) : (c)) 1437. #define unmeta(c)	(0x7f & (c)) 1438. 1439.  1440. void 1441. rhack(cmd) 1442. register char *cmd; 1443. { 1444. 	boolean do_walk, do_rush, prefix_seen, bad_command, 1445. 		firsttime = (cmd == 0); 1446. 1447. 	if (firsttime) { 1448. 		flags.nopick = 0; 1449. 		cmd = parse; 1450. 	} 1451. 	if (*cmd == '\033') { 1452. 		flags.move = FALSE; 1453. 		return; 1454. 	} 1455. #ifdef REDO 1456. 	if (*cmd == DOAGAIN && !in_doagain && saveq[0]) { 1457. 		in_doagain = TRUE; 1458. 		stail = 0; 1459. 		rhack((char *)0);	/* read and execute command */ 1460. 		in_doagain = FALSE; 1461. 		return; 1462. 	} 1463. 	/* Special case of *cmd == ' ' handled better below */ 1464. 	if(!*cmd || *cmd == (char)0377) 1465. #else 1466. 	if(!*cmd || *cmd == (char)0377 || (!flags.rest_on_space && *cmd == ' ')) 1467. #endif 1468. 	{ 1469. 		nhbell; 1470. 		flags.move = FALSE; 1471. 		return;		/* probably we just had an interrupt */ 1472. 	} 1473.  1474. 	/* handle most movement commands */ 1475. 	do_walk = do_rush = prefix_seen = FALSE; 1476. 	switch (*cmd) { 1477. 	 case 'g': if (movecmd(cmd[1])) { 1478. 			flags.run = 2; 1479. 			do_rush = TRUE; 1480. 		   } else 1481. 			prefix_seen = TRUE; 1482. 		   break; 1483. 	 case '5': if (!iflags.num_pad) break;	/* else FALLTHRU */ 1484. 	 case 'G': if (movecmd(lowc(cmd[1]))) { 1485. 			flags.run = 3; 1486. 			do_rush = TRUE; 1487. 		   } else 1488. 			prefix_seen = TRUE; 1489. 		   break; 1490. 	 case '-': if (!iflags.num_pad) break;	/* else FALLTHRU */ 1491. 	/* Effects of movement commands and invisible monsters: 1492. 	 * m: always move onto space (even if 'I' remembered) 1493. 	 * F: always attack space (even if 'I' not remembered) 1494. 	 * normal movement: attack if 'I', move otherwise 1495. 	 */ 1496. 	 case 'F':  if (movecmd(cmd[1])) { 1497. 			flags.forcefight = 1; 1498. 			do_walk = TRUE; 1499. 		   } else 1500. 			prefix_seen = TRUE; 1501. 		   break; 1502. 	 case 'm': if (movecmd(cmd[1]) || u.dz) { 1503. 			flags.run = 0; 1504. 			flags.nopick = 1; 1505. 			if (!u.dz) do_walk = TRUE; 1506. 			else cmd[0] = cmd[1];	/* "m<" or "m>" */ 1507. 		   } else 1508. 			prefix_seen = TRUE; 1509. 		   break; 1510. 	 case 'M': if (movecmd(lowc(cmd[1]))) { 1511. 			flags.run = 1; 1512. 			flags.nopick = 1; 1513. 			do_rush = TRUE; 1514. 		   } else 1515. 			prefix_seen = TRUE; 1516. 		   break; 1517. 	 case '0': if (!iflags.num_pad) break; 1518. 		   (void)ddoinv; /* a convenience borrowed from the PC */ 1519. 		   flags.move = FALSE; 1520. 		   multi = 0; 1521. 		   return; 1522. 	 default:  if (movecmd(*cmd)) {	/* ordinary movement */ 1523. 			do_walk = TRUE; 1524. 		   } else if (movecmd(iflags.num_pad ? 1525. 				      unmeta(*cmd) : lowc(*cmd))) { 1526. 			flags.run = 1; 1527. 			do_rush = TRUE; 1528. 		   } else if (movecmd(unctrl(*cmd))) { 1529. 			flags.run = 3; 1530. 			do_rush = TRUE; 1531. 		   }  1532. 		    break; 1533. 	} 1534. 	if (do_walk) { 1535. 	   if (multi) flags.mv = TRUE; 1536. 	   domove; 1537. 	   flags.forcefight = 0; 1538. 	   return; 1539. 	} else if (do_rush) { 1540. 	   if (firsttime) { 1541. 		if (!multi) multi = max(COLNO,ROWNO); 1542. 		u.last_str_turn = 0; 1543. 	   }  1544. 	    flags.mv = TRUE; 1545. 	   domove; 1546. 	   return; 1547. 	} else if (prefix_seen && cmd[1] == '\033') {	/* */ 1548. 	   /* don't report "unknown command" for change of heart... */ 1549. 	    bad_command = FALSE; 1550. 	} else if (*cmd == ' ' && !flags.rest_on_space) { 1551. 	   bad_command = TRUE;		/* skip cmdlist[] loop */ 1552. 1553. 	/* handle all other commands */ 1554. 	} else { 1555. 	   register const struct func_tab *tlist; 1556. 	   int res, NDECL((*func)); 1557. 1558. 	    for (tlist = cmdlist; tlist->f_char; tlist++) { 1559. 		if ((*cmd & 0xff) != (tlist->f_char & 0xff)) continue; 1560. 1561. 		if (u.uburied && !tlist->can_if_buried) { 1562. 		   You_cant("do that while you are buried!"); 1563. 		   res = 0; 1564. 		} else { 1565. 		   /* we discard 'const' because some compilers seem to have 1566. 		      trouble with the pointer passed to set_occupation */ 1567. 		   func = ((struct func_tab *)tlist)->f_funct; 1568. 		   if (tlist->f_text && !occupation && multi) 1569. 			set_occupation(func, tlist->f_text, multi); 1570. 		   res = (*func);		/* perform the command */ 1571. 		} 1572. 		if (!res) { 1573. 		   flags.move = FALSE; 1574. 		   multi = 0; 1575. 		} 1576. 		return; 1577. 	   }  1578. 	    /* if we reach here, cmd wasn't found in cmdlist[] */ 1579. 	   bad_command = TRUE; 1580. 	} 1581.  1582. 	if (bad_command) { 1583. 	   char expcmd[10]; 1584. 	   register char *cp = expcmd; 1585. 1586. 	    while (*cmd && (int)(cp - expcmd) < (int)(sizeof expcmd - 3)) { 1587. 		if (*cmd >= 040 && *cmd < 0177) { 1588. 		   *cp++ = *cmd++; 1589. 		} else if (*cmd & 0200) { 1590. 		   *cp++ = 'M'; 1591. 		   *cp++ = '-'; 1592. 		   *cp++ = *cmd++ &= ~0200; 1593. 		} else { 1594. 		   *cp++ = '^'; 1595. 		   *cp++ = *cmd++ ^ 0100; 1596. 		} 1597. 	    }  1598. 	    *cp = '\0'; 1599. 	   Norep("Unknown command '%s'.", expcmd); 1600. 	} 1601. 	/* didn't move */ 1602. 	flags.move = FALSE; 1603. 	multi = 0; 1604. 	return; 1605. } 1606.  1607. int 1608. xytod(x, y)	/* convert an x,y pair into a direction code */ 1609. schar x, y; 1610. { 1611. 	register int dd; 1612. 1613. 	for(dd = 0; dd < 8; dd++) 1614. 	   if(x == xdir[dd] && y == ydir[dd]) return dd; 1615. 1616. 	return -1; 1617. } 1618.  1619. void 1620. dtoxy(cc,dd)	/* convert a direction code into an x,y pair */ 1621. coord *cc; 1622. register int dd; 1623. { 1624. 	cc->x = xdir[dd]; 1625. 	cc->y = ydir[dd]; 1626. 	return; 1627. } 1628.  1629. int 1630. movecmd(sym)	/* also sets u.dz, but returns false for <> */ 1631. char sym; 1632. { 1633. 	register const char *dp; 1634. 	register const char *sdp; 1635. 	if(iflags.num_pad) sdp = ndir; else sdp = sdir;	/* DICE workaround */ 1636. 1637. 	u.dz = 0; 1638. 	if(!(dp = index(sdp, sym))) return 0; 1639. 	u.dx = xdir[dp-sdp]; 1640. 	u.dy = ydir[dp-sdp]; 1641. 	u.dz = zdir[dp-sdp]; 1642. 	if (u.dx && u.dy && u.umonnum == PM_GRID_BUG) { 1643. 		u.dx = u.dy = 0; 1644. 		return 0; 1645. 	} 1646. 	return !u.dz; 1647. } 1648.  1649. int 1650. getdir(s) 1651. const char *s; 1652. { 1653. 	char dirsym; 1654. 1655. #ifdef REDO 1656. 	if(in_doagain) 1657. 	   dirsym = readchar; 1658. 	else 1659. #endif 1660. 	   dirsym = yn_function (s ? s : "In what direction?",  1661. 					(char *)0, '\0'); 1662. #ifdef REDO 1663. 	savech(dirsym); 1664. #endif 1665. 	if(dirsym == '.' || dirsym == 's') 1666. 		u.dx = u.dy = u.dz = 0; 1667. 	else if(!movecmd(dirsym) && !u.dz) { 1668. 		if(!index(quitchars, dirsym)) 1669. 			pline("What a strange direction!"); 1670. 		return 0; 1671. 	} 1672. 	if(!u.dz && (Stunned || (Confusion && !rn2(5)))) confdir; 1673. 	return 1; 1674. } 1675.  1676. #endif /* OVL1 */ 1677. #ifdef OVLB 1678. 1679. void 1680. confdir 1681. { 1682. 	register int x = (u.umonnum == PM_GRID_BUG) ? 2*rn2(4) : rn2(8); 1683. 	u.dx = xdir[x]; 1684. 	u.dy = ydir[x]; 1685. 	return; 1686. } 1687.  1688. #endif /* OVLB */ 1689. #ifdef OVL0 1690. 1691. int 1692. isok(x,y) 1693. register int x, y; 1694. { 1695. 	/* x corresponds to curx, so x==1 is the first column. Ach. %% */ 1696. 	return x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1; 1697. } 1698.  1699. static NEARDATA int last_multi; 1700. 1701. /*  1702.  * convert a MAP window position into a movecmd 1703. */  1704. int 1705. click_to_cmd(x, y, mod) 1706.    int x, y, mod; 1707. { 1708.     x -= u.ux; 1709.    y -= u.uy; 1710.    /* convert without using floating point, allowing sloppy clicking */ 1711.    if(x > 2*abs(y)) 1712. 	x = 1, y = 0; 1713.    else if(y > 2*abs(x)) 1714. 	x = 0, y = 1; 1715.    else if(x < -2*abs(y)) 1716. 	x = -1, y = 0; 1717.    else if(y < -2*abs(x)) 1718. 	x = 0, y = -1; 1719.    else 1720. 	x = sgn(x), y = sgn(y); 1721. 1722.     if(x == 0 && y == 0)	/* map click on player to "rest" command */ 1723. 	return '.'; 1724. 1725.     x = xytod(x, y); 1726.    if(mod == CLICK_1) { 1727. 	return (iflags.num_pad ? ndir[x] : sdir[x]); 1728.    } else { 1729. 	return (iflags.num_pad ? M(ndir[x]) : 1730. 		(sdir[x] - 'a' + 'A')); /* run command */ 1731.    }  1732. }  1733.  1734. STATIC_OVL char * 1735. parse 1736. { 1737. #ifdef LINT	/* static char in_line[COLNO]; */ 1738. 	char in_line[COLNO]; 1739. #else 1740. 	static char in_line[COLNO]; 1741. #endif 1742. 	register int foo; 1743. 	boolean prezero = FALSE; 1744. 1745. 	multi = 0; 1746. 	flags.move = 1; 1747. 	flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */ 1748.  1749. 	if (!iflags.num_pad || (foo = readchar) == 'n') 1750. 	   for  { 1751. 		foo = readchar; 1752. 		if (foo >= '0' && foo <= '9') { 1753. 		   multi = 10 * multi + foo - '0'; 1754. 		   if (multi < 0 || multi >= LARGEST_INT) multi = LARGEST_INT; 1755. 		   if (multi > 9) { 1756. 			clear_nhwindow(WIN_MESSAGE); 1757. 			Sprintf(in_line, "Count: %d", multi); 1758. 			pline(in_line); 1759. 			mark_synch; 1760. 		   }  1761. 		    last_multi = multi; 1762. 		   if (!multi && foo == '0') prezero = TRUE; 1763. 		} else break;	/* not a digit */ 1764. 	   }  1765.  1766. 	if (foo == '\033') {   /* esc cancels count (TH) */ 1767. 	   clear_nhwindow(WIN_MESSAGE); 1768. 	   multi = last_multi = 0; 1769. # ifdef REDO 1770. 	} else if (foo == DOAGAIN || in_doagain) { 1771. 	   multi = last_multi; 1772. 	} else { 1773. 	   last_multi = multi; 1774. 	   savech(0);	/* reset input queue */ 1775. 	   savech((char)foo); 1776. # endif 1777. 	} 1778.  1779. 	if (multi) { 1780. 	   multi--; 1781. 	   save_cm = in_line; 1782. 	} else { 1783. 	   save_cm = (char *)0; 1784. 	} 1785. 	in_line[0] = foo; 1786. 	in_line[1] = '\0'; 1787. 	if (foo == 'g' || foo == 'G' || (iflags.num_pad && foo == '5') || 1788. 	    foo == 'm' || foo == 'M' || foo == 'F') { 1789. 	   foo = readchar; 1790. #ifdef REDO 1791. 	   savech((char)foo); 1792. #endif 1793. 	   in_line[1] = foo; 1794. 	   in_line[2] = 0; 1795. 	} 1796. 	clear_nhwindow(WIN_MESSAGE); 1797. 	if (prezero) in_line[0] = '\033'; 1798. 	return(in_line); 1799. } 1800.  1801. #endif /* OVL0 */ 1802. #ifdef OVLB 1803. 1804. #ifdef UNIX 1805. static 1806. void 1807. end_of_input 1808. { 1809. 	exit_nhwindows("End of input?"); 1810. #ifndef NOSAVEONHANGUP 1811. 	if (!program_state.done_hup++) 1812. 	   (void) dosave0; 1813. #endif 1814. 	clearlocks; 1815. 	terminate(EXIT_SUCCESS); 1816. } 1817. #endif 1818. 1819. #endif /* OVLB */ 1820. #ifdef OVL0 1821. 1822. char 1823. readchar 1824. { 1825. 	register int sym; 1826. 	int x = u.ux, y = u.uy, mod = 0; 1827. 1828. #ifdef REDO 1829. 	sym = in_doagain ? Getchar : nh_poskey(&x, &y, &mod); 1830. #else 1831. 	sym = Getchar; 1832. #endif 1833. 1834. #ifdef UNIX 1835. # ifdef NR_OF_EOFS 1836. 	if (sym == EOF) { 1837. 	   register int cnt = NR_OF_EOFS; 1838. 	 /*  1839. 	   * Some SYSV systems seem to return EOFs for various reasons 1840. 	  * (?like when one hits break or for interrupted systemcalls?), 1841. 	  * and we must see several before we quit. 1842. 	  */  1843. 	    do { 1844. 		clearerr(stdin);	/* omit if clearerr is undefined */ 1845. 		sym = Getchar; 1846. 	   } while (--cnt && sym == EOF); 1847. 	} 1848. # endif /* NR_OF_EOFS */ 1849. 	if (sym == EOF) 1850. 	   end_of_input; 1851. #endif /* UNIX */ 1852. 1853. 	if(sym == 0) /* click event */ 1854. 	   sym = click_to_cmd(x, y, mod); 1855. 	return((char) sym); 1856. } 1857. #endif /* OVL0 */ 1858. 1859. /*cmd.c*/