Source:Cmd.c

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