Source:NetHack 3.4.0/cmd.c

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