Source:SLASH'EM 0.0.7E7F2/cmd.c

Below is the full text to cmd.c from the source code of SLASH'EM 0.0.7E7F2. To link to a particular line, write [[SLASH'EM 0.0.7E7F2/cmd.c#line123 ]], for example.

The latest source code for vanilla NetHack is at Source code.

1.   /*	SCCS Id: @(#)cmd.c	3.4	2003/02/06	*/ 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 int 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(dofire); /**/ 49.  extern int NDECL(dothrow); /**/ 50.  extern int NDECL(doeat); /**/ 51.  extern int NDECL(done2); /**/ 52.  extern int NDECL(doengrave); /**/ 53.  extern int NDECL(dopickup); /**/ 54.  extern int NDECL(ddoinv); /**/ 55.  extern int NDECL(dotypeinv); /**/ 56.  extern int NDECL(dolook); /**/ 57.  extern int NDECL(doprgold); /**/ 58.  extern int NDECL(doprwep); /**/ 59.  extern int NDECL(doprarm); /**/ 60.  extern int NDECL(doprring); /**/ 61.  extern int NDECL(dopramulet); /**/ 62.  extern int NDECL(doprtool); /**/ 63.  extern int NDECL(dosuspend); /**/ 64.  extern int NDECL(doforce); /**/ 65.  extern int NDECL(doopen); /**/ 66.  extern int NDECL(doclose); /**/ 67.  extern int NDECL(dosh); /**/ 68.  extern int NDECL(dodiscovered); /**/ 69.  extern int NDECL(doset); /**/ 70.  extern int NDECL(dotogglepickup); /**/ 71.  extern int NDECL(dowhatis); /**/ 72.  extern int NDECL(doquickwhatis); /**/ 73.  extern int NDECL(dowhatdoes); /**/ 74.  extern int NDECL(dohelp); /**/ 75.  extern int NDECL(dohistory); /**/ 76.  extern int NDECL(doloot); /**/ 77.  extern int NDECL(dodrink); /**/ 78.  extern int NDECL(dodip); /**/ 79.  extern int NDECL(dosacrifice); /**/ 80.  extern int NDECL(dopray); /**/ 81.  extern int NDECL(doturn); /**/ 82.  extern int NDECL(dotech); /**/ 83.  extern int NDECL(doredraw); /**/ 84.  extern int NDECL(doread); /**/ 85.  extern int NDECL(dosave); /**/ 86.  extern int NDECL(dosearch); /**/ 87.  extern int NDECL(doidtrap); /**/ 88.  extern int NDECL(dopay); /**/ 89.  extern int NDECL(dosit); /**/ 90.  extern int NDECL(dotalk); /**/ 91.  extern int NDECL(docast); /**/ 92.  extern int NDECL(dovspell); /**/ 93.  extern int NDECL(dotele); /**/ 94.  extern int NDECL(dountrap); /**/ 95.  extern int NDECL(doversion); /**/ 96.  extern int NDECL(doextversion); /**/ 97.  extern int NDECL(doswapweapon); /**/ 98.  extern int NDECL(doswapweapon); /**/ 99.  extern int NDECL(dowield); /**/ 100. extern int NDECL(dowieldquiver); /**/ 101. extern int NDECL(dowieldquiver); /**/ 102. extern int NDECL(dozap); /**/ 103. extern int NDECL(doorganize); /**/ 104. extern int NDECL(dolistvanq); /**/ 105.  106.  #endif /* DUMB */ 107.  108.  #ifdef OVL1 109. static int NDECL((*timed_occ_fn)); 110. #endif /* OVL1 */ 111.  112.  STATIC_PTR int NDECL(doprev_message); 113. STATIC_PTR int NDECL(timed_occupation); 114. STATIC_PTR int NDECL(doextcmd); 115. #ifdef BORG 116. STATIC_PTR int NDECL(doborgtoggle); 117. #endif 118. STATIC_PTR int NDECL(domonability); 119. STATIC_PTR int NDECL(dotravel); 120. STATIC_PTR int NDECL(playersteal); 121. #if 0 122. STATIC_PTR int NDECL(specialpower); /* WAC -- use techniques */ 123. #endif 124. # ifdef WIZARD 125. STATIC_PTR int NDECL(wiz_wish); 126. STATIC_PTR int NDECL(wiz_identify); 127. STATIC_PTR int NDECL(wiz_map); 128. /* BEGIN TSANTH'S CODE */ 129. STATIC_PTR int NDECL(wiz_gain_ac); 130. STATIC_PTR int NDECL(wiz_gain_level); 131. STATIC_PTR int NDECL(wiz_toggle_invulnerability); 132. /* END TSANTH'S CODE */ 133. STATIC_PTR int NDECL(wiz_genesis); 134. STATIC_PTR int NDECL(wiz_where); 135. STATIC_PTR int NDECL(wiz_detect); 136. STATIC_PTR int NDECL(wiz_panic); 137. STATIC_PTR int NDECL(wiz_polyself); 138. STATIC_PTR int NDECL(wiz_level_tele); 139. STATIC_PTR int NDECL(wiz_level_change); 140. STATIC_PTR int NDECL(wiz_show_seenv); 141. STATIC_PTR int NDECL(wiz_show_vision); 142. STATIC_PTR int NDECL(wiz_mon_polycontrol); 143. STATIC_PTR int NDECL(wiz_show_wmodes); 144. #if defined(__BORLANDC__) && !defined(_WIN32) 145. extern void FDECL(show_borlandc_stats, (winid)); 146. #endif 147. #ifdef DEBUG_MIGRATING_MONS 148. STATIC_PTR int NDECL(wiz_migrate_mons); 149. #endif 150. STATIC_DCL void FDECL(count_obj, (struct obj *, long *, long *, BOOLEAN_P, BOOLEAN_P)); 151. STATIC_DCL void FDECL(obj_chain, (winid, const char *, struct obj *, long *, long *)); 152. STATIC_DCL void FDECL(mon_invent_chain, (winid, const char *, struct monst *, long *, long *)); 153. STATIC_DCL void FDECL(mon_chain, (winid, const char *, struct monst *, long *, long *)); 154. STATIC_DCL void FDECL(contained, (winid, const char *, long *, long *)); 155. STATIC_PTR int NDECL(wiz_show_stats); 156. #ifdef DISPLAY_LAYERS 157. STATIC_PTR int NDECL(wiz_show_display); 158. #endif 159. #  ifdef PORT_DEBUG 160. STATIC_DCL int NDECL(wiz_port_debug); 161. #  endif 162. # endif 163. STATIC_PTR int NDECL(enter_explore_mode); 164. STATIC_PTR int NDECL(doattributes); 165. STATIC_PTR int NDECL(doconduct); /**/ 166. STATIC_PTR boolean NDECL(minimal_enlightenment); 167. STATIC_PTR int FDECL(makemenu, (const char *, struct menu_list *)); 168.  169.  static NEARDATA struct rm *maploc; 170.  171.  #ifdef OVLB 172. STATIC_DCL void FDECL(enlght_line, (const char *,const char *,const char *)); 173. STATIC_DCL char *FDECL(enlght_combatinc, (const char *,int,int,char *)); 174. #ifdef UNIX 175. static void NDECL(end_of_input); 176. #endif 177. #endif /* OVLB */ 178.  179.  static const char* readchar_queue=""; 180.  181.  STATIC_DCL char *NDECL(parse); 182. STATIC_DCL boolean FDECL(help_dir, (CHAR_P,const char *)); 183.  184.  STATIC_PTR int NDECL(domenusystem); /* WAC the menus*/ 185.  186.  #ifdef BORG 187. /* in borg.c */ 188. extern char borg_on; 189. extern char borg_line[80]; 190. char borg_input(void); 191. #endif 192. #ifdef OVL1 193.  194.  STATIC_PTR int 195. doprev_message 196. {  197.      return nh_doprev_message; 198. }  199.   200.   201.  /* Count down by decrementing multi */ 202. STATIC_PTR int 203. timed_occupation 204. {  205.  	(*timed_occ_fn); 206. 	if (multi > 0) 207. 		multi--; 208. 	return multi > 0; 209. }  210.   211.  /* If you have moved since initially setting some occupations, they 212.  * now shouldn't be able to restart. 213.  *  214.   * The basic rule is that if you are carrying it, you can continue 215.  * since it is with you. If you are acting on something at a distance, 216.  * your orientation to it must have changed when you moved. 217.  *  218.   * The exception to this is taking off items, since they can be taken 219.  * off in a number of ways in the intervening time, screwing up ordering. 220.  *  221.   *	Currently:	Take off all armor. 222.  *			Picking Locks / Forcing Chests. 223.  *			Setting traps. 224.  */  225.  void 226. reset_occupations 227. {  228.  	reset_remarm; 229. 	reset_pick; 230. 	reset_trapset; 231. }  232.   233.  /* If a time is given, use it to timeout this function, otherwise the 234.  * function times out by its own means. 235.  */  236.  void 237. set_occupation(fn, txt, xtime) 238. int NDECL((*fn)); 239. const char *txt; 240. int xtime; 241. {  242.  	if (xtime) { 243. 		occupation = timed_occupation; 244. 		timed_occ_fn = fn; 245. 	} else 246. 		occupation = fn; 247. 	occtxt = txt; 248. 	occtime = 0; 249. 	return; 250. }  251.   252.  #ifdef REDO 253.  254.  static char NDECL(popch); 255.  256.  /* Provide a means to redo the last command. The flag `in_doagain' is set 257.  * to true while redoing the command. This flag is tested in commands that 258.  * require additional input (like `throw' which requires a thing and a  259.   * direction), and the input prompt is not shown. Also, while in_doagain is 260. * TRUE, no keystrokes can be saved into the saveq. 261.  */  262.  #define BSIZE 20 263. static char pushq[BSIZE], saveq[BSIZE]; 264. static NEARDATA int phead, ptail, shead, stail; 265.  266.  static char 267. popch { 268. 	/* If occupied, return '\0', letting tgetch know a character should 269. 	 * be read from the keyboard. If the character read is not the 270. 	 * ABORT character (as checked in pcmain.c), that character will be  271. * pushed back on the pushq. 272. 	 */  273.  	if (occupation) return '\0'; 274. 	if (in_doagain) return(char)((shead != stail) ? saveq[stail++] : '\0'); 275. 	else		return(char)((phead != ptail) ? pushq[ptail++] : '\0'); 276. }  277.   278.  char 279. pgetchar {		/* curtesy of aeb@cwi.nl */ 280. 	register int ch; 281.  282.  	if(!(ch = popch)) 283. 		ch = nhgetch; 284. 	return((char)ch); 285. }  286.   287.  /* A ch == 0 resets the pushq */ 288. void 289. pushch(ch) 290. char ch; 291. {  292.  	if (!ch) 293. 		phead = ptail = 0; 294. 	if (phead < BSIZE) 295. 		pushq[phead++] = ch; 296. 	return; 297. }  298.   299.  /* A ch == 0 resets the saveq. Only save keystrokes when not 300.  * replaying a previous command. 301.  */  302.  void 303. savech(ch) 304. char ch; 305. {  306.  	if (!in_doagain) { 307. 		if (!ch) 308. 			phead = ptail = shead = stail = 0; 309. 		else if (shead < BSIZE) 310. 			saveq[shead++] = ch; 311. 	}  312.  	return; 313. }  314.  #endif /* REDO */ 315.  316.  #endif /* OVL1 */ 317. #ifdef OVLB 318.  319.  STATIC_PTR int 320. doextcmd	/* here after # - now read a full-word command */ 321. {  322.  	int idx, retval; 323.  324.  	/* keep repeating until we don't run help or quit */ 325. 	do { 326. 	    idx = get_ext_cmd; 327. 	    if (idx < 0) return 0;	/* quit */ 328.  329.  	    retval = (*extcmdlist[idx].ef_funct); 330. 	} while (extcmdlist[idx].ef_funct == doextlist); 331.  332.  	return retval; 333. }  334.   335.  int 336. doextlist	/* here after #? - now list all full-word commands */ 337. {  338.  	register const struct ext_func_tab *efp; 339. 	char	 buf[BUFSZ]; 340. 	winid datawin; 341.  342.  	datawin = create_nhwindow(NHW_TEXT); 343. 	putstr(datawin, 0, ""); 344. 	putstr(datawin, 0, "            Extended Commands List"); 345. 	putstr(datawin, 0, ""); 346. 	putstr(datawin, 0, "    Press '#', then type:"); 347. 	putstr(datawin, 0, ""); 348.  349.  	for(efp = extcmdlist; efp->ef_txt; efp++) { 350. 		Sprintf(buf, "    %-15s - %s.", efp->ef_txt, efp->ef_desc); 351. 		putstr(datawin, 0, buf); 352. 	}  353.  	display_nhwindow(datawin, FALSE); 354. 	destroy_nhwindow(datawin); 355. 	return 0; 356. }  357.   358.  #ifdef BORG 359. STATIC_PTR int 360. doborgtoggle 361. {  362.  	char    qbuf[QBUFSZ]; 363. 	char    c;  364. Strcpy(qbuf,"Really enable cyborg?"); 365. 	if ((c = yn_function(qbuf, ynqchars, 'n')) == 'y') { 366. 		borg_on = 1; 367. 		pline("The cyborg is enabled.... Good luck!"); 368. 	}  369.  	return 0; 370. }  371.  #endif 372.  373.  #if defined(TTY_GRAPHICS) || defined(GL_GRAPHICS) || defined(SDL_GRAPHICS) 374. #define MAX_EXT_CMD 40		/* Change if we ever have > 40 ext cmds */ 375. /*  376.   * This is currently used only by the tty port and is  377. * controlled via runtime option 'extmenu' 378.  * -AJA- The SDL/GL window systems use it too. 379.  */  380.  int 381. extcmd_via_menu	/* here after # - now show pick-list of possible commands */ 382. {  383.      const struct ext_func_tab *efp; 384.     menu_item *pick_list = (menu_item *)0; 385.     winid win; 386.     anything any; 387.     const struct ext_func_tab *choices[MAX_EXT_CMD]; 388.     char buf[BUFSZ]; 389.     char cbuf[QBUFSZ], prompt[QBUFSZ], fmtstr[20]; 390.     int i, n, nchoices, acount; 391.     int ret,  biggest; 392.     int accelerator, prevaccelerator; 393.     int  matchlevel = 0; 394.  395.      ret = 0; 396.     cbuf[0] = '\0'; 397.     biggest = 0; 398.     while (!ret) { 399. 	    i = n = 0; 400. 	    accelerator = 0; 401. 	    any.a_void = 0; 402. 	    /* populate choices */ 403. 	    for(efp = extcmdlist; efp->ef_txt; efp++) { 404. 		if (!matchlevel || !strncmp(efp->ef_txt, cbuf, matchlevel)) { 405. 			choices[i++] = efp; 406. 			if ((int)strlen(efp->ef_desc) > biggest) { 407. 				biggest = strlen(efp->ef_desc); 408. 				Sprintf(fmtstr,"%%-%ds", biggest + 15); 409. 			}  410.  #ifdef DEBUG 411. 			if (i >= MAX_EXT_CMD - 2) { 412. 			    impossible("Exceeded %d extended commands in doextcmd menu",  413.  					MAX_EXT_CMD - 2); 414. 			    return 0; 415. 			}  416.  #endif 417. 		}  418.  	    }  419.  	    choices[i] = (struct ext_func_tab *)0; 420. 	    nchoices = i;  421. /* if we're down to one, we have our selection so get out of here */ 422. 	    if (nchoices == 1) { 423. 		for (i = 0; extcmdlist[i].ef_txt != (char *)0; i++) 424. 			if (!strncmpi(extcmdlist[i].ef_txt, cbuf, matchlevel)) { 425. 				ret = i;  426. break; 427. 			}  428.  		break; 429. 	    }  430.   431.  	    /* otherwise... */ 432.  	    win = create_nhwindow(NHW_MENU); 433. 	    start_menu(win); 434. 	    prevaccelerator = 0; 435. 	    acount = 0; 436. 	    for(i = 0; choices[i]; ++i) { 437. 		accelerator = choices[i]->ef_txt[matchlevel]; 438. 		if (accelerator != prevaccelerator || nchoices < (ROWNO - 3)) { 439. 		    if (acount) { 440.  			/* flush the extended commands for that letter already in buf */ 441. 			Sprintf(buf, fmtstr, prompt); 442. 			any.a_char = prevaccelerator; 443. 			add_menu(win, NO_GLYPH, &any, any.a_char, 0,  444.  					ATR_NONE, buf, FALSE); 445. 			acount = 0; 446. 		    }  447.  		}  448.  		prevaccelerator = accelerator; 449. 		if (!acount || nchoices < (ROWNO - 3)) { 450. 		    Sprintf(prompt, "%s [%s]", choices[i]->ef_txt,  451.  				choices[i]->ef_desc); 452. 		} else if (acount == 1) { 453. 		    Sprintf(prompt, "%s or %s", choices[i-1]->ef_txt,  454.  				choices[i]->ef_txt); 455. 		} else { 456. 		    Strcat(prompt," or "); 457. 		    Strcat(prompt, choices[i]->ef_txt); 458. 		}  459.  		++acount; 460. 	    }  461.  	    if (acount) { 462. 		/* flush buf */ 463. 		Sprintf(buf, fmtstr, prompt); 464. 		any.a_char = prevaccelerator; 465. 		add_menu(win, NO_GLYPH, &any, any.a_char, 0, ATR_NONE, buf, FALSE); 466. 	    }  467.  	    Sprintf(prompt, "Extended Command: %s", cbuf); 468. 	    end_menu(win, prompt); 469. 	    n = select_menu(win, PICK_ONE, &pick_list); 470. 	    destroy_nhwindow(win); 471. 	    if (n==1) { 472. 		if (matchlevel > (QBUFSZ - 2)) { 473. 			free((genericptr_t)pick_list); 474. #ifdef DEBUG 475. 			impossible("Too many characters (%d) entered in extcmd_via_menu",  476.  				matchlevel); 477. #endif 478. 			ret = -1; 479. 		} else { 480. 			cbuf[matchlevel++] = pick_list[0].item.a_char; 481. 			cbuf[matchlevel] = '\0'; 482. 			free((genericptr_t)pick_list); 483. 		}  484.  	    } else { 485. 		if (matchlevel) { 486. 			ret = 0; 487. 			matchlevel = 0; 488. 		} else 489. 			ret = -1; 490. 	    }  491.      }  492.      return ret; 493. }  494.  #endif 495.  496.  /* #monster command - use special monster ability while polymorphed */ 497. STATIC_PTR int 498. domonability 499. {  500.  	if (can_breathe(youmonst.data)) return dobreathe; 501. 	else if (attacktype(youmonst.data, AT_SPIT)) return dospit; 502. 	else if (youmonst.data->mlet == S_NYMPH) return doremove; 503. 	else if (attacktype(youmonst.data, AT_GAZE)) return dogaze; 504. 	else if (is_were(youmonst.data)) return dosummon; 505. 	else if (webmaker(youmonst.data)) return dospinweb; 506. 	else if (is_hider(youmonst.data)) return dohide; 507. 	else if (is_mind_flayer(youmonst.data)) return domindblast; 508. 	else if (u.umonnum == PM_GREMLIN) { 509. 	    if(IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 510. 		if (split_mon(&youmonst, (struct monst *)0)) 511. 		    dryup(u.ux, u.uy, TRUE); 512. 	    } else There("is no fountain here."); 513. 	} else if (is_unicorn(youmonst.data)) { 514. 	    use_unicorn_horn((struct obj *)0); 515. 	    return 1; 516. 	} else if (youmonst.data->msound == MS_SHRIEK) { 517. 	    You("shriek."); 518. 	    if(u.uburied) 519. 		pline("Unfortunately sound does not carry well through rock."); 520. 	    else aggravate; 521. 	} else if (Upolyd) 522. 		pline("Any special ability you may have is purely reflexive."); 523. 	else You("don't have a special ability in your normal form!"); 524. 	return 0; 525. }  526.   527.  STATIC_PTR int 528. enter_explore_mode 529. {  530.  	if(!discover && !wizard) { 531. 		pline("Beware!  From explore mode there will be no return to normal game."); 532. 		if (yn("Do you want to enter explore mode?") == 'y') { 533. 			clear_nhwindow(WIN_MESSAGE); 534. 			You("are now in non-scoring explore mode."); 535. 			discover = TRUE; 536. 		}  537.  		else { 538. 			clear_nhwindow(WIN_MESSAGE); 539. 			pline("Resuming normal game."); 540. 		}  541.  	}  542.  	return 0; 543. }  544.   545.   546.  STATIC_PTR int 547. playersteal 548. {  549.  	register int x, y;  550. int temp, chanch, base, dexadj, statbonus = 0; 551. 	boolean no_steal = FALSE; 552.  553.  	if (nohands(youmonst.data)) { 554. 		pline("Could be hard without hands ..."); 555. 		no_steal = TRUE; 556. 	} else 557. 	if (near_capacity > SLT_ENCUMBER) { 558. 		Your("load is too heavy to attempt to steal."); 559. 		no_steal = TRUE; 560. 	}  561.  	if (no_steal) { 562. 		/* discard direction typeahead, if any */ 563. 		display_nhwindow(WIN_MESSAGE, TRUE);    /* --More-- */ 564. 		return(0); 565. 	}  566.   567.  	if(!getdir(NULL)) return(0); 568. 	if(!u.dx && !u.dy) return(0); 569.  570.  	x = u.ux + u.dx; 571. 	y = u.uy + u.dy; 572. 	  573.  	if(u.uswallow) { 574. 		pline("You search around but don't find anything."); 575. 		return(1); 576. 	}  577.   578.  	u_wipe_engr(2); 579.  580.  	maploc = &levl[x][y]; 581.  582.  	if(MON_AT(x, y)) { 583. 		register struct monst *mdat = m_at(x, y); 584.  585.  		/* calculate chanch of sucess */ 586. 		base = 5; 587. 		dexadj = 1; 588. 		if (Role_if(PM_ROGUE)) { 589. 			base = 5 + (u.ulevel * 2); 590. 			dexadj = 3; 591. 		}  592.  		if (ACURR(A_DEX) < 10) statbonus = (ACURR(A_DEX) - 10) * dexadj; 593. 		else 594. 		if (ACURR(A_DEX) > 14) statbonus = (ACURR(A_DEX) - 14) * dexadj; 595.  596.  		chanch = base + statbonus; 597.  598.  		if (uarmg && uarmg->otyp != GAUNTLETS_OF_DEXTERITY) 599. 				chanch -= 5; 600. 		if (!uarmg)     chanch += 5; 601. 		if (uarms)      chanch -= 10; 602. 		if (uarm && uarm->owt < 75)       chanch += 10; 603. 		else if (uarm && uarm->owt < 125) chanch += 5; 604. 		else if (uarm && uarm->owt < 175) chanch += 0; 605. 		else if (uarm && uarm->owt < 225) chanch -= 5; 606. 		else if (uarm && uarm->owt < 275) chanch -= 10; 607. 		else if (uarm && uarm->owt < 325) chanch -= 15; 608. 		else if (uarm && uarm->owt < 375) chanch -= 20; 609. 		else if (uarm)                    chanch -= 25; 610. 		if (chanch < 5) chanch = 5; 611. 		if (chanch > 95) chanch = 95; 612. 		if (rnd(100) < chanch || mdat->mtame) { 613.  614.  #ifdef GOLDOBJ 615. 			/* [CWC] This will steal money from the monster from the 616. 			 * first found goldobj - we could be really clever here and 617. 			 * then move onwards to the next goldobj in invent if we  618. * still have coins left to steal, but lets leave that until 619. 			 * we actually have other coin types to test it on. 620. 			 */  621.  			struct obj *gold = findgold(mdat->minvent); 622. 			if (gold) { 623. 				int mongold; 624. 				int coinstolen; 625. 				coinstolen = (u.ulevel * rn1(25,25)); 626. 				mongold = (int)gold->quan; 627. 				if (coinstolen > mongold) coinstolen = mongold; 628. 				if (coinstolen > 0)	{ 629. 					if (coinstolen != mongold) 630. 						gold = splitobj(gold, coinstolen); 631. 					obj_extract_self(gold); 632. 		      if (merge_choice(invent, gold) || inv_cnt < 52) { 633. 				    addinv(gold); 634. 						You("steal %s.", doname(gold)); 635. 					} else { 636.             You("grab %s, but find no room in your knapsack.", doname(gold)); 637. 			    	dropy(gold); 638. 					}  639.  				}  640.  				else 641. 				impossible("cmd.c:playersteal stealing negative money"); 642. #else 643. 			if (mdat->mgold) { 644. 				temp = (u.ulevel * rn1(25,25)); 645. 				if (temp > mdat->mgold) temp = mdat->mgold; 646. 				u.ugold += temp; 647. 				mdat->mgold -= temp; 648. 				You("steal %d gold.",temp); 649. #endif 650. 			} else 651. 				You("don't find anything to steal."); 652.  653.  			if (!mdat->mtame) exercise(A_DEX, TRUE); 654. 			return(1); 655. 		} else { 656. 			You("failed to steal anything."); 657. 			setmangry(mdat); 658. 			return(1); 659. 	       }  660.  	} else { 661. 		pline("I don't see anybody to rob there!"); 662. 		return(0); 663. 	}  664.   665.  	return(0); 666. }  667.   668.  #ifdef WIZARD 669.  670.  /* ^W command - wish for something */ 671. STATIC_PTR int 672. wiz_wish	/* Unlimited wishes for debug mode by Paul Polderman */ 673. {  674.  	if (wizard) { 675. 	    boolean save_verbose = flags.verbose; 676.  677.  	    flags.verbose = FALSE; 678. 	    makewish; 679. 	    flags.verbose = save_verbose; 680. 	    (void) encumber_msg; 681. 	} else 682. 	    pline("Unavailable command '^W'."); 683. 	return 0; 684. }  685.   686.   687.  #if 0	/* WAC -- Now uses techniques */ 688. STATIC_PTR int 689. specialpower      /* Special class abilites [modified by Tom] */ 690. {  691.  	/*  692.  	 * STEPHEN WHITE'S NEW CODE 693. 	 *  694.  	 * For clarification, lastuse (as declared in decl.{c|h}) is the 695. 	 * actual length of time the power is active, nextuse is when you can 696. 	 * next use the ability. 697. 	 */  698.   699.          /*Added wizard mode can choose to use ability - wAC*/ 700. 	if (u.unextuse) { 701. 	    You("have to wait %s before using your ability again.",  702.  		(u.unextuse > 500) ? "for a while" : "a little longer"); 703. #ifdef WIZARD 704.             if (!wizard || (yn("Use ability anyways?") == 'n')) 705. #endif 706.                 return(0); 707. 	}  708.   709.  	switch (u.role) { 710. 	    case 'A': 711. /*WAC stolen from the spellcasters...'A' can identify from 712.         historical research*/ 713. 		if(Hallucination || Stunned || Confusion) { 714. 		    You("can't concentrate right now!"); 715. 		    break; 716. 		} else if((ACURR(A_INT) + ACURR(A_WIS)) < rnd(60)) { 717. 			pline("Nothing in your pack looks familiar."); 718. 		    u.unextuse = rn1(500,500); 719. 		    break; 720. 		} else if(invent) { 721. 		    int ret; 722. 			You("examine your possessions."); 723. 			identify_pack(1); 724. /*WAC this should be better - made like scroll of identify*/ 725. /* KMH -- also commented out use of 'ret' without initialization */ 726. /*                  ret = ggetobj("identify", identify, 1, FALSE);*/ 727. /*		    if (ret < 0) break; *//* quit or no eligible items */ 728. /*                  ret = ggetobj("identify", identify, 1, FALSE);*/ 729. 		} else { 730. 			/* KMH -- fixed non-compliant string */ 731. 			You("are already quite familiar with the contents of your pack."); 732. 		    break; 733. 		}  734.  		u.unextuse = rn1(500,1500); 735. 		break; 736. 	    case 'G': 737. 			Your("ability, gem identification, is automatic."); 738. 			return(0); 739. 		case 'P': 740. 			Your("ability, bless and curse detection, is automatic."); 741. 			return(0); 742. 	    case 'D': 743. 			/* KMH -- Just do it! (Besides, Alt isn't portable...) */ 744. 			return (polyatwill); 745. 			/*Your("ability, polymorphing, uses the alt-y key.");*/ 746. 			/*return(0);*/ 747. 	    case 'L': 748. 		/*only when empty handed, in human form!*/ 749. 		if (Upolyd) { 750. 			You("can't do this while polymorphed!"); 751. 			break; 752. 		}  753.  		if (uwep == 0) { 754. 			Your("fingernails extend into claws!"); 755. 			aggravate; 756. 			u.ulastuse = d(2,4) + (u.ulevel/5) + 1; /* [max] was d(2,8) */ 757. 			u.unextuse = rn1(1000,1000); /* [max] increased delay */ 758. 		}  759.  		else You("can't do this while holding a weapon!"); 760. 		break; 761. 	    case 'R': 762. 	    /* KMH -- Just do it! (Besides, Alt isn't portable...) */ 763. 	    return (playersteal); 764. 		/*Your("ability, stealing, uses the alt-b key.");*/ 765.         /*return(0);*/ 766. 		break; 767. 	    case 'M': 768. 		Your("special ability is unarmed combat, and it is automatic."); 769.                 return(0); 770. 		break; 771. 	    case 'C': 772. 	    case 'T': 773. 		You("don't have a special ability!"); 774.                 return(0); 775. 		break; 776. 	    case 'B': 777. 		You("fly into a berserk rage!"); 778. 		u.ulastuse = d(2,8) + (u.ulevel/5) + 1; 779. 		incr_itimeout(&HFast, u.ulastuse); 780. 		u.unextuse = rn1(1000,500); 781. 		return(0); 782. 		break; 783. 	    case 'F': 784. 	    case 'I': 785. 	    case 'N': 786. 	    case 'W': 787.             /* WAC spell-users can study their known spells*/ 788. 		if(Hallucination || Stunned || Confusion) { 789. 		    You("can't concentrate right now!"); 790. 		    break; 791. 		} else { 792. 			You("concentrate..."); 793. 			studyspell; /*in spell.c*/ 794. 		}  795.  		break; 796. 	    case 'E': 797.                 Your("%s %s become blurs as they reach for your quiver!",  798.  			uarmg ? "gloved" : "bare",      /* Del Lamb */  799.  			makeplural(body_part(HAND))); 800.                 u.ulastuse = rnd((int) (u.ulevel/6 + 1)) + 1; 801. 		u.unextuse = rn1(1000,500); 802. 		break; 803. 	    case 'U': 804. 	    case 'V': 805. 		if(!uwep || (weapon_type(uwep) == P_NONE)) { 806. 		    You("are not wielding a weapon!"); 807. 		    break; 808. 		} else if(uwep->known == TRUE) { 809.                     You("study and practice with your %s %s.",  810.                          uarmg ? "gloved" : "bare",      /* Del Lamb */  811.  			makeplural(body_part(HAND))); 812.                     practice_weapon; 813. 		} else { 814.                     if (not_fully_identified(uwep)) { 815.                         You("examine %s.", doname(uwep)); 816.                             if (rnd(15) <= ACURR(A_INT)) { 817.                                 makeknown(uwep->otyp); 818.                                 uwep->known = TRUE; 819.                                 You("discover it is %s",doname(uwep)); 820.                                 } else 821.                      pline("Unfortunately, you didn't learn anything new."); 822.                     }  823.                  /*WAC Added practicing code - in weapon.c*/ 824.                     practice_weapon; 825. 		}  826.                  u.unextuse = rn1(500,500); 827. 		break; 828. 	    case 'H': 829. 		if (Hallucination || Stunned || Confusion) { 830. 		    You("are in no condition to perform surgery!"); 831. 		    break; 832. 		}  833.  		if ((Sick) || (Slimed)) {       /* WAC cure sliming too */ 834. 		    if(carrying(SCALPEL)) { 835. 			pline("Using your scalpel (ow!), you cure your infection!"); 836. 			make_sick(0L,(char *)0, TRUE,SICK_ALL); 837. 			Slimed = 0; 838. 			if(u.uhp > 6) u.uhp -= 5; 839. 			else          u.uhp = 1; 840. 			u.unextuse = rn1(500,500); 841. 			break; 842. 		    } else pline("If only you had a scalpel..."); 843. 		}  844.  		if (u.uhp < u.uhpmax) { 845. 		    if(carrying(MEDICAL_KIT)) { 846. 			pline("Using your medical kit, you bandage your wounds."); 847. 			u.uhp += (u.ulevel * (rnd(2)+1)) + rn1(5,5); 848. 		    } else { 849. 			pline("You bandage your wounds as best you can."); 850. 			u.uhp += (u.ulevel) + rn1(5,5); 851. 		    }  852.  		    u.unextuse = rn1(1000,500); 853. 		    if (u.uhp > u.uhpmax) u.uhp = u.uhpmax; 854. 		} else pline("You don't need your healing powers!"); 855. 		break; 856. 	    case 'K': 857. 		if (u.uhp < u.uhpmax || Sick || Slimed) { /*WAC heal sliming */ 858. 			if (Sick) You("lay your hands on the foul sickness..."); 859. 			pline("A warm glow spreads through your body!"); 860. 			if (Slimed) pline_The("slime is removed."); 861. 			Slimed = 0; 862. 			if(Sick) make_sick(0L,(char*)0, TRUE, SICK_ALL); 863. 			else     u.uhp += (u.ulevel * 4); 864. 			if (u.uhp > u.uhpmax) u.uhp = u.uhpmax; 865. 			u.unextuse = 3000; 866. 		} else pline(nothing_happens); 867. 		break; 868. 	    case 'S': 869. 		You("scream \"KIIILLL!\""); 870. 		aggravate; 871. 		u.ulastuse = rnd((int) (u.ulevel/6 + 1)) + 1; 872. 		u.unextuse = rn1(1000,500); 873. 		return(0); 874. 		break; 875. #ifdef YEOMAN 876. 		case 'Y': 877. #ifdef STEED 878. 			if (u.usteed) { 879. 				pline("%s gets tamer.", Monnam(u.usteed)); 880. 				tamedog(u.usteed, (struct obj *) 0); 881. 				u.unextuse = rn1(1000,500); 882. 			} else 883. 				Your("special ability is only effective when riding a monster."); 884. 			break; 885. #else 886. 			You("don't have a special ability!"); 887. 			return(0); 888. #endif 889. #endif 890. 	    default: 891. 		break; 892. 	  }  893.  /*By default,  action should take a turn*/ 894. 	return(1); 895. }  896.  #endif 897.  898.   899.  /* ^I command - identify hero's inventory */ 900. STATIC_PTR int 901. wiz_identify 902. {  903.  	if (wizard)	identify_pack(0); 904. 	else		pline("Unavailable command '^I'."); 905. 	return 0; 906. }  907.   908.  /* ^F command - reveal the level map and any traps on it */ 909. STATIC_PTR int 910. wiz_map 911. {  912.  	if (wizard) { 913. 	    struct trap *t; 914. 	    long save_Hconf = HConfusion, 915. 		 save_Hhallu = HHallucination; 916.  917.  	    HConfusion = HHallucination = 0L; 918. 	    for (t = ftrap; t != 0; t = t->ntrap) { 919. 		t->tseen = 1; 920. 		map_trap(t, TRUE); 921. 	    }  922.  	    do_mapping; 923. 	    HConfusion = save_Hconf; 924. 	    HHallucination = save_Hhallu; 925. 	} else 926. 	    pline("Unavailable command '^F'."); 927. 	return 0; 928. }  929.   930.  /* ^G command - generate monster(s); a count prefix will be honored */ 931. STATIC_PTR int 932. wiz_gain_level 933. {  934.  	if (wizard) pluslvl(FALSE); 935. 	else            pline("Unavailable command '^J'."); 936. 	return 0; 937. }  938.   939.  /* BEGIN TSANTH'S CODE */ 940. STATIC_PTR int 941. wiz_gain_ac 942. {  943.  	if (wizard) { 944. 		if (u.ublessed < 20) { 945. 			pline("Intrinsic AC increased by 1."); 946. 			HProtection |= FROMOUTSIDE; 947. 			u.ublessed++; 948. 			flags.botl = 1; 949. 		} else 950. 			pline("Intrinsic AC is already maximized."); 951. 	}  952.  	else 953. 		pline("Unavailable command '^C'."); 954. 	return 0; 955. }  956.   957.  STATIC_PTR int 958. wiz_toggle_invulnerability 959. {  960.  	if (wizard) { 961. 	    if ((Invulnerable == 0) && (u.uinvulnerable == FALSE)) { 962. 	            You("will be invulnerable for 32000 turns."); 963. 	            Invulnerable = 32000; 964. 	            u.uinvulnerable = TRUE; 965. 	    }  966.  	    else { 967. 	            You("are no longer invulnerable."); 968. 	            Invulnerable = 0; 969. 	            u.uinvulnerable = FALSE; 970. 	    }  971.  	}  972.  	else            pline("Unavailable command '^N'."); 973. 	return 0; 974. }  975.  /* END TSANTH'S CODE */ 976.  977.  STATIC_PTR int 978. wiz_genesis 979. {  980.  	if (wizard)	(void) create_particular; 981. 	else		pline("Unavailable command '^G'."); 982. 	return 0; 983. }  984.   985.  /* ^O command - display dungeon layout */ 986. STATIC_PTR int 987. wiz_where 988. {  989.  	if (wizard) (void) print_dungeon(FALSE, (schar *)0, (xchar *)0); 990. 	else	    pline("Unavailable command '^O'."); 991. 	return 0; 992. }  993.   994.  /* ^E command - detect unseen (secret doors, traps, hidden monsters) */ 995. STATIC_PTR int 996. wiz_detect 997. {  998.  	if(wizard)  (void) findit; 999. 	else	    pline("Unavailable command '^E'."); 1000. 	return 0; 1001. } 1002.  1003. /* ^V command - level teleport */ 1004. STATIC_PTR int 1005. wiz_level_tele 1006. { 1007. 	if (wizard)	level_tele; 1008. 	else		pline("Unavailable command '^V'."); 1009. 	return 0; 1010. } 1011.  1012. /* #monpolycontrol command - choose new form for shapechangers, polymorphees */ 1013. STATIC_PTR int 1014. wiz_mon_polycontrol 1015. { 1016.     iflags.mon_polycontrol = !iflags.mon_polycontrol; 1017.    pline("Monster polymorph control is %s.",  1018. 	  iflags.mon_polycontrol ? "on" : "off"); 1019.    return 0; 1020. } 1021.  1022. /* #levelchange command - adjust hero's experience level */ 1023. STATIC_PTR int 1024. wiz_level_change 1025. { 1026.     char buf[BUFSZ]; 1027.    int newlevel; 1028.    int ret; 1029. 1030.     getlin("To what experience level do you want to be set?", buf); 1031.    (void)mungspaces(buf); 1032.    if (buf[0] == '\033' || buf[0] == '\0') ret = 0; 1033.    else ret = sscanf(buf, "%d", &newlevel); 1034. 1035.     if (ret != 1) { 1036. 	pline(Never_mind); 1037. 	return 0; 1038.    }  1039.     if (newlevel == u.ulevel) { 1040. 	You("are already that experienced."); 1041.    } else if (newlevel < u.ulevel) { 1042. 	if (u.ulevel == 1) { 1043. 	   You("are already as inexperienced as you can get."); 1044. 	   return 0; 1045. 	} 1046. 	if (newlevel < 1) newlevel = 1; 1047. 	while (u.ulevel > newlevel) 1048. 	   losexp("#levelchange", TRUE); 1049.    } else { 1050. 	if (u.ulevel >= MAXULEV) { 1051. 	   You("are already as experienced as you can get."); 1052. 	   return 0; 1053. 	} 1054. 	if (newlevel > MAXULEV) newlevel = MAXULEV; 1055. 	while (u.ulevel < newlevel) 1056. 	   pluslvl(FALSE); 1057.    }  1058.     u.ulevelmax = u.ulevel; 1059.    return 0; 1060. } 1061.  1062. /* #panic command - test program's panic handling */ 1063. STATIC_PTR int 1064. wiz_panic 1065. { 1066. 	if (yn("Do you want to call panic and end your game?") == 'y') 1067. 		panic("crash test."); 1068.        return 0; 1069. } 1070.  1071. /* #polyself command - change hero's form */ 1072. STATIC_PTR int 1073. wiz_polyself 1074. { 1075.         polyself(TRUE); 1076.        return 0; 1077. } 1078.  1079. /* #seenv command */ 1080. STATIC_PTR int 1081. wiz_show_seenv 1082. { 1083. 	winid win; 1084. 	int x, y, v, startx, stopx, curx; 1085. 	char row[COLNO+1]; 1086. 1087. 	win = create_nhwindow(NHW_TEXT); 1088. 	/* 1089. 	 * Each seenv description takes up 2 characters, so center 1090. 	 * the seenv display around the hero. 1091. 	 */ 1092. 	startx = max(1, u.ux-(COLNO/4)); 1093. 	stopx = min(startx+(COLNO/2), COLNO); 1094. 	/* can't have a line exactly 80 chars long */ 1095. 	if (stopx - startx == COLNO/2) startx++; 1096. 1097. 	for (y = 0; y < ROWNO; y++) { 1098. 	   for (x = startx, curx = 0; x < stopx; x++, curx += 2) { 1099. 		if (x == u.ux && y == u.uy) { 1100. 		   row[curx] = row[curx+1] = '@'; 1101. 		} else { 1102. 		   v = levl[x][y].seenv & 0xff; 1103. 		   if (v == 0) 1104. 			row[curx] = row[curx+1] = ' '; 1105. 		   else 1106. 			Sprintf(&row[curx], "%02x", v); 1107. 		} 1108. 	    }  1109. 	    /* remove trailing spaces */ 1110. 	   for (x = curx-1; x >= 0; x--) 1111. 		if (row[x] != ' ') break; 1112. 	   row[x+1] = '\0'; 1113. 1114. 	    putstr(win, 0, row); 1115. 	} 1116. 	display_nhwindow(win, TRUE); 1117. 	destroy_nhwindow(win); 1118. 	return 0; 1119. } 1120.  1121. /* #vision command */ 1122. STATIC_PTR int 1123. wiz_show_vision 1124. { 1125. 	winid win; 1126. 	int x, y, v; 1127. char row[COLNO+1]; 1128. 1129. 	win = create_nhwindow(NHW_TEXT); 1130. 	Sprintf(row, "Flags: 0x%x could see, 0x%x in sight, 0x%x temp lit", 1131. 		COULD_SEE, IN_SIGHT, TEMP_LIT); 1132. 	putstr(win, 0, row); 1133. 	putstr(win, 0, ""); 1134. 	for (y = 0; y < ROWNO; y++) { 1135. 	   for (x = 1; x < COLNO; x++) { 1136. 		if (x == u.ux && y == u.uy) 1137. 		   row[x] = '@'; 1138. 		else { 1139. 		   v = viz_array[y][x]; /* data access should be hidden */ 1140. 		   if (v == 0) 1141. 			row[x] = ' '; 1142. 		   else 1143. 			row[x] = '0' + viz_array[y][x]; 1144. 		} 1145. 	    }  1146. 	    /* remove trailing spaces */ 1147. 	   for (x = COLNO-1; x >= 1; x--) 1148. 		if (row[x] != ' ') break; 1149. 	   row[x+1] = '\0'; 1150. 1151. 	    putstr(win, 0, &row[1]); 1152. 	} 1153. 	display_nhwindow(win, TRUE); 1154. 	destroy_nhwindow(win); 1155. 	return 0; 1156. } 1157.  1158. /* #wmode command */ 1159. STATIC_PTR int 1160. wiz_show_wmodes 1161. { 1162. 	winid win; 1163. 	int x,y; 1164. 	char row[COLNO+1]; 1165. 	struct rm *lev; 1166. 1167. 	win = create_nhwindow(NHW_TEXT); 1168. 	for (y = 0; y < ROWNO; y++) { 1169. 	   for (x = 0; x < COLNO; x++) { 1170. 		lev = &levl[x][y]; 1171. 		if (x == u.ux && y == u.uy) 1172. 		   row[x] = '@'; 1173. 		else if (IS_WALL(lev->typ) || lev->typ == SDOOR) 1174. 		   row[x] = '0' + (lev->wall_info & WM_MASK); 1175. 		else if (lev->typ == CORR) 1176. 		   row[x] = '#'; 1177. 		else if (IS_ROOM(lev->typ) || IS_DOOR(lev->typ)) 1178. 		   row[x] = '.'; 1179. 		else 1180. 		   row[x] = 'x'; 1181. 	   }  1182. 	    row[COLNO] = '\0'; 1183. 	   putstr(win, 0, row); 1184. 	} 1185. 	display_nhwindow(win, TRUE); 1186. 	destroy_nhwindow(win); 1187. 	return 0; 1188. } 1189.  1190. #endif /* WIZARD */ 1191. 1192.  1193. /* -enlightenment and conduct- */ 1194. static winid en_win; 1195. static const char 1196. 	You_[] = "You ", 1197. 	are[] = "are ",  were[]  = "were ", 1198. 	have[] = "have ", had[]  = "had ", 1199. 	can[] = "can ",  could[] = "could "; 1200. static const char 1201. 	have_been[] = "have been ", 1202. 	have_never[] = "have never ", never[] = "never "; 1203. 1204. #define enl_msg(prefix,present,past,suffix) \ 1205. 			enlght_line(prefix, final ? past : present, suffix) 1206. #define you_are(attr)	enl_msg(You_,are,were,attr) 1207. #define you_have(attr)	enl_msg(You_,have,had,attr) 1208. #define you_can(attr)	enl_msg(You_,can,could,attr) 1209. #define you_have_been(goodthing) enl_msg(You_,have_been,were,goodthing) 1210. #define you_have_never(badthing) enl_msg(You_,have_never,never,badthing) 1211. #define you_have_X(something)	enl_msg(You_,have,(const char *)"",something) 1212. 1213. static void 1214. enlght_line(start, middle, end) 1215. const char *start, *middle, *end; 1216. { 1217. 	char buf[BUFSZ]; 1218. 1219. 	Sprintf(buf, "%s%s%s.", start, middle, end); 1220. 	putstr(en_win, 0, buf); 1221. } 1222.  1223.  1224.  1225. /* KMH, intrinsic patch -- several of these are updated */ 1226. void 1227. enlightenment(final) 1228. int final;	/* 0 => still in progress; 1 => over, survived; 2 => dead */ 1229. { 1230. 	int ltmp; 1231. 	char buf[BUFSZ]; 1232. 1233. 	en_win = create_nhwindow(NHW_MENU); 1234. 	putstr(en_win, 0, final ? "Final Attributes:" : "Current Attributes:"); 1235. 	putstr(en_win, 0, ""); 1236. 1237. #ifdef ELBERETH 1238. 	if (u.uevent.uhand_of_elbereth) { 1239. 	   static const char * const hofe_titles[3] = { 1240. 				"the Hand of Elbereth", 1241. 				"the Envoy of Balance", 1242. 				"the Glory of Arioch" 1243. 	   };  1244. 	    you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1]); 1245. 	} 1246. #endif 1247. 1248. 	/* note: piousness 20 matches MIN_QUEST_ALIGN (quest.h) */ 1249. 	if (u.ualign.record >= 20)	you_are("piously aligned"); 1250. 	else if (u.ualign.record > 13)	you_are("devoutly aligned"); 1251. 	else if (u.ualign.record > 8)	you_are("fervently aligned"); 1252. 	else if (u.ualign.record > 3)	you_are("stridently aligned"); 1253. 	else if (u.ualign.record == 3)	you_are("aligned"); 1254. 	else if (u.ualign.record > 0)	you_are("haltingly aligned"); 1255. 	else if (u.ualign.record == 0)	you_are("nominally aligned"); 1256. 	else if (u.ualign.record >= -3)	you_have("strayed"); 1257. 	else if (u.ualign.record >= -8)	you_have("sinned"); 1258. 	else you_have("transgressed"); 1259. #ifdef WIZARD 1260. 	if (wizard) { 1261. 		Sprintf(buf, " %d", u.ualign.record); 1262. 		enl_msg("Your alignment ", "is", "was", buf); 1263. 	} 1264. #endif 1265. 1266. 	/*** Resistances to troubles ***/ 1267. 	if (Fire_resistance) you_are("fire resistant"); 1268. 	if (Cold_resistance) you_are("cold resistant"); 1269. 	if (Sleep_resistance) you_are("sleep resistant"); 1270. 	if (Disint_resistance) you_are("disintegration-resistant"); 1271. 	if (Shock_resistance) you_are("shock resistant"); 1272. 	if (Poison_resistance) you_are("poison resistant"); 1273. 	if (Drain_resistance) you_are("level-drain resistant"); 1274. 	if (Sick_resistance) you_are("immune to sickness"); 1275. 	if (Antimagic) you_are("magic-protected"); 1276. 	if (Acid_resistance) you_are("acid resistant"); 1277. 	if (Stone_resistance) 1278. 		you_are("petrification resistant"); 1279. 	if (Invulnerable) you_are("invulnerable"); 1280. 	if (u.uedibility) you_can("recognize detrimental food"); 1281. 1282. 	/*** Troubles ***/ 1283. 	if (Halluc_resistance) 1284. 		enl_msg("You resist", "", "ed", " hallucinations"); 1285. 	if (final) { 1286. 		if (Hallucination) you_are("hallucinating"); 1287. 		if (Stunned) you_are("stunned"); 1288. 		if (Confusion) you_are("confused"); 1289. 		if (Blinded) you_are("blinded"); 1290. 		if (Sick) { 1291. 			if (u.usick_type & SICK_VOMITABLE) 1292. 				you_are("sick from food poisoning"); 1293. 			if (u.usick_type & SICK_NONVOMITABLE) 1294. 				you_are("sick from illness"); 1295. 		} 1296. 	}  1297. 	if (Stoned) you_are("turning to stone"); 1298. 	if (Slimed) you_are("turning into slime"); 1299. 	if (Strangled) you_are((u.uburied) ? "buried" : "being strangled"); 1300. 	if (Glib) { 1301. 		Sprintf(buf, "slippery %s", makeplural(body_part(FINGER))); 1302. 		you_have(buf); 1303. 	} 1304. 	if (Fumbling) enl_msg("You fumble", "", "d", ""); 1305. 	if (Wounded_legs 1306. #ifdef STEED  1307. 	    && !u.usteed  1308. #endif  1309. 			  ) { 1310. 		Sprintf(buf, "wounded %s", makeplural(body_part(LEG))); 1311. 		you_have(buf); 1312. 	} 1313. #if defined(WIZARD) && defined(STEED) 1314. 	if (Wounded_legs && u.usteed && wizard) { 1315. 	   Strcpy(buf, x_monnam(u.usteed, ARTICLE_YOUR, (char *)0, 1316. 		   SUPPRESS_SADDLE | SUPPRESS_HALLUCINATION, FALSE)); 1317. 	   *buf = highc(*buf); 1318. 	   enl_msg(buf, " has", " had", " wounded legs"); 1319. 	} 1320. #endif 1321. 	if (Sleeping) enl_msg("You ", "fall", "fell", " asleep"); 1322. 	if (Hunger) enl_msg("You hunger", "", "ed", " rapidly"); 1323. 1324. 	/*** Vision and senses ***/ 1325. 	if (See_invisible) enl_msg(You_, "see", "saw", " invisible"); 1326. 	if (Blind_telepat) you_are("telepathic"); 1327. 	if (Warning) you_are("warned"); 1328. 	if (Warn_of_mon && flags.warntype) { 1329. 	   /* [ALI] Add support for undead */ 1330. 	   int i, nth = 0; 1331. 	   unsigned long warntype = flags.warntype; 1332. 	   struct { unsigned long mask; const char *str; } warntypes[] = { 1333. 		M2_ORC,		"orcs", 1334. 		M2_DEMON,	"demons", 1335. 		M2_UNDEAD,	"undead", 1336. 	   };  1337.  1338. 	    Sprintf(buf, "aware of the presence of "); 1339. 	   for(i = 0; i < SIZE(warntypes); i++) 1340. 	   {  1341. 		if (warntype & warntypes[i].mask) { 1342. 		   warntype &= ~warntypes[i].mask; 1343. 		   if (nth) { 1344. 			if (warntype) 1345. 			   strcat(buf, ", "); 1346. 			else 1347. 			   strcat(buf, " and "); 1348. 		   }  1349. 		    else 1350. 			nth = 1; 1351. 		   strcat(buf, warntypes[i].str); 1352. 		} 1353. 	    }  1354. 	    if (warntype) 1355. 	   {  1356. 		if (nth) 1357. 		   strcat(buf, " and "); 1358. 		strcat(buf, something); 1359. 	   }  1360. 		you_are(buf); 1361. 	} 1362. #if 0	/* ALI - dealt with under Warn_of_mon */ 1363. 	if (Undead_warning) you_are("warned of undead"); 1364. #endif 1365. 	if (Searching) you_have("automatic searching"); 1366. 	if (Clairvoyant) you_are("clairvoyant"); 1367. 	if (Infravision) you_have("infravision"); 1368. 	if (Detect_monsters) you_are("sensing the presence of monsters"); 1369. 	if (u.umconf) you_are("going to confuse monsters"); 1370. 1371. 	/*** Appearance and behavior ***/ 1372. 	if (Adornment) { 1373. 	   int adorn = 0; 1374. 1375. 	    if(uleft && uleft->otyp == RIN_ADORNMENT) adorn += uleft->spe; 1376. 	   if(uright && uright->otyp == RIN_ADORNMENT) adorn += uright->spe; 1377. 	   if (adorn < 0) 1378. 		you_are("poorly adorned"); 1379. 	   else 1380. 		you_are("adorned"); 1381. 	} 1382. 	if (Invisible) you_are("invisible"); 1383. 	else if (Invis) you_are("invisible to others"); 1384. 	/* ordinarily "visible" is redundant; this is a special case for 1385. 	  the situation when invisibility would be an expected attribute */ 1386. 	else if ((HInvis || EInvis || pm_invisible(youmonst.data)) && BInvis) 1387. 	   you_are("visible"); 1388. 	if (Displaced) you_are("displaced"); 1389. 	if (Stealth) you_are("stealthy"); 1390. 	if (Aggravate_monster) enl_msg("You aggravate", "", "d", " monsters"); 1391. 	if (Conflict) enl_msg("You cause", "", "d", " conflict"); 1392. 1393. 	/*** Transportation ***/ 1394. 	if (Jumping) you_can("jump"); 1395. 	if (Teleportation) you_can("teleport"); 1396. 	if (Teleport_control) you_have("teleport control"); 1397. 	if (Lev_at_will) you_are("levitating, at will"); 1398. 	else if (Levitation) you_are("levitating");	/* without control */ 1399. 	else if (Flying) you_can("fly"); 1400. 	if (Wwalking) you_can("walk on water"); 1401. 	if (Swimming) you_can("swim"); 1402. 	if (Breathless) you_can("survive without air"); 1403. 	else if (Amphibious) you_can("breathe water"); 1404. 	if (Passes_walls) you_can("walk through walls"); 1405. #ifdef STEED 1406. 	/* If you die while dismounting, u.usteed is still set. Since several 1407. 	 * places in the done sequence depend on u.usteed, just detect this 1408. 	 * special case. */ 1409. 	if (u.usteed && (final < 2 || strcmp(killer, "riding accident"))) { 1410. 	   Sprintf(buf, "riding %s", y_monnam(u.usteed)); 1411. 	   you_are(buf); 1412. 	} 1413. #endif 1414. 	if (u.uswallow) { 1415. 	   Sprintf(buf, "swallowed by %s", a_monnam(u.ustuck)); 1416. #ifdef WIZARD 1417. 	   if (wizard) Sprintf(eos(buf), " (%u)", u.uswldtim); 1418. #endif 1419. 	   you_are(buf); 1420. 	} else if (u.ustuck) { 1421. 	   Sprintf(buf, "%s %s",  1422. 		    (Upolyd && sticks(youmonst.data)) ? "holding" : "held by",  1423. 		    a_monnam(u.ustuck)); 1424. 	   you_are(buf); 1425. 	} 1426.  1427. 	/*** Physical attributes ***/ 1428. 	if (u.uhitinc) 1429. 	   you_have(enlght_combatinc("to hit", u.uhitinc, final, buf)); 1430. 	if (u.udaminc) 1431. 	   you_have(enlght_combatinc("damage", u.udaminc, final, buf)); 1432. 	if (Slow_digestion) you_have("slower digestion"); 1433. 	if (Regeneration) enl_msg("You regenerate", "", "d", ""); 1434. 	if (u.uspellprot || Protection) { 1435. 	   int prot = 0; 1436. 1437. 	    if(uleft && uleft->otyp == RIN_PROTECTION) prot += uleft->spe; 1438. 	   if(uright && uright->otyp == RIN_PROTECTION) prot += uright->spe; 1439. 	   if (HProtection & INTRINSIC) prot += u.ublessed; 1440. 	   prot += u.uspellprot; 1441. 1442. 	    if (prot < 0) 1443. 		you_are("ineffectively protected"); 1444. 	   else 1445. 		you_are("protected"); 1446. 	} 1447. 	if (Protection_from_shape_changers) 1448. 		you_are("protected from shape changers"); 1449. 	if (Polymorph) you_are("polymorphing"); 1450. 	if (Polymorph_control) you_have("polymorph control"); 1451. 	if (u.ulycn >= LOW_PM) { 1452. 		Strcpy(buf, an(mons[u.ulycn].mname)); 1453. 		you_are(buf); 1454. 	} 1455. 	if (Upolyd) { 1456. 	   if (u.umonnum == u.ulycn) Strcpy(buf, "in beast form"); 1457. 	   else Sprintf(buf, "polymorphed into %s", an(youmonst.data->mname)); 1458. #ifdef WIZARD 1459. 	   if (wizard) Sprintf(eos(buf), " (%d)", u.mtimedone); 1460. #endif 1461. 	   you_are(buf); 1462. 	} 1463. 	if (Unchanging) you_can("not change from your current form"); 1464. 	if (Fast) you_are(Very_fast ? "very fast" : "fast"); 1465. 	if (Reflecting) you_have("reflection"); 1466. 	if (Free_action) you_have("free action"); 1467. 	if (Fixed_abil) you_have("fixed abilities"); 1468. 	if (uamul && uamul->otyp == AMULET_VERSUS_STONE) 1469. 		enl_msg("You ", "will be", "would have been", " depetrified"); 1470. 	if (Lifesaved) 1471. 		enl_msg("Your life ", "will be", "would have been", " saved"); 1472. 	if (u.twoweap) { 1473. 	   if (uwep && uswapwep) 1474. 		Sprintf(buf, "wielding two weapons at once"); 1475. 	   else if (uwep || uswapwep) 1476. 		Sprintf(buf, "fighting with a weapon and your %s %s", 1477. 			uwep ? "left" : "right", body_part(HAND)); 1478. 	   else 1479. 		Sprintf(buf, "fighting with two %s", 1480. 			makeplural(body_part(HAND))); 1481. 	   you_are(buf); 1482. 	} 1483.  1484. 	/*** Miscellany ***/ 1485. 	if (Luck) { 1486. 	   ltmp = abs((int)Luck); 1487. 	   Sprintf(buf, "%s%slucky",  1488. 		    ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "",  1489. 		    Luck < 0 ? "un" : ""); 1490. #ifdef WIZARD 1491. 	   if (wizard) Sprintf(eos(buf), " (%d)", Luck); 1492. #endif 1493. 	   you_are(buf); 1494. 	} 1495. #ifdef WIZARD 1496. 	 else if (wizard) enl_msg("Your luck ", "is", "was", " zero"); 1497. #endif 1498. 	if (u.moreluck > 0) you_have("extra luck"); 1499. 	else if (u.moreluck < 0) you_have("reduced luck"); 1500. 	if (carrying(LUCKSTONE) || stone_luck(TRUE)) { 1501. 	   ltmp = stone_luck(FALSE); 1502. 	   if (ltmp <= 0) 1503. 		enl_msg("Bad luck ", "does", "did", " not time out for you"); 1504. 	   if (ltmp >= 0) 1505. 		enl_msg("Good luck ", "does", "did", " not time out for you"); 1506. 	} 1507.  1508. 	/* KMH, balance patch -- healthstones affect health */ 1509. 	if (u.uhealbonus) 1510. 	{ 1511. 		Sprintf(buf, "%s health", u.uhealbonus > 0 ? "extra" :  1512. 			"reduced"); 1513. #ifdef WIZARD 1514. 	   if (wizard) Sprintf(eos(buf), " (%d)", u.uhealbonus); 1515. #endif 1516. 		you_have(buf); 1517. 	} 1518. #ifdef WIZARD 1519. 	 else if (wizard) enl_msg("Your health bonus ", "is", "was", " zero"); 1520. #endif 1521. 1522. 	if (u.ugangr) { 1523. 	   Sprintf(buf, " %sangry with you",  1524. 		    u.ugangr > 6 ? "extremely " : u.ugangr > 3 ? "very " : ""); 1525. #ifdef WIZARD 1526. 	   if (wizard) Sprintf(eos(buf), " (%d)", u.ugangr); 1527. #endif 1528. 	   enl_msg(u_gname, " is", " was", buf); 1529. 	} else 1530. 	   /*  1531. 	     * We need to suppress this when the game is over, because death 1532. 	    * can change the value calculated by can_pray, potentially 1533. 	    * resulting in a false claim that you could have prayed safely. 1534. 	    */  1535. 	  if (!final) { 1536. #if 0 1537. 	   /* "can [not] safely pray" vs "could [not] have safely prayed" */ 1538. 	   Sprintf(buf, "%s%ssafely pray%s", can_pray(FALSE) ? "" : "not ",  1539. 		    final ? "have " : "", final ? "ed" : ""); 1540. #else 1541. 	   Sprintf(buf, "%ssafely pray", can_pray(FALSE) ? "" : "not "); 1542. #endif 1543. #ifdef WIZARD 1544. 	   if (wizard) Sprintf(eos(buf), " (%d)", u.ublesscnt); 1545. #endif 1546. 	   you_can(buf); 1547. #if 0	/* WAC -- replaced by techniques */ 1548. /*	   Sprintf(buf, "%s%suse%s your special", !u.unextuse ? "" : "not ",  1549. 		    final ? "have " : "", final ? "d" : "");*/ 1550. 	   Sprintf(buf, "%suse your special", !u.unextuse ? "" : "not "); 1551. #ifdef WIZARD 1552. 	   if (wizard) Sprintf(eos(buf), " (%d)", u.unextuse); 1553. #endif 1554. 	   you_can(buf); 1555. #endif 1556. 	} 1557.  1558.     {  1559. 	const char *p; 1560. 1561. 	buf[0] = '\0'; 1562. 	if (final < 2) {   /* still in progress, or quit/escaped/ascended */ 1563. 	   p = "survived after being killed "; 1564. 	   switch (u.umortality) { 1565. 	   case 0:  p = !final ? (char *)0 : "survived"; break; 1566. 	   case 1:  Strcpy(buf, "once");  break; 1567. 	   case 2:  Strcpy(buf, "twice");  break; 1568. 	   case 3:  Strcpy(buf, "thrice");  break; 1569. 	   default: Sprintf(buf, "%d times", u.umortality); 1570. 		    break; 1571. 	   }  1572. 	} else {		/* game ended in character's death */ 1573. 	   p = "are dead"; 1574. 	   switch (u.umortality) { 1575. 	   case 0:  impossible("dead without dying?"); 1576. 	   case 1:  break;			/* just "are dead" */ 1577. 	   default: Sprintf(buf, " (%d%s time!)", u.umortality,  1578. 			     ordin(u.umortality)); 1579. 		    break; 1580. 	   }  1581. 	}  1582. 	if (p) enl_msg(You_, "have been killed ", p, buf); 1583.    }  1584.  1585. 	display_nhwindow(en_win, TRUE); 1586. 	destroy_nhwindow(en_win); 1587. 	return; 1588. } 1589.  1590. /*  1591.  * Courtesy function for non-debug, non-explorer mode players 1592. * to help refresh them about who/what they are. 1593. * Returns FALSE if menu cancelled (dismissed with ESC), TRUE otherwise. 1594. */  1595. STATIC_OVL boolean 1596. minimal_enlightenment 1597. { 1598. 	winid tmpwin; 1599. 	menu_item *selected; 1600. 	anything any; 1601. 	int genidx, n; 1602. char buf[BUFSZ], buf2[BUFSZ]; 1603. 	static const char untabbed_fmtstr[] = "%-15s: %-12s"; 1604. 	static const char untabbed_deity_fmtstr[] = "%-17s%s"; 1605. 	static const char tabbed_fmtstr[] = "%s:\t%-12s"; 1606. 	static const char tabbed_deity_fmtstr[] = "%s\t%s"; 1607. 	static const char *fmtstr; 1608. 	static const char *deity_fmtstr; 1609. 1610. 	fmtstr = iflags.menu_tab_sep ? tabbed_fmtstr : untabbed_fmtstr; 1611. 	deity_fmtstr = iflags.menu_tab_sep ? 1612. 			tabbed_deity_fmtstr : untabbed_deity_fmtstr; 1613. 	any.a_void = 0; 1614. 	buf[0] = buf2[0] = '\0'; 1615. 	tmpwin = create_nhwindow(NHW_MENU); 1616. 	start_menu(tmpwin); 1617. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings, "Starting", FALSE); 1618. 1619. 	/* Starting name, race, role, gender */ 1620. 	Sprintf(buf, fmtstr, "name", plname); 1621. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1622. 	Sprintf(buf, fmtstr, "race", urace.noun); 1623. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1624. 	Sprintf(buf, fmtstr, "role", 1625. 		(flags.initgend && urole.name.f) ? urole.name.f : urole.name.m); 1626. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1627. 	Sprintf(buf, fmtstr, "gender", genders[flags.initgend].adj); 1628. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1629. 1630. 	/* Starting alignment */ 1631. 	Sprintf(buf, fmtstr, "alignment", align_str(u.ualignbase[A_ORIGINAL])); 1632. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1633. 1634. 	/* Current name, race, role, gender */ 1635. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE); 1636. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings, "Current", FALSE); 1637. 	Sprintf(buf, fmtstr, "race", Upolyd ? youmonst.data->mname : urace.noun); 1638. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1639. 	if (Upolyd) { 1640. 	   Sprintf(buf, fmtstr, "role (base)",  1641. 		(u.mfemale && urole.name.f) ? urole.name.f : urole.name.m); 1642. 	   add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1643. 	} else { 1644. 	   Sprintf(buf, fmtstr, "role",  1645. 		(flags.female && urole.name.f) ? urole.name.f : urole.name.m); 1646. 	   add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1647. 	} 1648. 	/* don't want poly_gender here; it forces `2' for non-humanoids */ 1649. 	genidx = is_neuter(youmonst.data) ? 2 : flags.female; 1650. 	Sprintf(buf, fmtstr, "gender", genders[genidx].adj); 1651. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1652. 	if (Upolyd && (int)u.mfemale != genidx) { 1653. 	   Sprintf(buf, fmtstr, "gender (base)", genders[u.mfemale].adj); 1654. 	   add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1655. 	} 1656.  1657. 	/* Current alignment */ 1658. 	Sprintf(buf, fmtstr, "alignment", align_str(u.ualign.type)); 1659. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1660. 1661. 	/* Deity list */ 1662. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, "", FALSE); 1663. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, iflags.menu_headings, "Deities", FALSE); 1664. 	Sprintf(buf2, deity_fmtstr, align_gname(A_CHAOTIC), 1665. 	    (u.ualignbase[A_ORIGINAL] == u.ualign.type 1666. 		&& u.ualign.type == A_CHAOTIC) ? " (s,c)" : 1667. 	    (u.ualignbase[A_ORIGINAL] == A_CHAOTIC)       ? " (s)" :  1668. 	    (u.ualign.type   == A_CHAOTIC)       ? " (c)" : ""); 1669. 	Sprintf(buf, fmtstr, "Chaotic", buf2); 1670. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1671. 1672. 	Sprintf(buf2, deity_fmtstr, align_gname(A_NEUTRAL),  1673. 	    (u.ualignbase[A_ORIGINAL] == u.ualign.type 1674. 		&& u.ualign.type == A_NEUTRAL) ? " (s,c)" : 1675. 	    (u.ualignbase[A_ORIGINAL] == A_NEUTRAL)       ? " (s)" :  1676. 	    (u.ualign.type   == A_NEUTRAL)       ? " (c)" : ""); 1677. 	Sprintf(buf, fmtstr, "Neutral", buf2); 1678. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1679. 1680. 	Sprintf(buf2, deity_fmtstr, align_gname(A_LAWFUL),  1681. 	    (u.ualignbase[A_ORIGINAL] == u.ualign.type && 1682. 		u.ualign.type == A_LAWFUL) ? " (s,c)" :  1683. 	    (u.ualignbase[A_ORIGINAL] == A_LAWFUL)        ? " (s)" :  1684. 	    (u.ualign.type   == A_LAWFUL)        ? " (c)" : ""); 1685. 	Sprintf(buf, fmtstr, "Lawful", buf2); 1686. 	add_menu(tmpwin, NO_GLYPH, &any, 0, 0, ATR_NONE, buf, FALSE); 1687. 1688. 	end_menu(tmpwin, "Base Attributes"); 1689. 	n = select_menu(tmpwin, PICK_NONE, &selected); 1690. 	destroy_nhwindow(tmpwin); 1691. 	return (n != -1); 1692. } 1693.  1694. STATIC_PTR int 1695. doattributes 1696. { 1697. 	if (!minimal_enlightenment) 1698. 		return 0; 1699. 	if (wizard || discover) 1700. 		enlightenment(0); 1701. 	return 0; 1702. } 1703.  1704. static const struct menu_tab game_menu[] = { 1705. 	{'O', TRUE, doset, "Options"}, 1706. 	{'r', TRUE, doredraw, "Redraw Screen"}, 1707. 	{'x', TRUE, enter_explore_mode, "Enter Explore Mode"}, 1708. #ifdef SHELL 1709. 	{'!', TRUE, dosh, "Jump to Shell"}, 1710. #endif 1711. 	{'S', TRUE, dosave, "Save"}, 1712. 	{'q', TRUE, done2, "Quit [M-q]"}, 1713. 	{0,0,0,0}, 1714. };  1715.  1716. static const struct menu_tab inv_menu[] = { 1717. 	{(char)0, TRUE, (void *)0, "View Inventory"}, 1718. 	{'i', TRUE, ddoinv, "Inventory List"}, 1719. 	{'I', TRUE, dotypeinv, "Inventory List by Type"}, 1720. 	{'*', TRUE, doprinuse, "Items in use"}, 1721. 	{(char)0, TRUE, (void *)0, "Ready Items"}, 1722. 	{'w', FALSE, dowield, "Wield Weapon"}, 1723. 	{'W', FALSE, dowear, "Wear Protective Gear"}, 1724. 	{'Q', FALSE, dowieldquiver, "Prepare missile weapon (in Quiver)"}, 1725. 	{'T', FALSE, dotakeoff, "Take off Protective Gear"}, 1726. 	{(char)0, TRUE, (void *)0, "Manipulate Items"}, 1727. 	{'a', FALSE, doapply, "Apply an object"}, 1728. 	{'d', FALSE, dodip, "Dip an object [M-d]"}, 1729. 	{'E', FALSE, doengrave, "Engrave into the ground"}, 1730. 	{'f', FALSE, dofire, "Fire your prepared missile weapon"}, 1731. 	{'i', TRUE, doinvoke, "Invoke your weapon"}, 1732. 	{'t', FALSE, dothrow, "Throw an item"}, 1733. 	{(char)0, TRUE, (void *)0, "Drop Items"}, 1734. 	{'d', FALSE, dodrop, "Drop an object"}, 1735. 	{'D', FALSE, doddrop, "Multi-Drop"}, 1736. 	{0,0,0,0} 1737. };  1738.  1739. static const struct menu_tab action_menu[] = { 1740. 	{'c', FALSE, doclose, "Close a door"}, 1741. 	{'e', FALSE, doeat, "Eat some food"}, 1742. 	{'f', FALSE, doforce, "Force a lock [M-f]"}, 1743. 	{'l', FALSE, doloot, "Loot an object"}, 1744. 	{'o', FALSE, doopen, "Open a door"}, 1745. 	{'q', TRUE, dodrink, "Quaff a potion"}, 1746. 	{'r', FALSE, doread, "Read an object"}, 1747. 	{'u', FALSE, dountrap, "Untrap"}, 1748. 	{'z', FALSE, dozap, "Zap a wand"}, 1749. 	{'Z', TRUE, docast, "Cast a spell"}, 1750. 	{0,0,0,0} 1751. };  1752.  1753. static const struct menu_tab player_menu[] = { 1754. 	{'b', FALSE, playersteal, "Steal from Monsters [M-b]"}, 1755. 	{'c', TRUE, dotalk, "Chat with Monsters [M-c]"}, 1756. 	{'d', FALSE, dokick, "Do Kick"}, 1757. 	/*       {'e', FALSE, specialpower, "Use your Class Ability [M-e]"},*/ 1758. 	{'e', TRUE, enhance_weapon_skill, "Weapon Skills [M-k]"}, 1759. 	{'m', TRUE, domonability, "Use your Monster Ability [M-m]"}, 1760. 	{'o', FALSE, dosacrifice, "Offer a Sacrifice [M-o]"}, 1761. 	{'p', FALSE, dopay, "Pay the Shopkeeper"}, 1762. 	{'s', FALSE, dosit, "Sit down [M-s]"}, 1763. 	{'t', TRUE, dotele, "Controlled Teleport [C-t]"}, 1764. /*	{'T', TRUE, doturn, "Turn Undead [M-t]"},*/ 1765. 	{'T', TRUE, dotech, "Use Techniques [M-t]"}, 1766. 	{'x', TRUE, doattributes, "Show attributes"}, 1767. 	{'y', TRUE, polyatwill, "Self-Polymorph [M-y]"}, 1768. 	{0,0,0,0} 1769. };  1770.  1771. #ifdef WIZARD 1772. static const struct menu_tab wizard_menu[] = { 1773. 	{'c', TRUE, wiz_gain_ac, "Increase AC"}, 1774. #ifdef DISPLAY_LAYERS 1775. 	{'d', TRUE, wiz_show_display, "Detail display layers"}, 1776. #endif 1777. 	{'e', TRUE, wiz_detect, "Detect secret doors and traps"}, 1778. 	{'f', TRUE, wiz_map, "Do magic mapping"}, 1779. 	{'g', TRUE, wiz_genesis, "Create monster"}, 1780. 	{'i', TRUE, wiz_identify, "Identify items in pack"}, 1781. 	{'j', TRUE, wiz_gain_level, "Go up an experience level"}, 1782. 	{'n', TRUE, wiz_toggle_invulnerability, "Toggle invulnerability"}, 1783. 	{'o', TRUE, wiz_where, "Tell locations of special levels"}, 1784. 	{'v', TRUE, wiz_level_tele, "Do trans-level teleport"}, 1785. 	{'w', TRUE, wiz_wish, "Make wish"}, 1786. 	{'L', TRUE, wiz_light_sources, "show mobile light sources"}, 1787. 	{'M', TRUE, wiz_show_stats, "show memory statistics"}, 1788. 	{'S', TRUE, wiz_show_seenv, "show seen vectors"}, 1789. 	{'T', TRUE, wiz_timeout_queue, "look at timeout queue"}, 1790. 	{'V', TRUE, wiz_show_vision, "show vision array"}, 1791. 	{'W', TRUE, wiz_show_wmodes, "show wall modes"}, 1792. #ifdef DEBUG 1793. 	{'&', TRUE, wiz_debug_cmd, "wizard debug command"}, 1794. #endif 1795. 	{0,0,0,0,0}, 1796. };  1797. #endif 1798. 1799. static const struct menu_tab help_menu[] = { 1800. 	{'?', TRUE, dohelp, "Help Contents"}, 1801. 	{'v', TRUE, doextversion, "Version"}, 1802. 	{'/', TRUE, dowhatis, "Identify an object on the screen" }, 1803. 	{'&', TRUE, dowhatdoes, "Determine what a key does"}, 1804. 	{0,0,0,0,0}, 1805. };  1806.  1807. static const struct menu_tab main_menu[] = { 1808. 	{'g', TRUE, (void *)0, "Game"}, 1809. 	{'i', TRUE, (void *)0, "Inventory"}, 1810. 	{'a', TRUE, (void *)0, "Action"}, 1811. 	{'p', TRUE, (void *)0, "Player"}, 1812. 	{'d', TRUE, (void *)0, "Discoveries"}, 1813. #ifdef WIZARD 1814. 	{'w', TRUE, (void *)0, "Wizard"}, 1815. #endif 1816. 	{'?', TRUE, (void *)0, "Help"}, 1817. 	{0,0,0,0}, 1818. };  1819.  1820. static const struct menu_tab discover_menu[] = { 1821. 	{'X', TRUE, dovspell, "View known spells"},                 /* Mike Stephenson */ 1822. 	{'d', TRUE, dodiscovered, "Items already discovered [\\]"},            /* Robert Viduya */ 1823. 	{'C', TRUE, do_mname, "Name a monster"}, 1824. 	{0,0,0,0}, 1825. };  1826.  1827. static struct menu_list main_menustruct[] = { 1828. 	{"Game", "Main Menu", game_menu}, 1829. 	{"Inventory", "Main Menu", inv_menu}, 1830. 	{"Action", "Main Menu", action_menu}, 1831. 	{"Player", "Main Menu", player_menu}, 1832. 	{"Discoveries", "Main Menu", discover_menu}, 1833. #ifdef WIZARD 1834. 	{"Wizard", "Main Menu", wizard_menu}, 1835. #endif 1836. 	{"Help", "Main Menu", help_menu}, 1837. 	{"Main Menu",(char *)0, main_menu}, 1838. 	{0,0,0}, 1839. };  1840.  1841. STATIC_PTR int 1842. makemenu(menuname, menu_struct) 1843. const char *menuname; 1844. struct menu_list menu_struct[]; 1845. { 1846. 	winid win; 1847. 	anything any; 1848. 	menu_item *selected; 1849.        int n, i, NDECL((*func)); 1850.        const struct menu_tab *current_menu; 1851. 1852. 	any.a_void = 0; 1853. 	win = create_nhwindow(NHW_MENU); 1854. 	start_menu(win); 1855. 1856.         for (i = 0; menu_struct[i].m_header; i++) { 1857.                if (strcmp(menu_struct[i].m_header,menuname)) continue; 1858.                current_menu = menu_struct[i].m_menu; 1859.                for (n = 0; current_menu[n].m_item; n++) { 1860.                        if (u.uburied && !current_menu[n].can_if_buried) continue; 1861. #ifdef WIZARD 1862. 			if (!wizard && !current_menu[n].m_funct && !strcmp(current_menu[n].m_item,"Wizard")) continue; 1863. #endif 1864.                        if (current_menu[n].m_char == (char)0) { 1865.                                any.a_int = 0; 1866.                                add_menu(win, NO_GLYPH, &any, 0, 0, ATR_BOLD,  1867.                                      current_menu[n].m_item, MENU_UNSELECTED); 1868.                                continue; 1869.                        }  1870.                         any.a_int = n + 1; /* non-zero */ 1871.                        add_menu(win, NO_GLYPH, &any, current_menu[n].m_char,  1872.                         0, ATR_NONE, current_menu[n].m_item, MENU_UNSELECTED); 1873.                }  1874.                 break; 1875.        }  1876.         end_menu(win, menuname); 1877.        n = select_menu(win, PICK_ONE, &selected); 1878.        destroy_nhwindow(win); 1879.        if (n > 0) { 1880.                /* we discard 'const' because some compilers seem to have 1881. 		      trouble with the pointer passed to set_occupation */ 1882.                i = selected[0].item.a_int - 1; 1883.                func = current_menu[i].m_funct; 1884.                if (current_menu[i].m_text && !occupation && multi) 1885.                      set_occupation(func, current_menu[i].m_text, multi); 1886.                /*WAC catch void into makemenu */ 1887.                if (func == (void *)0) 1888.                        return (makemenu(current_menu[i].m_item, menu_struct)); 1889.                else return (*func);            /* perform the command */ 1890.        } else if (n < 0) { 1891.                for (i = 0; menu_struct[i].m_header; i++){ 1892.                   if (menuname == menu_struct[i].m_header) { 1893.                    if (menu_struct[i].m_parent) 1894.                      return (makemenu(menu_struct[i].m_parent, menu_struct)); 1895.                    else return (0); 1896.                }  1897.         }  1898.         }  1899.         return 0; 1900. } 1901.  1902. STATIC_PTR int 1903. domenusystem /* WAC add helpful menus ;B */ 1904. { 1905.         return (makemenu("Main Menu", main_menustruct)); 1906. } 1907.  1908. /* KMH, #conduct 1909. * (shares enlightenment's tense handling) 1910. */  1911. STATIC_PTR int 1912. doconduct 1913. { 1914. 	show_conduct(0); 1915. 	return 0; 1916. } 1917.  1918. /* format increased damage or chance to hit */ 1919. static char * 1920. enlght_combatinc(inctyp, incamt, final, outbuf) 1921. const char *inctyp; 1922. int incamt, final; 1923. char *outbuf; 1924. { 1925. 	char numbuf[24]; 1926. 	const char *modif, *bonus; 1927. 1928. 	if (final  1929. #ifdef WIZARD  1930. 		|| wizard  1931. #endif  1932. 	  ) { 1933. 	   Sprintf(numbuf, "%s%d",  1934. 		    (incamt > 0) ? "+" : "", incamt); 1935. 	   modif = (const char *) numbuf; 1936. 	} else { 1937. 	   int absamt = abs(incamt); 1938. 1939. 	    if (absamt <= 3) modif = "small"; 1940. 	   else if (absamt <= 6) modif = "moderate"; 1941. 	   else if (absamt <= 12) modif = "large"; 1942. 	   else modif = "huge"; 1943. 	} 1944. 	bonus = (incamt > 0) ? "bonus" : "penalty"; 1945. 	/* "bonus to hit" vs "damage bonus" */ 1946. 	if (!strcmp(inctyp, "damage")) { 1947. 	   const char *ctmp = inctyp; 1948. 	   inctyp = bonus; 1949. 	   bonus = ctmp; 1950. 	} 1951. 	Sprintf(outbuf, "%s %s %s", an(modif), bonus, inctyp); 1952. 	return outbuf; 1953. } 1954.  1955. void 1956. show_conduct(final) 1957. int final; 1958. { 1959. 	char buf[BUFSZ]; 1960. 	int ngenocided; 1961. 1962. 	/* Create the conduct window */ 1963. 	en_win = create_nhwindow(NHW_MENU); 1964. 	putstr(en_win, 0, "Voluntary challenges:"); 1965. 	putstr(en_win, 0, ""); 1966. 1967. 	if (!u.uconduct.food && !u.uconduct.unvegan) 1968. 	   enl_msg(You_, "have gone", "went", " without food"); 1969. 	   /* But beverages are okay */ 1970. 	else if (!u.uconduct.food) 1971. 	   enl_msg(You_, "have gone", "went", " without eating"); 1972. 	   /* But quaffing animal products (eg., blood) is okay */ 1973. 	else if (!u.uconduct.unvegan) 1974. 	   you_have_X("followed a strict vegan diet"); 1975. 	else if (!u.uconduct.unvegetarian) 1976. 	   you_have_been("vegetarian"); 1977. 1978. 	if (!u.uconduct.gnostic) 1979. 	   you_have_been("an atheist"); 1980. 1981. 	if (!u.uconduct.weaphit) 1982. 	   you_have_never("hit with a wielded weapon"); 1983. #ifdef WIZARD 1984. 	else if (wizard) { 1985. 	   Sprintf(buf, "used a wielded weapon %ld time%s",  1986. 		    u.uconduct.weaphit, plur(u.uconduct.weaphit)); 1987. 	   you_have_X(buf); 1988. 	} 1989. #endif 1990. 	if (!u.uconduct.killer) 1991. 	   you_have_been("a pacifist"); 1992. 1993. 	if (!u.uconduct.literate) 1994. 	   you_have_been("illiterate"); 1995. #ifdef WIZARD 1996. 	else if (wizard) { 1997. 	   Sprintf(buf, "read items or engraved %ld time%s",  1998. 		    u.uconduct.literate, plur(u.uconduct.literate)); 1999. 	   you_have_X(buf); 2000. 	} 2001. #endif 2002. 2003. 	ngenocided = num_genocides; 2004. 	if (ngenocided == 0) { 2005. 	   you_have_never("genocided any monsters"); 2006. 	} else { 2007. 	   Sprintf(buf, "genocided %d type%s of monster%s",  2008. 		    ngenocided, plur(ngenocided), plur(ngenocided)); 2009. 	   you_have_X(buf); 2010. 	} 2011.  2012. 	if (!u.uconduct.polypiles) 2013. 	   you_have_never("polymorphed an object"); 2014. #ifdef WIZARD 2015. 	else if (wizard) { 2016. 	   Sprintf(buf, "polymorphed %ld item%s",  2017. 		    u.uconduct.polypiles, plur(u.uconduct.polypiles)); 2018. 	   you_have_X(buf); 2019. 	} 2020. #endif 2021. 2022. 	if (!u.uconduct.polyselfs) 2023. 	   you_have_never("changed form"); 2024. #ifdef WIZARD 2025. 	else if (wizard) { 2026. 	   Sprintf(buf, "changed form %ld time%s",  2027. 		    u.uconduct.polyselfs, plur(u.uconduct.polyselfs)); 2028. 	   you_have_X(buf); 2029. 	} 2030. #endif 2031. 2032. 	if (!u.uconduct.wishes) 2033. 	   you_have_X("used no wishes"); 2034. 	else { 2035. 	   Sprintf(buf, "used %ld wish%s",  2036. 		    u.uconduct.wishes, (u.uconduct.wishes > 1L) ? "es" : ""); 2037. 	   you_have_X(buf); 2038. 2039. 	    if (!u.uconduct.wisharti) 2040. 		enl_msg(You_, "have not wished", "did not wish", 2041. 			" for any artifacts"); 2042. 	} 2043.  2044.  2045. 	if (!u.uconduct.celibacy) 2046. 		you_have_X("remained celibate"); 2047. #ifdef WIZARD 2048. 	else if (wizard) { 2049. 		Sprintf(buf, "broken your vow of celibacy %ld time%s.", 2050. 			u.uconduct.celibacy, u.uconduct.celibacy > 1 ? "s" : ""); 2051. 		you_have_X(buf); 2052. 	} 2053. #endif 2054. 2055. 	/* Pop up the window and wait for a key */ 2056. 	display_nhwindow(en_win, TRUE); 2057. 	destroy_nhwindow(en_win); 2058. } 2059.  2060. #endif /* OVLB */ 2061. #ifdef OVL1 2062. 2063. #ifndef M  2064. # ifndef NHSTDC 2065. # define M(c)		(0x80 | (c)) 2066. # else 2067. # define M(c)		((c) - 128) 2068. # endif /* NHSTDC */ 2069. #endif 2070. #ifndef C 2071. #define C(c)		(0x1f & (c)) 2072. #endif 2073. 2074. static const struct func_tab cmdlist[] = { 2075. 	{C('d'), FALSE, dokick}, /* "D" is for door!...? Msg is in dokick.c */ 2076. #ifdef WIZARD 2077. 	{C('b'), FALSE, playersteal}, 2078. /* BEGIN TSANTH'S CODE */ 2079. 	{C('c'), TRUE, wiz_gain_ac}, 2080. /* END TSANTH'S CODE */ 2081. 	{C('e'), TRUE, wiz_detect}, 2082. 	{C('f'), TRUE, wiz_map}, 2083. 	{C('g'), TRUE, wiz_genesis}, 2084. 	{C('i'), TRUE, wiz_identify}, 2085. 	{C('j'), TRUE, wiz_gain_level}, 2086. #endif 2087. 	{C('l'), TRUE, doredraw}, /* if number_pad is set */ 2088. #ifdef WIZARD 2089. /* BEGIN TSANTH'S CODE */ 2090. 	{C('n'), TRUE, wiz_toggle_invulnerability}, 2091. /* END TSANTH'S CODE */ 2092. 	{C('o'), TRUE, wiz_where}, 2093. #endif 2094. 	{C('p'), TRUE, doprev_message}, 2095. 	{C('q'), TRUE, done2}, 2096. 	{C('r'), TRUE, doredraw}, 2097. /*	{C('s'), FALSE, specialpower},*/ 2098. 	{C('s'), TRUE, dosave}, 2099. 	{C('t'), TRUE, dotele}, 2100. #ifdef WIZARD 2101. 	{C('v'), TRUE, wiz_level_tele}, 2102. 	{C('w'), TRUE, wiz_wish}, 2103. #endif 2104. 	{C('x'), TRUE, doattributes}, 2105. 	{C('y'), TRUE, polyatwill}, 2106. #ifdef SUSPEND 2107. 	{C('z'), TRUE, dosuspend}, 2108. #endif 2109. 	{'a', FALSE, doapply}, 2110. 	{'A', FALSE, doddoremarm}, 2111. 	{M('a'), TRUE, doorganize}, 2112. /*	'b', 'B' : go sw */ 2113. #ifdef BORG 2114. 	{'B', TRUE, doborgtoggle}, /* [Tom] */ 2115. #endif 2116. 	{M('b'), FALSE, playersteal},  /* jla */ 2117. #if 0 2118. 	{M('b'), FALSE, specialpower},  /* jla */ 2119. #endif 2120. 	{'c', FALSE, doclose}, 2121. 	{'C', TRUE, do_mname}, 2122. 	{M('c'), TRUE, dotalk}, 2123. 	{'d', FALSE, dodrop}, 2124. 	{'D', FALSE, doddrop}, 2125. 	{M('d'), FALSE, dodip}, 2126. 	{'e', FALSE, doeat}, 2127. 	{'E', FALSE, doengrave}, 2128. 	{M('e'), TRUE, enhance_weapon_skill}, 2129. 	{'f', FALSE, dofire}, 2130. /*	'F' : fight (one time) */ 2131. 	{M('f'), FALSE, doforce}, 2132. /*	'g', 'G' : multiple go */ 2133. /*	'h', 'H' : go west */ 2134. 	{'h', TRUE, dohelp}, /* if number_pad is set */ 2135. 	{'i', TRUE, ddoinv}, 2136. 	{'I', TRUE, dotypeinv},		/* Robert Viduya */ 2137. 	{M('i'), TRUE, doinvoke}, 2138. /*	'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */ 2139. 	{'j', FALSE, dojump}, /* if number_pad is on */ 2140. 	{M('j'), FALSE, dojump}, 2141. 	{'k', FALSE, dokick}, /* if number_pad is on */ 2142. 	{'K', TRUE, dolistvanq}, /* if number_pad is on */ 2143. 	{M('k'), TRUE, enhance_weapon_skill}, 2144. 	{'l', FALSE, doloot}, /* if number_pad is on */ 2145. 	{M('l'), FALSE, doloot}, 2146. /*	'n' prefixes a count if number_pad is on */ 2147. 	{M('m'), TRUE, domonability}, 2148. 	{'N', TRUE, ddocall}, /* if number_pad is on */ 2149. 	{M('n'), TRUE, ddocall}, 2150. 	{'o', FALSE, doopen}, 2151. 	{'O', TRUE, doset}, 2152. 	{M('o'), FALSE, dosacrifice}, 2153. 	{'p', FALSE, dopay}, 2154. /*WAC replace with dowear*/ 2155. 	{'P', FALSE, doputon}, 2156. 	{M('p'), TRUE, dopray}, 2157. 	{'q', FALSE, dodrink}, 2158. 	{'Q', FALSE, dowieldquiver}, 2159. 	{M('q'), TRUE, done2}, 2160. 	{'r', FALSE, doread}, 2161. 	{'R', FALSE, doremring}, 2162. 	{M('r'), FALSE, dorub}, 2163. 	{'s', TRUE, dosearch, "searching"}, 2164. 	{'S', TRUE, dosave}, 2165. 	{M('s'), FALSE, dosit}, 2166. 	{'t', FALSE, dothrow}, 2167. 	{'T', FALSE, dotakeoff}, 2168. /*	{M('t'), TRUE, doturn},*/ 2169. 	{M('t'), TRUE, dotech}, 2170. /*	'u', 'U' : go ne */ 2171. 	{'u', FALSE, dountrap}, /* if number_pad is on */ 2172. 	{M('u'), FALSE, dountrap}, 2173. 	{'v', TRUE, doversion}, 2174. 	{'V', TRUE, dohistory}, 2175. 	{M('v'), TRUE, doextversion}, 2176. /*replaced with dowear*/ 2177. 	{'w', FALSE, dowield}, 2178. 	{'W', FALSE, dowear}, 2179. 	{M('w'), FALSE, dowipe}, 2180. 	{'x', FALSE, doswapweapon},                   /* [Tom] */ 2181. 	{'X', TRUE, enter_explore_mode}, 2182. #if 0 2183.        {M('x'), TRUE, dovspell},                  /* Mike Stephenson */ 2184. #endif 2185. /*	'y', 'Y' : go nw */ 2186. 	{M('y'), FALSE, polyatwill}, /* jla */ 2187. 	{'z', FALSE, dozap}, 2188. 	{'Z', TRUE, docast}, 2189. 	{'<', FALSE, doup}, 2190. 	{'>', FALSE, dodown}, 2191. 	{'/', TRUE, dowhatis}, 2192. 	{'&', TRUE, dowhatdoes}, 2193. 	{'?', TRUE, dohelp}, 2194. 	{M('?'), TRUE, doextlist}, 2195. #ifdef SHELL 2196. 	{'!', TRUE, dosh}, 2197. #endif 2198. 	{'.', TRUE, donull, "waiting"}, 2199. 	{' ', TRUE, donull, "waiting"}, 2200. 	{',', FALSE, dopickup}, 2201. 	{':', TRUE, dolook}, 2202. 	{';', TRUE, doquickwhatis}, 2203. 	{'^', TRUE, doidtrap}, 2204. 	{'\\', TRUE, dodiscovered},		/* Robert Viduya */ 2205. 	{'@', TRUE, dotogglepickup}, 2206. 	{M('2'), FALSE, dotwoweapon}, 2207. /* WAC Angband style items in use, menusystem 2208. 	{'*', TRUE, doinvinuse}, */ 2209. 	{'`', TRUE, domenusystem}, 2210. 	{'~', TRUE, domenusystem}, 2211. 	{WEAPON_SYM, TRUE, doprwep}, 2212. 	{ARMOR_SYM, TRUE, doprarm}, 2213. 	{RING_SYM, TRUE, doprring}, 2214. 	{AMULET_SYM, TRUE, dopramulet}, 2215. 	{TOOL_SYM, TRUE, doprtool}, 2216. 	{'*', TRUE, doprinuse},	/* inventory of all equipment in use */ 2217. 	{GOLD_SYM, TRUE, doprgold}, 2218. 	{SPBOOK_SYM, TRUE, dovspell},			/* Mike Stephenson */ 2219. 	{'#', TRUE, doextcmd}, 2220. 	{'_', TRUE, dotravel}, 2221. 	{0,0,0,0} 2222. };  2223.  2224. struct ext_func_tab extcmdlist[] = { 2225. 	{"2weapon", "toggle two-weapon combat", dotwoweapon, FALSE}, 2226. 	{"adjust", "adjust inventory letters", doorganize, TRUE}, 2227. 	{"borrow", "steal from monsters", playersteal, FALSE}, /* jla */ 2228. 	{"chat", "talk to someone", dotalk, TRUE},	/* converse? */ 2229. 	{"conduct", "list which challenges you have adhered to", doconduct, TRUE}, 2230. 	{"dip", "dip an object into something", dodip, FALSE}, 2231. 	{"enhance", "advance or check weapons skills", enhance_weapon_skill, 2232. 							TRUE}, 2233. #if 0 2234. 	{"ethics", "list which challenges you have adhered to", doethics, TRUE}, 2235. #endif 2236. 	{"explore", "enter explore mode", enter_explore_mode, TRUE}, 2237. 	{"force", "force a lock", doforce, FALSE}, 2238. 	{"invoke", "invoke an object's powers", doinvoke, TRUE}, 2239. 	{"jump", "jump to a location", dojump, FALSE}, 2240. 	{"loot", "loot a box on the floor", doloot, FALSE}, 2241. 	{"monster", "use a monster's special ability", domonability, TRUE}, 2242. 	{"name", "name an item or type of object", ddocall, TRUE}, 2243. 	{"offer", "offer a sacrifice to the gods", dosacrifice, FALSE}, 2244. 	{"pray", "pray to the gods for help", dopray, TRUE}, 2245. 	{"quit", "exit without saving current game", done2, TRUE}, 2246. #ifdef STEED 2247. 	{"ride", "ride (or stop riding) a monster", doride, FALSE}, 2248. #endif 2249. 	{"rub", "rub a lamp or a stone", dorub, FALSE}, 2250. 	{"sit", "sit down", dosit, FALSE}, 2251. #ifdef SHOUT 2252. 	{"shout", "say something loud", doyell, TRUE}, /* jrn */ 2253. #endif 2254. 	{"technique", "perform a technique", dotech, TRUE}, 2255. 	{"turn", "turn undead", doturn, TRUE}, 2256. 	{"twoweapon", "toggle two-weapon combat", dotwoweapon, FALSE}, 2257. 	{"untrap", "untrap something", dountrap, FALSE}, 2258. 	{"vanquished", "list vanquished monsters", dolistvanq, TRUE}, 2259. 	{"version", "list compile time options for this version of Slash'EM", 2260. 		doextversion, TRUE}, 2261. 	{"wipe", "wipe off your face", dowipe, FALSE}, 2262. 	{"youpoly", "polymorph at will", polyatwill, FALSE}, /* jla */ 2263. 	{"?", "get this list of extended commands", doextlist, TRUE}, 2264. #if defined(WIZARD) 2265. 	/* 2266. 	 * There must be a blank entry here for every entry in the table 2267. 	 * below. 2268. 	 */ 2269. #ifdef DISPLAY_LAYERS 2270. 	{(char *)0, (char *)0, donull, TRUE}, 2271. #endif 2272. 	{(char *)0, (char *)0, donull, TRUE}, 2273. 	{(char *)0, (char *)0, donull, TRUE}, 2274. #ifdef DEBUG_MIGRATING_MONS 2275. 	{(char *)0, (char *)0, donull, TRUE}, 2276. #endif 2277. 	{(char *)0, (char *)0, donull, TRUE}, 2278. 	{(char *)0, (char *)0, donull, TRUE}, 2279. #ifdef PORT_DEBUG 2280. 	{(char *)0, (char *)0, donull, TRUE}, 2281. #endif 2282. 	{(char *)0, (char *)0, donull, TRUE}, 2283. 	{(char *)0, (char *)0, donull, TRUE}, 2284.        {(char *)0, (char *)0, donull, TRUE}, 2285. 	{(char *)0, (char *)0, donull, TRUE}, 2286. 	{(char *)0, (char *)0, donull, TRUE}, 2287. #ifdef DEBUG 2288. 	{(char *)0, (char *)0, donull, TRUE}, 2289. #endif 2290. 	{(char *)0, (char *)0, donull, TRUE}, 2291. #endif 2292. 	{(char *)0, (char *)0, donull, TRUE}	/* sentinel */ 2293. }; 2294.  2295. #if defined(WIZARD) 2296. static const struct ext_func_tab debug_extcmdlist[] = { 2297. #ifdef DISPLAY_LAYERS 2298. 	{"display", "detail display layers", wiz_show_display, TRUE}, 2299. #endif 2300. 	{"levelchange", "change experience level", wiz_level_change, TRUE}, 2301. 	{"lightsources", "show mobile light sources", wiz_light_sources, TRUE}, 2302. #ifdef DEBUG_MIGRATING_MONS 2303. 	{"migratemons", "migrate n random monsters", wiz_migrate_mons, TRUE}, 2304. #endif 2305. 	{"monpolycontrol", "control monster polymorphs", wiz_mon_polycontrol, TRUE}, 2306. 	{"panic", "test panic routine (fatal to game)", wiz_panic, TRUE}, 2307. 	{"polyself", "polymorph self", wiz_polyself, TRUE}, 2308. #ifdef PORT_DEBUG 2309. 	{"portdebug", "wizard port debug command", wiz_port_debug, TRUE}, 2310. #endif 2311. 	{"seenv", "show seen vectors", wiz_show_seenv, TRUE}, 2312. 	{"stats", "show memory statistics", wiz_show_stats, TRUE}, 2313. 	{"timeout", "look at timeout queue", wiz_timeout_queue, TRUE}, 2314. 	{"vision", "show vision array", wiz_show_vision, TRUE}, 2315. #ifdef DEBUG 2316. 	{"wizdebug", "wizard debug command", wiz_debug_cmd, TRUE}, 2317. #endif 2318. 	{"wmode", "show wall modes", wiz_show_wmodes, TRUE}, 2319. 	{(char *)0, (char *)0, donull, TRUE} 2320. }; 2321.  2322. /*  2323.  * Insert debug commands into the extended command list. This function 2324. * assumes that the last entry will be the help entry. 2325. *  2326.  * You must add entries in ext_func_tab every time you add one to the 2327. * debug_extcmdlist. 2328. */  2329. void 2330. add_debug_extended_commands 2331. { 2332. 	int i, j, k, n;  2333. 2334. 	/* count the # of help entries */ 2335. 	for (n = 0; extcmdlist[n].ef_txt[0] != '?'; n++) 2336. 	   ;  2337.  2338. 	for (i = 0; debug_extcmdlist[i].ef_txt; i++) { 2339. 	   for (j = 0; j < n; j++) 2340. 		if (strcmp(debug_extcmdlist[i].ef_txt, extcmdlist[j].ef_txt) < 0) break; 2341. 2342. 	    /* insert i'th debug entry into extcmdlist[j], pushing down  */ 2343. 	   for (k = n; k >= j; --k) 2344. 		extcmdlist[k+1] = extcmdlist[k]; 2345. 	   extcmdlist[j] = debug_extcmdlist[i]; 2346. 	   n++;	/* now an extra entry */ 2347. 	} 2348. }  2349.  2350.  2351. static const char template[] = "%-18s %4ld  %6ld"; 2352. static const char count_str[] = "                  count  bytes"; 2353. static const char separator[] = "-- - --"; 2354. 2355. STATIC_OVL void 2356. count_obj(chain, total_count, total_size, top, recurse) 2357. 	struct obj *chain; 2358. 	long *total_count; 2359. 	long *total_size; 2360. 	boolean top; 2361. 	boolean recurse; 2362. { 2363. 	long count, size; 2364. 	struct obj *obj; 2365. 2366. 	for (count = size = 0, obj = chain; obj; obj = obj->nobj) { 2367. 	   if (top) { 2368. 		count++; 2369. 		size += sizeof(struct obj) + obj->oxlth + obj->onamelth; 2370. 	   }  2371. 	    if (recurse && obj->cobj) 2372. 		count_obj(obj->cobj, total_count, total_size, TRUE, TRUE); 2373. 	} 2374. 	*total_count += count; 2375. 	*total_size += size; 2376. } 2377.  2378. STATIC_OVL void 2379. obj_chain(win, src, chain, total_count, total_size) 2380. 	winid win; 2381. 	const char *src; 2382. 	struct obj *chain; 2383. 	long *total_count; 2384. 	long *total_size; 2385. { 2386. 	char buf[BUFSZ]; 2387. 	long count = 0, size = 0; 2388. 2389. 	count_obj(chain, &count, &size, TRUE, FALSE); 2390. 	*total_count += count; 2391. 	*total_size += size; 2392. 	Sprintf(buf, template, src, count, size); 2393. 	putstr(win, 0, buf); 2394. } 2395.  2396. STATIC_OVL void 2397. mon_invent_chain(win, src, chain, total_count, total_size) 2398. 	winid win; 2399. 	const char *src; 2400. 	struct monst *chain; 2401. 	long *total_count; 2402. 	long *total_size; 2403. { 2404. 	char buf[BUFSZ]; 2405. 	long count = 0, size = 0; 2406. 	struct monst *mon; 2407. 2408. 	for (mon = chain; mon; mon = mon->nmon) 2409. 	   count_obj(mon->minvent, &count, &size, TRUE, FALSE); 2410. 	*total_count += count; 2411. 	*total_size += size; 2412. 	Sprintf(buf, template, src, count, size); 2413. 	putstr(win, 0, buf); 2414. } 2415.  2416. STATIC_OVL void 2417. contained(win, src, total_count, total_size) 2418. 	winid win; 2419. 	const char *src; 2420. 	long *total_count; 2421. 	long *total_size; 2422. { 2423. 	char buf[BUFSZ]; 2424. 	long count = 0, size = 0; 2425. 	struct monst *mon; 2426. 2427. 	count_obj(invent, &count, &size, FALSE, TRUE); 2428. 	count_obj(fobj, &count, &size, FALSE, TRUE); 2429. 	count_obj(level.buriedobjlist, &count, &size, FALSE, TRUE); 2430. 	count_obj(migrating_objs, &count, &size, FALSE, TRUE); 2431. 	/* DEADMONSTER check not required in this loop since they have no inventory */ 2432. 	for (mon = fmon; mon; mon = mon->nmon) 2433. 	   count_obj(mon->minvent, &count, &size, FALSE, TRUE); 2434. 	for (mon = migrating_mons; mon; mon = mon->nmon) 2435. 	   count_obj(mon->minvent, &count, &size, FALSE, TRUE); 2436. 2437. 	*total_count += count; *total_size += size; 2438. 2439. 	Sprintf(buf, template, src, count, size); 2440. 	putstr(win, 0, buf); 2441. } 2442.  2443. STATIC_OVL void 2444. mon_chain(win, src, chain, total_count, total_size) 2445. 	winid win; 2446. 	const char *src; 2447. 	struct monst *chain; 2448. 	long *total_count; 2449. 	long *total_size; 2450. { 2451. 	char buf[BUFSZ]; 2452. 	long count, size; 2453. 	struct monst *mon; 2454. 2455. 	for (count = size = 0, mon = chain; mon; mon = mon->nmon) { 2456. 	   count++; 2457. 	   size += sizeof(struct monst) + mon->mxlth + mon->mnamelth; 2458. 	} 2459. 	*total_count += count; 2460. 	*total_size += size; 2461. 	Sprintf(buf, template, src, count, size); 2462. 	putstr(win, 0, buf); 2463. } 2464.  2465. /*  2466.  * Display memory usage of all monsters and objects on the level. 2467. */  2468. static int 2469. wiz_show_stats 2470. { 2471. 	char buf[BUFSZ]; 2472. 	winid win; 2473. 	long total_obj_size = 0, total_obj_count = 0; 2474. 	long total_mon_size = 0, total_mon_count = 0; 2475. 2476. 	win = create_nhwindow(NHW_TEXT); 2477. 	putstr(win, 0, "Current memory statistics:"); 2478. 	putstr(win, 0, ""); 2479. 	Sprintf(buf, "Objects, size %d", (int) sizeof(struct obj)); 2480. 	putstr(win, 0, buf); 2481. 	putstr(win, 0, ""); 2482. 	putstr(win, 0, count_str); 2483. 2484. 	obj_chain(win, "invent", invent, &total_obj_count, &total_obj_size); 2485. 	obj_chain(win, "fobj", fobj, &total_obj_count, &total_obj_size); 2486. 	obj_chain(win, "buried", level.buriedobjlist, 2487. 				&total_obj_count, &total_obj_size); 2488. 	obj_chain(win, "migrating obj", migrating_objs, 2489. 				&total_obj_count, &total_obj_size); 2490. 	mon_invent_chain(win, "minvent", fmon, 2491. 				&total_obj_count,&total_obj_size); 2492. 	mon_invent_chain(win, "migrating minvent", migrating_mons, 2493. 				&total_obj_count, &total_obj_size); 2494. 2495. 	contained(win, "contained",  2496. 				&total_obj_count, &total_obj_size); 2497. 2498. 	putstr(win, 0, separator); 2499. 	Sprintf(buf, template, "Total", total_obj_count, total_obj_size); 2500. 	putstr(win, 0, buf); 2501. 2502. 	putstr(win, 0, ""); 2503. 	putstr(win, 0, ""); 2504. 	Sprintf(buf, "Monsters, size %d", (int) sizeof(struct monst)); 2505. 	putstr(win, 0, buf); 2506. 	putstr(win, 0, ""); 2507. 2508. 	mon_chain(win, "fmon", fmon,  2509. 				&total_mon_count, &total_mon_size); 2510. 	mon_chain(win, "migrating", migrating_mons, 2511. 				&total_mon_count, &total_mon_size); 2512. 2513. 	putstr(win, 0, separator); 2514. 	Sprintf(buf, template, "Total", total_mon_count, total_mon_size); 2515. 	putstr(win, 0, buf); 2516. 2517. #if defined(__BORLANDC__) && !defined(_WIN32) 2518. 	show_borlandc_stats(win); 2519. #endif 2520. 2521. 	display_nhwindow(win, FALSE); 2522. 	destroy_nhwindow(win); 2523. 	return 0; 2524. } 2525.  2526. void 2527. sanity_check 2528. { 2529. 	obj_sanity_check; 2530. 	timer_sanity_check; 2531. } 2532.  2533. #ifdef DISPLAY_LAYERS 2534. /* 2535.  * Detail contents of each display layer at specified location(s). 2536. */  2537. static int 2538. wiz_show_display 2539. { 2540.     int ans, glyph; 2541.    coord cc; 2542.    winid win; 2543.    char buf[BUFSZ]; 2544.    struct rm *lev; 2545. 2546.     cc.x = u.ux; 2547.    cc.y = u.uy; 2548.    pline("Pick a location."); 2549.    ans = getpos(&cc, FALSE, "a location of interest"); 2550.    if (ans < 0 || cc.x < 0) 2551. 	return 0;	/* done */ 2552.    lev = &levl[cc.x][cc.y]; 2553.    win = create_nhwindow(NHW_MENU); 2554.    Sprintf(buf, "Contents of hero's memory at (%d, %d):", cc.x, cc.y); 2555.    putstr(win, 0, buf); 2556.    putstr(win, 0, ""); 2557.    Sprintf(buf, "Invisible monster: %s",  2558. 	    lev->mem_invis ? "present" : "none"); 2559.    putstr(win, 0, buf); 2560.    if (lev->mem_obj && lev->mem_corpse) 2561. 	if (mons[lev->mem_obj - 1].geno & G_UNIQ) 2562. 	   Sprintf(buf, "Object: %s%s corpse",  2563. 		    type_is_pname(&mons[lev->mem_obj - 1]) ? "" : "the ",  2564. 		    s_suffix(mons[lev->mem_obj - 1].mname)); 2565. 	else 2566. 	   Sprintf(buf, "Object: %s corpse", mons[lev->mem_obj - 1].mname); 2567.    else 2568. 	Sprintf(buf, "Object: %s", lev->mem_obj ? 2569. 		obj_typename(lev->mem_obj - 1) : "none"); 2570.    putstr(win, 0, buf); 2571.    Sprintf(buf, "Trap: %s", lev->mem_trap ?  2572. 	    defsyms[trap_to_defsym(lev->mem_trap)].explanation : "none"); 2573.    putstr(win, 0, buf); 2574.    Sprintf(buf, "Backgroud: %s", defsyms[lev->mem_bg].explanation); 2575.    putstr(win, 0, buf); 2576.    putstr(win, 0, ""); 2577.    glyph = glyph_at(cc.x, cc.y); 2578.    Sprintf(buf, "Buffered (3rd screen): "); 2579.    if (glyph_is_monster(glyph)) { 2580. 	Strcat(buf, mons[glyph_to_mon(glyph)].mname); 2581. 	if (glyph_is_pet(glyph)) 2582. 	   Strcat(buf, " (tame)"); 2583. 	if (glyph_is_ridden_monster(glyph)) 2584. 	   Strcat(buf, " (ridden)"); 2585. 	if (glyph_is_detected_monster(glyph)) 2586. 	   Strcat(buf, " (detected)"); 2587.    } else if (glyph_is_object(glyph)) { 2588. 	if (glyph_is_body(glyph)) { 2589. 	   int corpse = glyph_to_body(glyph); 2590. 	   if (mons[corpse].geno & G_UNIQ) 2591. 		Sprintf(eos(buf), "%s%s corpse", 2592. 			type_is_pname(&mons[corpse]) ? "" : "the ",  2593. 			s_suffix(mons[corpse].mname)); 2594. 	   else 2595. 		Sprintf(eos(buf), "%s corpse", mons[corpse].mname); 2596. 	} else 2597. 	   Strcat(buf, obj_typename(glyph_to_obj(glyph))); 2598.    } else if (glyph_is_invisible(glyph)) 2599. 	Strcat(buf, "invisible monster"); 2600.    else if (glyph_is_cmap(glyph)) 2601. 	Strcat(buf, defsyms[glyph_to_cmap(glyph)].explanation); 2602.    else 2603. 	Sprintf(eos(buf), "[%d]", glyph); 2604.    putstr(win, 0, buf); 2605.    display_nhwindow(win, FALSE); 2606.    destroy_nhwindow(win); 2607.    return 0; 2608. } 2609. #endif 2610. 2611. #ifdef DEBUG_MIGRATING_MONS 2612. static int 2613. wiz_migrate_mons 2614. { 2615. 	int mcount = 0; 2616. 	char inbuf[BUFSZ]; 2617. 	struct permonst *ptr; 2618. 	struct monst *mtmp; 2619. 	d_level tolevel; 2620. 	getlin("How many random monsters to migrate? [0]", inbuf); 2621. 	if (*inbuf == '\033') return 0; 2622. 	mcount = atoi(inbuf); 2623. 	if (mcount < 0 || mcount > (COLNO * ROWNO) || Is_botlevel(&u.uz)) 2624. 		return 0; 2625. 	while (mcount > 0) { 2626. 		if (Is_stronghold(&u.uz)) 2627. 		   assign_level(&tolevel, &valley_level); 2628. 		else 2629. 		   get_level(&tolevel, depth(&u.uz) + 1); 2630. 		ptr = rndmonst; 2631. 		mtmp = makemon(ptr, 0, 0, NO_MM_FLAGS); 2632. 		if (mtmp) migrate_to_level(mtmp, ledger_no(&tolevel), 2633. 				MIGR_RANDOM, (coord *)0); 2634. 		mcount--; 2635. 	} 2636. 	return 0; 2637. } 2638. #endif 2639. 2640. #endif /* WIZARD */ 2641. 2642. #define unctrl(c)	((c) <= C('z') ? (0x60 | (c)) : (c)) 2643. #define unmeta(c)	(0x7f & (c)) 2644. 2645.  2646. void 2647. rhack(cmd) 2648. register char *cmd; 2649. { 2650. 	boolean do_walk, do_rush, prefix_seen, bad_command, 2651. 		firsttime = (cmd == 0); 2652. 2653. 	iflags.menu_requested = FALSE; 2654. 	if (firsttime) { 2655. 		flags.nopick = 0; 2656. 		cmd = parse; 2657. 	} 2658. 	if (*cmd == '\033') { /* key - user might be panicking */ 2659. 		/* Bring up the menu */ 2660. 		if (multi || !flags.menu_on_esc || !(domenusystem)) { 2661. 		flags.move = FALSE; 2662. 		   multi = 0; 2663. 		} 2664. 		return; 2665. #if 0 2666. 		flags.move = FALSE; 2667. 		return; 2668. #endif 2669. 	} 2670. #ifdef REDO 2671. 	if (*cmd == DOAGAIN && !in_doagain && saveq[0]) { 2672. 		in_doagain = TRUE; 2673. 		stail = 0; 2674. 		rhack((char *)0);	/* read and execute command */ 2675. 		in_doagain = FALSE; 2676. 		return; 2677. 	} 2678. 	/* Special case of *cmd == ' ' handled better below */ 2679. 	if(!*cmd || *cmd == (char)0377) 2680. #else 2681. 	if(!*cmd || *cmd == (char)0377 || (!flags.rest_on_space && *cmd == ' ')) 2682. #endif 2683. 	{ 2684. 		nhbell; 2685. 		flags.move = FALSE; 2686. 		return;		/* probably we just had an interrupt */ 2687. 	} 2688. 	if (iflags.num_pad && iflags.num_pad_mode == 1) { 2689. 		/* This handles very old inconsistent DOS/Windows behaviour 2690. 		 * in a new way: earlier, the keyboard handler mapped these, 2691. 		 * which caused counts to be strange when entered from the 2692. 		 * number pad. Now do not map them until here. 2693. 		 */ 2694. 		switch (*cmd) { 2695. 		   case '5':       *cmd = 'g'; break; 2696. 		   case M('5'):    *cmd = 'G'; break; 2697. 		   case M('0'):    *cmd = 'I'; break; 2698.        	}  2699.         }  2700. 	/* handle most movement commands */ 2701. 	do_walk = do_rush = prefix_seen = FALSE; 2702. 	flags.travel = iflags.travel1 = 0; 2703. 	switch (*cmd) { 2704. 	 case 'g': if (movecmd(cmd[1])) { 2705. 			flags.run = 2; 2706. 			do_rush = TRUE; 2707. 		   } else 2708. 			prefix_seen = TRUE; 2709. 		   break; 2710. 	 case '5': if (!iflags.num_pad) break;	/* else FALLTHRU */ 2711. 	 case 'G': if (movecmd(lowc(cmd[1]))) { 2712. 			flags.run = 3; 2713. 			do_rush = TRUE; 2714. 		   } else 2715. 			prefix_seen = TRUE; 2716. 		   break; 2717. 	 case '-': if (!iflags.num_pad) break;	/* else FALLTHRU */ 2718. 	/* Effects of movement commands and invisible monsters: 2719. 	 * m: always move onto space (even if 'I' remembered) 2720. 	 * F: always attack space (even if 'I' not remembered) 2721. 	 * normal movement: attack if 'I', move otherwise 2722. 	 */ 2723. 	 case 'F':  if (movecmd(cmd[1])) { 2724. 			flags.forcefight = 1; 2725. 			do_walk = TRUE; 2726. 		   } else 2727. 			prefix_seen = TRUE; 2728. 		   break; 2729. 	 case 'm': if (movecmd(cmd[1]) || u.dz) { 2730. 			flags.run = 0; 2731. 			flags.nopick = 1; 2732. 			if (!u.dz) do_walk = TRUE; 2733. 			else cmd[0] = cmd[1];	/* "m<" or "m>" */ 2734. 		   } else 2735. 			prefix_seen = TRUE; 2736. 		   break; 2737. 	 case 'M': if (movecmd(lowc(cmd[1]))) { 2738. 			flags.run = 1; 2739. 			flags.nopick = 1; 2740. 			do_rush = TRUE; 2741. 		   } else 2742. 			prefix_seen = TRUE; 2743. 		   break; 2744. 	 case '0': if (!iflags.num_pad) break; 2745. 		   (void)ddoinv; /* a convenience borrowed from the PC */ 2746. 		   flags.move = FALSE; 2747. 		   multi = 0; 2748. 		   return; 2749. 	 case CMD_TRAVEL: 2750. 		   if (iflags.travelcmd) { 2751. 			   flags.travel = 1; 2752. 			   iflags.travel1 = 1; 2753. 			   flags.run = 8; 2754. 			   flags.nopick = 1; 2755. 			   do_rush = TRUE; 2756. 			   break; 2757. 		   }  2758. 		    /*FALLTHRU*/ 2759. 	 default:  if (movecmd(*cmd)) {	/* ordinary movement */ 2760. 			flags.run = 0;	/* only matters here if it was 8 */ 2761. 			do_walk = TRUE; 2762. 		   } else if (movecmd(iflags.num_pad ? 2763. 				      unmeta(*cmd) : lowc(*cmd))) { 2764. 			flags.run = 1; 2765. 			do_rush = TRUE; 2766. 		   } else if (movecmd(unctrl(*cmd))) { 2767. 			flags.run = 3; 2768. 			do_rush = TRUE; 2769. 		   }  2770. 		    break; 2771. 	} 2772.  2773. 	/* some special prefix handling */ 2774. 	/* overload 'm' prefix for ',' to mean "request a menu" */ 2775. 	if (prefix_seen && cmd[1] == ',') { 2776. 		iflags.menu_requested = TRUE; 2777. 		++cmd; 2778. 	} 2779.  2780. 	if (do_walk) { 2781. 	   if (multi) flags.mv = TRUE; 2782. 	   domove; 2783. 	   flags.forcefight = 0; 2784. 	   return; 2785. 	} else if (do_rush) { 2786. 	   if (firsttime) { 2787. 		if (!multi) multi = max(COLNO,ROWNO); 2788. 		u.last_str_turn = 0; 2789. 	   }  2790. 	    flags.mv = TRUE; 2791. 	   domove; 2792. 	   return; 2793. 	} else if (prefix_seen && cmd[1] == '\033') {	/* */ 2794. 	   /* don't report "unknown command" for change of heart... */ 2795. 	    bad_command = FALSE; 2796. 	} else if (*cmd == ' ' && !flags.rest_on_space) { 2797. 	   bad_command = TRUE;		/* skip cmdlist[] loop */ 2798. 	/* handle all other commands */ 2799. 	} else { 2800. 	   register const struct func_tab *tlist; 2801. 	   int res, NDECL((*func)); 2802. 	   for (tlist = cmdlist; tlist->f_char; tlist++) { 2803. 		if ((*cmd & 0xff) != (tlist->f_char & 0xff)) continue; 2804. 2805. 		if (u.uburied && !tlist->can_if_buried) { 2806. 		   You_cant("do that while you are buried!"); 2807. 		   res = 0; 2808. 		} else { 2809. 		   /* we discard 'const' because some compilers seem to have 2810. 		      trouble with the pointer passed to set_occupation */ 2811. 		   func = ((struct func_tab *)tlist)->f_funct; 2812. 		   if (tlist->f_text && !occupation && multi) 2813. 			set_occupation(func, tlist->f_text, multi); 2814. 		   res = (*func);		/* perform the command */ 2815. 		} 2816. 		if (!res) { 2817. 		   flags.move = FALSE; 2818. 		   multi = 0; 2819. 		} 2820. 		return; 2821. 	   }  2822. 	    /* if we reach here, cmd wasn't found in cmdlist[] */ 2823. 	   bad_command = TRUE; 2824. 	} 2825. 	if (bad_command) { 2826. 	   char expcmd[10]; 2827. 	   register char *cp = expcmd; 2828. 2829. 	    while (*cmd && (int)(cp - expcmd) < (int)(sizeof expcmd - 3)) { 2830. 		if (*cmd >= 040 && *cmd < 0177) { 2831. 		   *cp++ = *cmd++; 2832. 		} else if (*cmd & 0200) { 2833. 		   *cp++ = 'M'; 2834. 		   *cp++ = '-'; 2835. 		   *cp++ = *cmd++ &= ~0200; 2836. 		} else { 2837. 		   *cp++ = '^'; 2838. 		   *cp++ = *cmd++ ^ 0100; 2839. 		} 2840. 	    }  2841. 	    *cp = '\0'; 2842. 	   if (!prefix_seen || !iflags.cmdassist ||  2843. 		!help_dir(0, "Invalid direction key!")) 2844. 	   Norep("Unknown command '%s'.", expcmd); 2845. 	} 2846. 	/* didn't move */ 2847. 	flags.move = FALSE; 2848. 	multi = 0; 2849. 	return; 2850. } 2851.  2852. int 2853. xytod(x, y)	/* convert an x,y pair into a direction code */ 2854. schar x, y; 2855. { 2856. 	register int dd; 2857. 2858. 	for(dd = 0; dd < 8; dd++) 2859. 	   if(x == xdir[dd] && y == ydir[dd]) return dd; 2860. 2861. 	return -1; 2862. } 2863.  2864. void 2865. dtoxy(cc,dd)	/* convert a direction code into an x,y pair */ 2866. coord *cc; 2867. register int dd; 2868. { 2869. 	cc->x = xdir[dd]; 2870. 	cc->y = ydir[dd]; 2871. 	return; 2872. } 2873.  2874. int 2875. movecmd(sym)	/* also sets u.dz, but returns false for <> */ 2876. char sym; 2877. { 2878. 	register const char *dp; 2879. 	register const char *sdp; 2880. 	if(iflags.num_pad) sdp = ndir; else sdp = sdir;	/* DICE workaround */ 2881. 2882. 	u.dz = 0; 2883. 	if(!(dp = index(sdp, sym))) return 0; 2884. 	u.dx = xdir[dp-sdp]; 2885. 	u.dy = ydir[dp-sdp]; 2886. 	u.dz = zdir[dp-sdp]; 2887. 	if (u.dx && u.dy && u.umonnum == PM_GRID_BUG) { 2888. 		u.dx = u.dy = 0; 2889. 		return 0; 2890. 	} 2891. 	return !u.dz; 2892. } 2893.  2894. /*  2895.  * uses getdir but unlike getdir it specifically 2896. * produces coordinates using the direction from getdir 2897. * and verifies that those coordinates are ok. 2898. *  2899.  * If the call to getdir returns 0, Never_mind is displayed. 2900. * If the resulting coordinates are not okay, emsg is displayed. 2901. *  2902.  * Returns non-zero if coordinates in cc are valid. 2903. */  2904. int get_adjacent_loc(prompt,emsg,x,y,cc) 2905. const char *prompt, *emsg; 2906. xchar x,y; 2907. coord *cc; 2908. { 2909. 	xchar new_x, new_y; 2910. 	if (!getdir(prompt)) { 2911. 		pline(Never_mind); 2912. 		return 0; 2913. 	} 2914. 	new_x = x + u.dx; 2915. 	new_y = y + u.dy; 2916. 	if (cc && isok(new_x,new_y)) { 2917. 		cc->x = new_x; 2918. 		cc->y = new_y; 2919. 	} else { 2920. 		if (emsg) pline(emsg); 2921. 		return 0; 2922. 	} 2923. 	return 1; 2924. } 2925.  2926. int 2927. getdir(s) 2928. const char *s; 2929. { 2930. 	char dirsym; 2931. 	/* WAC add dirsymbols to generic prompt */ 2932. 	char buf[BUFSZ]; 2933.         2934. 	Sprintf(buf, "In what direction? [%s]",  2935.                 (iflags.num_pad ? ndir : sdir)); 2936. 2937.  2938. #ifdef REDO 2939. 	if(in_doagain || *readchar_queue) 2940. 	   dirsym = readchar; 2941. 	else 2942. #endif 2943. 	do { 2944. 	   dirsym = yn_function ((s && *s != '^') ? s : buf, (char *)0, '\0'); 2945. 	} while (!movecmd(dirsym) && !index(quitchars, dirsym) 2946.                 && dirsym == '.' && dirsym == 's' && !u.dz); 2947. 2948. #ifdef REDO 2949. 	savech(dirsym); 2950. #endif 2951. 	if(dirsym == '.' || dirsym == 's') 2952. 		u.dx = u.dy = u.dz = 0; 2953. 	else if(!movecmd(dirsym) && !u.dz) { 2954. 		boolean did_help = FALSE; 2955. 		if(!index(quitchars, dirsym)) { 2956. 		   if (iflags.cmdassist) { 2957. 			did_help = help_dir((s && *s == '^') ? dirsym : 0, 2958. 					    "Invalid direction key!"); 2959. 		   }  2960. 		    if (!did_help) pline("What a strange direction!"); 2961. 		} 2962. 		return 0; 2963. 	} 2964. 	if(!u.dz && (Stunned || (Confusion && !rn2(5)))) confdir; 2965. 	return 1; 2966. } 2967.  2968. STATIC_OVL boolean 2969. help_dir(sym, msg) 2970. char sym; 2971. const char *msg; 2972. { 2973. 	char ctrl; 2974. 	winid win; 2975. 	static const char wiz_only_list[] = "EFGIOVW"; 2976. 	char buf[BUFSZ], buf2[BUFSZ], *expln; 2977. 2978. 	win = create_nhwindow(NHW_TEXT); 2979. 	if (!win) return FALSE; 2980. 	if (msg) { 2981. 		Sprintf(buf, "cmdassist: %s", msg); 2982. 		putstr(win, 0, buf); 2983. 		putstr(win, 0, ""); 2984. 	} 2985. 	if (letter(sym)) { 2986. 	   sym = highc(sym); 2987. 	   ctrl = (sym - 'A') + 1; 2988. 	   if ((expln = dowhatdoes_core(ctrl, buf2))  2989. 		&& (!index(wiz_only_list, sym) 2990. #ifdef WIZARD 2991. 		   || wizard 2992. #endif 2993. 	                    )) {  2994. 		Sprintf(buf, "Are you trying to use ^%c%s?", sym,  2995. 			index(wiz_only_list, sym) ? "" :  2996. 			" as specified in the Guidebook"); 2997. 		putstr(win, 0, buf); 2998. 		putstr(win, 0, ""); 2999. 		putstr(win, 0, expln); 3000. 		putstr(win, 0, ""); 3001. 		putstr(win, 0, "To use that command, you press"); 3002. 		Sprintf(buf, 3003. 			"the  key, and the <%c> key at the same time.", sym); 3004. 		putstr(win, 0, buf); 3005. 		putstr(win, 0, ""); 3006. 	   }  3007. 	}  3008. 	if (iflags.num_pad && u.umonnum == PM_GRID_BUG) { 3009. 	   putstr(win, 0, "Valid direction keys in your current form (with number_pad on) are:"); 3010. 	   putstr(win, 0, "             8   "); 3011. 	   putstr(win, 0, "             |   "); 3012. 	   putstr(win, 0, "          4- . -6"); 3013. 	   putstr(win, 0, "             |   "); 3014. 	   putstr(win, 0, "             2   "); 3015. 	} else if (u.umonnum == PM_GRID_BUG) { 3016. 	   putstr(win, 0, "Valid direction keys in your current form are:"); 3017. 	   putstr(win, 0, "             k   "); 3018. 	   putstr(win, 0, "             |   "); 3019. 	   putstr(win, 0, "          h- . -l"); 3020. 	   putstr(win, 0, "             |   "); 3021. 	   putstr(win, 0, "             j   "); 3022. 	} else if (iflags.num_pad) { 3023. 	   putstr(win, 0, "Valid direction keys (with number_pad on) are:"); 3024. 	   putstr(win, 0, "          7  8  9"); 3025. 	   putstr(win, 0, "           \\ | / "); 3026. 	   putstr(win, 0, "          4- . -6"); 3027. 	   putstr(win, 0, "           / | \\ "); 3028. 	   putstr(win, 0, "          1  2  3"); 3029. 	} else { 3030. 	   putstr(win, 0, "Valid direction keys are:"); 3031. 	   putstr(win, 0, "          y  k  u"); 3032. 	   putstr(win, 0, "           \\ | / "); 3033. 	   putstr(win, 0, "          h- . -l"); 3034. 	   putstr(win, 0, "           / | \\ "); 3035. 	   putstr(win, 0, "          b  j  n"); 3036. 	}; 3037. 	putstr(win, 0, ""); 3038. 	putstr(win, 0, "         <  up"); 3039. 	putstr(win, 0, "         >  down"); 3040. 	putstr(win, 0, "         .  direct at yourself"); 3041. 	putstr(win, 0, ""); 3042. 	putstr(win, 0, "(Suppress this message with !cmdassist in config file.)"); 3043. 	display_nhwindow(win, FALSE); 3044. 	destroy_nhwindow(win); 3045. 	return TRUE; 3046. } 3047.  3048. #endif /* OVL1 */ 3049. #ifdef OVLB 3050. 3051. void 3052. confdir 3053. { 3054. 	register int x = (u.umonnum == PM_GRID_BUG) ? 2*rn2(4) : rn2(8); 3055. 	u.dx = xdir[x]; 3056. 	u.dy = ydir[x]; 3057. 	return; 3058. } 3059.  3060. #endif /* OVLB */ 3061. #ifdef OVL0 3062. 3063. int 3064. isok(x,y) 3065. register int x, y; 3066. { 3067. 	/* x corresponds to curx, so x==1 is the first column. Ach. %% */ 3068. 	return x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1; 3069. } 3070.  3071. static NEARDATA int last_multi; 3072. 3073. /*  3074.  * convert a MAP window position into a movecmd 3075. */  3076. const char * 3077. click_to_cmd(x, y, mod) 3078.    int x, y, mod; 3079. { 3080.     int dir; 3081.    static char cmd[4]; 3082.    cmd[1]=0; 3083. 3084.     x -= u.ux; 3085.    y -= u.uy; 3086. 3087.     if (iflags.travelcmd) { 3088.        if (abs(x) <= 1 && abs(y) <= 1 ) { 3089. 	x = sgn(x), y = sgn(y); 3090.    } else { 3091. 	u.tx = u.ux+x; 3092. 	u.ty = u.uy+y; 3093. 	cmd[0] = CMD_TRAVEL; 3094. 	return cmd; 3095.    }  3096.  3097.     if(x == 0 && y == 0) { 3098. 	/* here */ 3099. 	if(IS_FOUNTAIN(levl[u.ux][u.uy].typ) || IS_SINK(levl[u.ux][u.uy].typ)) { 3100. 	   cmd[0]=mod == CLICK_1 ? 'q' : M('d'); 3101. 	   return cmd; 3102. 	} else if(IS_THRONE(levl[u.ux][u.uy].typ)) { 3103. 	   cmd[0]=M('s'); 3104. 	   return cmd; 3105. 	} else if((u.ux == xupstair && u.uy == yupstair) 3106. 		  || (u.ux == sstairs.sx && u.uy == sstairs.sy && sstairs.up)  3107. 		  || (u.ux == xupladder && u.uy == yupladder)) { 3108. 	   return "<"; 3109. 	} else if((u.ux == xdnstair && u.uy == ydnstair) 3110. 		  || (u.ux == sstairs.sx && u.uy == sstairs.sy && !sstairs.up)  3111. 		  || (u.ux == xdnladder && u.uy == ydnladder)) { 3112. 	   return ">"; 3113. 	} else if(OBJ_AT(u.ux, u.uy)) { 3114. 	   cmd[0] = Is_container(level.objects[u.ux][u.uy]) ? M('l') : ','; 3115. 	   return cmd; 3116. 	} else { 3117. 	   return "."; /* just rest */ 3118. 	} 3119.     }  3120.  3121.     /* directional commands */ 3122. 3123.     dir = xytod(x, y); 3124. 3125. 	if (!m_at(u.ux+x, u.uy+y) && !test_move(u.ux, u.uy, x, y, TEST_MOVE)) { 3126. 	cmd[1] = (iflags.num_pad ? ndir[dir] : sdir[dir]); 3127. 	cmd[2] = 0; 3128. 	if (IS_DOOR(levl[u.ux+x][u.uy+y].typ)) { 3129. 	   /* slight assistance to the player: choose kick/open for them */ 3130. 	   if (levl[u.ux+x][u.uy+y].doormask & D_LOCKED) { 3131. 		cmd[0] = C('d'); 3132. 		return cmd; 3133. 	   }  3134. 	    if (levl[u.ux+x][u.uy+y].doormask & D_CLOSED) { 3135. 		cmd[0] = 'o'; 3136. 		return cmd; 3137. 	   }  3138. 	}  3139. 	if (levl[u.ux+x][u.uy+y].typ <= SCORR) { 3140. 	   cmd[0] = 's'; 3141. 	   cmd[1] = 0; 3142. 	   return cmd; 3143. 	} 3144.     }  3145.     } else { 3146.        /* convert without using floating point, allowing sloppy clicking */ 3147.        if(x > 2*abs(y)) 3148.            x = 1, y = 0; 3149.        else if(y > 2*abs(x)) 3150.            x = 0, y = 1; 3151.        else if(x < -2*abs(y)) 3152.            x = -1, y = 0; 3153.        else if(y < -2*abs(x)) 3154.            x = 0, y = -1; 3155.        else 3156.            x = sgn(x), y = sgn(y); 3157. 3158.         if(x == 0 && y == 0)	/* map click on player to "rest" command */ 3159.            return "."; 3160. 3161.         dir = xytod(x, y); 3162.    }  3163.  3164.     /* move, attack, etc. */ 3165.    cmd[1] = 0; 3166.    if(mod == CLICK_1) { 3167. 	cmd[0] = (iflags.num_pad ? ndir[dir] : sdir[dir]); 3168.    } else { 3169. 	cmd[0] = (iflags.num_pad ? M(ndir[dir]) : 3170. 		(sdir[dir] - 'a' + 'A')); /* run command */ 3171.    }  3172.  3173.     return cmd; 3174. } 3175.  3176. STATIC_OVL char * 3177. parse 3178. { 3179. #ifdef LINT	/* static char in_line[COLNO]; */ 3180. 	char in_line[COLNO]; 3181. #else 3182. 	static char in_line[COLNO]; 3183. #endif 3184. 	register int foo; 3185. #ifdef BORG 3186. 	char junk_char; 3187. #endif 3188. 	static char repeat_char; 3189. 	boolean prezero = FALSE; 3190. 3191. 	multi = 0; 3192. 	flags.move = 1; 3193. 	flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */ 3194.  3195. #ifdef BORG 3196. 	if (borg_on) { 3197. 	/* KMH -- Danger! kbhit is non-standard! */ 3198. 	   if (!kbhit) { 3199. 	      borg_input; 3200. 	      return(borg_line); 3201. 	  } else { 3202. 		 junk_char = readchar; 3203. 		 pline("Cyborg terminated."); 3204. 		 borg_on = 0; 3205. 	  }  3206.  3207. 	} else 3208. #endif 3209. 	/* [Tom] for those who occasionally go insane... */ 3210. 	if (repeat_hit) { 3211. 		/* Sanity checks for repeat_hit */ 3212. 		if (repeat_hit < 0) repeat_hit = 0; 3213. 		else { 3214. 			/* Don't want things to get too out of hand */ 3215. 			if (repeat_hit > 10) repeat_hit = 10; 3216. 			 3217. 			repeat_hit--; 3218. 			in_line[0] = repeat_char; 3219. 			in_line[1] = 0; 3220. 			return (in_line); 3221. 		} 3222. 	}  3223.  3224. 	if (!iflags.num_pad || (foo = readchar) == 'n') 3225. 	   for  { 3226. 		foo = readchar; 3227. 		if (foo >= '0' && foo <= '9') { 3228. 		   multi = 10 * multi + foo - '0'; 3229. 		   if (multi < 0 || multi >= LARGEST_INT) multi = LARGEST_INT; 3230. 		   if (multi > 9) { 3231. 			clear_nhwindow(WIN_MESSAGE); 3232. 			Sprintf(in_line, "Count: %d", multi); 3233. 			pline(in_line); 3234. 			mark_synch; 3235. 		   }  3236. 		    last_multi = multi; 3237. 		   if (!multi && foo == '0') prezero = TRUE; 3238. 		} else break;	/* not a digit */ 3239. 	   }  3240.  3241. 	if (foo == '\033') {   /* esc cancels count (TH) */ 3242. 	   clear_nhwindow(WIN_MESSAGE); 3243. 	   /* multi = */ last_multi = 0;  /* WAC multi is cleared later in rhack */ 3244. # ifdef REDO 3245. 	} else if (foo == DOAGAIN || in_doagain) { 3246. 	   multi = last_multi; 3247. 	} else { 3248. 	   last_multi = multi; 3249. 	   savech(0);	/* reset input queue */ 3250. 	   savech((char)foo); 3251. # endif 3252. 	} 3253.  3254. 	if (multi) { 3255. 	   multi--; 3256. 	   save_cm = in_line; 3257. 	} else { 3258. 	   save_cm = (char *)0; 3259. 	} 3260. 	in_line[0] = foo; 3261. 	in_line[1] = '\0'; 3262. 3263. 	if (foo == 'g' || foo == 'G' || foo == 'm' || foo == 'M' ||  3264. 	    foo == 'F' || (iflags.num_pad && (foo == '5' || foo == '-'))) { 3265. 	   foo = readchar; 3266. #ifdef REDO 3267. 	   savech((char)foo); 3268. #endif 3269. 	   in_line[1] = foo; 3270. 	   in_line[2] = 0; 3271. 	} 3272. 	clear_nhwindow(WIN_MESSAGE); 3273. 3274. 	if (prezero) in_line[0] = '\033'; 3275. 	repeat_char = in_line[0]; 3276. 	 3277. 	return(in_line); 3278. } 3279.  3280. #endif /* OVL0 */ 3281. #ifdef OVLB 3282. 3283. #ifdef UNIX 3284. static 3285. void 3286. end_of_input 3287. { 3288. #ifndef NOSAVEONHANGUP 3289. 	if (!program_state.done_hup++ && program_state.something_worth_saving) 3290. 	   (void) dosave0; 3291. #endif 3292. 	exit_nhwindows((char *)0); 3293. 	clearlocks; 3294. 	terminate(EXIT_SUCCESS); 3295. } 3296. #endif 3297. 3298. #endif /* OVLB */ 3299. #ifdef OVL0 3300. 3301. char 3302. readchar 3303. { 3304. 	register int sym; 3305. 	int x = u.ux, y = u.uy, mod = 0; 3306. 3307. 	if ( *readchar_queue ) 3308. 	   sym = *readchar_queue++; 3309. 	else 3310. #ifdef REDO 3311. 	   sym = in_doagain ? Getchar : nh_poskey(&x, &y, &mod); 3312. #else 3313. 	   sym = Getchar; 3314. #endif 3315. 3316. #ifdef UNIX 3317. # ifdef NR_OF_EOFS 3318. 	if (sym == EOF) { 3319. 	   register int cnt = NR_OF_EOFS; 3320. 	 /*  3321. 	   * Some SYSV systems seem to return EOFs for various reasons 3322. 	  * (?like when one hits break or for interrupted systemcalls?), 3323. 	  * and we must see several before we quit. 3324. 	  */  3325. 	    do { 3326. 		clearerr(stdin);	/* omit if clearerr is undefined */ 3327. 		sym = Getchar; 3328. 	   } while (--cnt && sym == EOF); 3329. 	} 3330. # endif /* NR_OF_EOFS */ 3331. 	if (sym == EOF) 3332. 	   end_of_input; 3333. #endif /* UNIX */ 3334. 3335. 	if(sym == 0) { 3336. 	   /* click event */ 3337. 	   readchar_queue = click_to_cmd(x, y, mod); 3338. 	   sym = *readchar_queue++; 3339. 	} 3340. 	return((char) sym); 3341. } 3342.  3343. STATIC_PTR int 3344. dotravel 3345. { 3346. 	/* Keyboard travel command */ 3347. 	static char cmd[2]; 3348. 	coord cc; 3349. 3350. 	if (!iflags.travelcmd) return 0; 3351. 	cmd[1]=0; 3352. 	cc.x = iflags.travelcc.x; 3353. cc.y = iflags.travelcc.y; 3354. if (cc.x == -1 && cc.y == -1) { 3355. 	   /* No cached destination, start attempt from current position */ 3356. 	   cc.x = u.ux; 3357. 	   cc.y = u.uy; 3358. 	} 3359. 	pline("Where do you want to travel to?"); 3360. 	if (getpos(&cc, TRUE, "the desired destination") < 0) { 3361. 		/* user pressed ESC */ 3362. 		return 0; 3363. 	} 3364. 	iflags.travelcc.x = u.tx = cc.x;  3365. iflags.travelcc.y = u.ty = cc.y; 3366. cmd[0] = CMD_TRAVEL; 3367. 	readchar_queue = cmd; 3368. 	return 0; 3369. } 3370.  3371. #ifdef PORT_DEBUG 3372. # ifdef WIN32CON 3373. extern void NDECL(win32con_debug_keystrokes); 3374. extern void NDECL(win32con_handler_info); 3375. # endif 3376. 3377. int 3378. wiz_port_debug 3379. { 3380. 	int n, k;  3381. winid win; 3382. 	anything any; 3383. 	int item = 'a'; 3384. 	int num_menu_selections; 3385. 	struct menu_selection_struct { 3386. 		char *menutext; 3387. 		char *portname; 3388. 		void NDECL((*fn)); 3389. 	} menu_selections[] = { 3390. #ifdef WIN32CON 3391. 		{"test win32 keystrokes", "tty", win32con_debug_keystrokes}, 3392. 		{"show keystroke handler information", "tty", 3393. 				win32con_handler_info}, 3394. #endif 3395. 		{(char *)0, (char *)0, (void NDECL((*)))0}/* array terminator */ 3396. 	}; 3397.  3398. 	num_menu_selections = SIZE(menu_selections) - 1; 3399. 	for (k=n=0; k < num_menu_selections; ++k) 3400. 		if (!strcmp(menu_selections[k].portname, windowprocs.name)) 3401. 			n++; 3402. 	if (n > 0) { 3403. 		menu_item *pick_list; 3404. 		win = create_nhwindow(NHW_MENU); 3405. 		start_menu(win); 3406. 		for (k=0; k < num_menu_selections; ++k) { 3407. 			if (strcmp(menu_selections[k].portname, 3408. 				  windowprocs.name)) 3409. 				continue; 3410. 			any.a_int = k+1; 3411. 			add_menu(win, NO_GLYPH, &any, item++, 0, ATR_NONE, 3412. 				menu_selections[k].menutext, MENU_UNSELECTED); 3413. 		} 3414. 		end_menu(win, "Which port debugging feature?"); 3415. 		n = select_menu(win, PICK_ONE, &pick_list); 3416. 		destroy_nhwindow(win); 3417. 		if (n > 0) { 3418. 			n = pick_list[0].item.a_int - 1; 3419. 			free((genericptr_t) pick_list); 3420. 			/* execute the function */ 3421. 			(*menu_selections[n].fn); 3422. 		} 3423. 	} else 3424. 		pline("No port-specific debug capability defined."); 3425. 	return 0; 3426. } 3427. # endif /*PORT_DEBUG*/ 3428. 3429. #endif /* OVL0 */ 3430. #ifdef OVLB 3431. /* 3432.  *   Parameter validator for generic yes/no function to prevent 3433. *   the core from sending too long a prompt string to the 3434. *   window port causing a buffer overflow there. 3435. */  3436. char 3437. yn_function(query,resp, def) 3438. const char *query,*resp; 3439. char def; 3440. { 3441. 	char qbuf[QBUFSZ]; 3442. 	unsigned truncspot, reduction = sizeof(" [N] ?") + 1; 3443. 3444. 	if (resp) reduction += strlen(resp) + sizeof("  "); 3445. 	if (strlen(query) < (QBUFSZ - reduction)) 3446. 		return (*windowprocs.win_yn_function)(query, resp, def); 3447. 	paniclog("Query truncated: ", query); 3448. 	reduction += sizeof("..."); 3449. 	truncspot = QBUFSZ - reduction; 3450. 	(void) strncpy(qbuf, query, (int)truncspot); 3451. 	qbuf[truncspot] = '\0'; 3452. 	Strcat(qbuf,"..."); 3453. 	return (*windowprocs.win_yn_function)(qbuf, resp, def); 3454. } 3455. #endif 3456. 3457. /*cmd.c*/