Source:NetHack 3.1.0/cmd.c

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

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

1.   /*	SCCS Id: @(#)cmd.c	3.1	92/11/25	*/ 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. 8.   /*  9.     * Some systems may have getchar return EOF for various reasons, and 10.   * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs. 11.   */  12.   #if defined(SYSV) || defined(DGUX) || defined(HPUX) 13.  #define	NR_OF_EOFS	20 14.  #endif 15.   16.   #ifdef DUMB	/* stuff commented out in extern.h, but needed here */ 17.  extern int NDECL(doapply); /**/ 18.  extern int NDECL(dorub); /**/ 19.  extern int NDECL(dojump); /**/ 20.  extern int NDECL(doextlist); /**/ 21.  extern int NDECL(dodrop); /**/ 22.  extern int NDECL(doddrop); /**/ 23.  extern int NDECL(dodown); /**/ 24.  extern int NDECL(doup); /**/ 25.  extern int NDECL(donull); /**/ 26.  extern int NDECL(dowipe); /**/ 27.  extern int NDECL(do_mname); /**/ 28.  extern int NDECL(ddocall); /**/ 29.  extern int NDECL(dotakeoff); /**/ 30.  extern int NDECL(doremring); /**/ 31.  extern int NDECL(dowear); /**/ 32.  extern int NDECL(doputon); /**/ 33.  extern int NDECL(doddoremarm); /**/ 34.  extern int NDECL(dokick); /**/ 35.  extern int NDECL(dothrow); /**/ 36.  extern int NDECL(doeat); /**/ 37.  extern int NDECL(done2); /**/ 38.  extern int NDECL(doengrave); /**/ 39.  extern int NDECL(dopickup); /**/ 40.  extern int NDECL(ddoinv); /**/ 41.  extern int NDECL(dotypeinv); /**/ 42.  extern int NDECL(dolook); /**/ 43.  extern int NDECL(doprgold); /**/ 44.  extern int NDECL(doprwep); /**/ 45.  extern int NDECL(doprarm); /**/ 46.  extern int NDECL(doprring); /**/ 47.  extern int NDECL(dopramulet); /**/ 48.  extern int NDECL(doprtool); /**/ 49.  extern int NDECL(dosuspend); /**/ 50.  extern int NDECL(doforce); /**/ 51.  extern int NDECL(doopen); /**/ 52.  extern int NDECL(doclose); /**/ 53.  extern int NDECL(dosh); /**/ 54.  extern int NDECL(dodiscovered); /**/ 55.  extern int NDECL(doset); /**/ 56.  extern int NDECL(dotogglepickup); /**/ 57.  extern int NDECL(dowhatis); /**/ 58.  extern int NDECL(doquickwhatis); /**/ 59.  extern int NDECL(dowhatdoes); /**/ 60.  extern int NDECL(dohelp); /**/ 61.  extern int NDECL(dohistory); /**/ 62.  extern int NDECL(doloot); /**/ 63.  extern int NDECL(dodrink); /**/ 64.  extern int NDECL(dodip); /**/ 65.  extern int NDECL(dosacrifice); /**/ 66.  extern int NDECL(dopray); /**/ 67.  extern int NDECL(doturn); /**/ 68.  extern int NDECL(doredraw); /**/ 69.  extern int NDECL(doread); /**/ 70.  extern int NDECL(dosave); /**/ 71.  extern int NDECL(dosearch); /**/ 72.  extern int NDECL(doidtrap); /**/ 73.  extern int NDECL(dopay); /**/ 74.  extern int NDECL(dosit); /**/ 75.  extern int NDECL(dotalk); /**/ 76.  extern int NDECL(docast); /**/ 77.  extern int NDECL(dovspell); /**/ 78.  extern int NDECL(dotele); /**/ 79.  extern int NDECL(dountrap); /**/ 80.  extern int NDECL(doversion); /**/ 81.  extern int NDECL(doextversion); /**/ 82.  extern int NDECL(dowield); /**/ 83.  extern int NDECL(dozap); /**/ 84.  extern int NDECL(doorganize); /**/ 85.  #endif /* DUMB */ 86.   87.   #ifdef OVL1 88.  static int NDECL((*timed_occ_fn)); 89.  #endif /* OVL1 */ 90.   91.   STATIC_PTR int NDECL(doprev_message); 92.  STATIC_PTR int NDECL(timed_occupation); 93.  STATIC_PTR int NDECL(doextcmd); 94.  # ifdef POLYSELF 95.  STATIC_PTR int NDECL(domonability); 96.  # endif 97.  # ifdef WIZARD 98.  STATIC_PTR int NDECL(wiz_wish); 99.  STATIC_PTR int NDECL(wiz_identify); 100. STATIC_PTR int NDECL(wiz_map); 101. STATIC_PTR int NDECL(wiz_genesis); 102. STATIC_PTR int NDECL(wiz_where); 103. STATIC_PTR int NDECL(wiz_detect); 104. STATIC_PTR int NDECL(wiz_level_tele); 105. # endif 106. # ifdef EXPLORE_MODE 107. STATIC_PTR int NDECL(enter_explore_mode); 108. # endif 109. # if defined(WIZARD) || defined(EXPLORE_MODE) 110. STATIC_PTR int NDECL(wiz_attributes); 111. # endif 112.  113.  #ifdef OVLB 114. static void FDECL(enlght_line, (const char *,const char *,const char *)); 115. #ifdef UNIX 116. static void NDECL(end_of_input); 117. #endif 118. #endif /* OVLB */ 119.  120.  #ifdef OVL0 121. static int FDECL(click_to_cmd, (int,int,int)); 122. #endif /* OVL0 */ 123.  124.  STATIC_OVL char *NDECL(parse); 125.  126.  #ifdef UNIX 127. extern boolean hu; 128. #endif 129.  130.  #ifdef OVL1 131.  132.  STATIC_PTR int 133. doprev_message 134. {  135.      return nh_doprev_message; 136. }  137.   138.  /* Count down by decrementing multi */ 139. STATIC_PTR int 140. timed_occupation { 141. 	(*timed_occ_fn); 142. 	if (multi > 0) 143. 		multi--; 144. 	return multi > 0; 145. }  146.   147.  /* If you have moved since initially setting some occupations, they 148.  * now shouldn't be able to restart. 149.  *  150.   * The basic rule is that if you are carrying it, you can continue 151.  * since it is with you. If you are acting on something at a distance, 152.  * your orientation to it must have changed when you moved. 153.  *  154.   * The exception to this is taking off items, since they can be taken 155.  * off in a number of ways in the intervening time, screwing up ordering. 156.  *  157.   *	Currently:	Take off all armor. 158.  *			Picking Locks / Forcing Chests. 159.  */  160.  void 161. reset_occupations { 162.  163.  	reset_remarm; 164. 	reset_pick; 165. }  166.   167.  /* If a time is given, use it to timeout this function, otherwise the 168.  * function times out by its own means. 169.  */  170.  void 171. set_occupation(fn, txt, xtime) 172. int NDECL((*fn)); 173. const char *txt; 174. int xtime; 175. {  176.  	if (xtime) { 177. 		occupation = timed_occupation; 178. 		timed_occ_fn = fn; 179. 	} else 180. 		occupation = fn; 181. 	occtxt = txt; 182. 	occtime = 0; 183. 	return; 184. }  185.   186.  #ifdef REDO 187.  188.  static char NDECL(popch); 189.  190.  /* Provide a means to redo the last command. The flag `in_doagain' is set 191.  * to true while redoing the command. This flag is tested in commands that 192.  * require additional input (like `throw' which requires a thing and a  193.   * direction), and the input prompt is not shown. Also, while in_doagain is 194. * TRUE, no keystrokes can be saved into the saveq. 195.  */  196.  #define BSIZE 20 197. static char pushq[BSIZE], saveq[BSIZE]; 198. static int NEARDATA phead, NEARDATA ptail, NEARDATA shead, NEARDATA stail; 199.  200.  static char 201. popch { 202. 	/* If occupied, return '\0', letting tgetch know a character should 203. 	 * be read from the keyboard. If the character read is not the 204. 	 * ABORT character (as checked in pcmain.c), that character will be  205. * pushed back on the pushq. 206. 	 */  207.  	if (occupation) return '\0'; 208. 	if (in_doagain) return (shead != stail) ? saveq[stail++] : '\0'; 209. 	else		return (phead != ptail) ? pushq[ptail++] : '\0'; 210. }  211.   212.  char 213. pgetchar {		/* curtesy of aeb@cwi.nl */ 214. 	register int ch; 215.  216.  	if(!(ch = popch)) 217. 		ch = nhgetch; 218. 	return(ch); 219. }  220.   221.  /* A ch == 0 resets the pushq */ 222. void 223. pushch(ch) 224. char ch; 225. {  226.  	if (!ch) 227. 		phead = ptail = 0; 228. 	if (phead < BSIZE) 229. 		pushq[phead++] = ch; 230. 	return; 231. }  232.   233.  /* A ch == 0 resets the saveq. Only save keystrokes when not 234.  * replaying a previous command. 235.  */  236.  void 237. savech(ch) 238. char ch; 239. {  240.  	if (!in_doagain) { 241. 		if (!ch) 242. 			phead = ptail = shead = stail = 0; 243. 		else if (shead < BSIZE) 244. 			saveq[shead++] = ch; 245. 	}  246.  	return; 247. }  248.  #endif /* REDO */ 249.  250.  #endif /* OVL1 */ 251. #ifdef OVLB 252.  253.  STATIC_PTR int 254. doextcmd	/* here after # - now read a full-word command */ 255. {  256.  	char buf[BUFSZ]; 257. 	register const struct ext_func_tab *efp = extcmdlist; 258. again: 259. #ifdef COM_COMPL 260. 	get_ext_cmd(buf); 261. #else 262. 	getlin("#", buf); 263. #endif 264. 	clear_nhwindow(WIN_MESSAGE); 265. 	if(buf[0] == '\0' || buf[0] == '\033') 266. 		return 0; 267. 	if(buf[0] == '?') { 268. 		(void) doextlist; 269. 		goto again; 270. 	}  271.  	while(efp->ef_txt) { 272. 		if(!strncmpi(efp->ef_txt, buf,BUFSIZ)) 273. 			return (*(efp->ef_funct)); 274. 		efp++; 275. 	}  276.  	pline("%s: unknown extended command.", buf); 277. 	return 0; 278. }  279.   280.  int 281. doextlist	/* here after #? - now list all full-word commands */ 282. {  283.  	register const struct ext_func_tab *efp; 284. 	char	 buf[BUFSZ]; 285. 	winid datawin; 286.  287.  	datawin = create_nhwindow(NHW_TEXT); 288. 	putstr(datawin, 0, ""); 289. 	putstr(datawin, 0, "            Extended Commands List"); 290. 	putstr(datawin, 0, ""); 291. #ifdef COM_COMPL 292. 	putstr(datawin, 0, "    Press '#', then type (first letter only):"); 293. #else 294. 	putstr(datawin, 0, "    Press '#', then type:"); 295. #endif 296. 	putstr(datawin, 0, ""); 297.  298.  	for(efp = extcmdlist; efp->ef_txt; efp++) { 299. 		Sprintf(buf, "    %-8s  - %s.", efp->ef_txt, efp->ef_desc); 300. 		putstr(datawin, 0, buf); 301. 	}  302.  	display_nhwindow(datawin, FALSE); 303. 	destroy_nhwindow(datawin); 304. 	return 0; 305. }  306.   307.  #ifdef POLYSELF 308. STATIC_PTR int 309. domonability 310. {  311.  	if (can_breathe(uasmon)) return dobreathe; 312. 	else if (attacktype(uasmon, AT_SPIT)) return dospit; 313. 	else if (u.usym == S_NYMPH) return doremove; 314. 	else if (u.usym == S_UMBER) return doconfuse; 315. 	else if (is_were(uasmon)) return dosummon; 316. 	else if (webmaker(uasmon)) return dospinweb; 317. 	else if (is_hider(uasmon)) return dohide; 318. 	else if(u.umonnum == PM_GREMLIN) { 319. 	    if(IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 320. 		struct monst *mtmp; 321. 		if ((mtmp = cloneu) != 0) { 322. 			mtmp->mhpmax = (u.mhmax /= 2); 323. 			You("multiply."); 324. 			dryup(u.ux,u.uy); 325. 		}  326.  	    } else pline("There is no fountain here."); 327. 	}  328.  	else if (u.usym == S_UNICORN) { 329. 	    use_unicorn_horn((struct obj *)0); 330. 	    return 1; 331. 	} else if (u.umonnum == PM_MIND_FLAYER) return domindblast; 332. 	else if (uasmon->msound == MS_SHRIEK) { 333. 	    You("shriek."); 334. 	    aggravate; 335. 	} else if (u.umonnum >= 0) 336. 		pline("Any special ability you may have is purely reflexive."); 337. 	else You("don't have a special ability!"); 338. 	return 0; 339. }  340.  #endif 341.  342.  #ifdef EXPLORE_MODE 343. STATIC_PTR int 344. enter_explore_mode 345. {  346.  	if(!discover && !wizard) { 347. 		pline("Beware!  From discovery mode there will be no return to normal game."); 348. 		if (yn("Do you want to enter discovery mode?") == 'y') { 349. 			clear_nhwindow(WIN_MESSAGE); 350. 			You("are now in non-scoring discovery mode."); 351. 			discover = TRUE; 352. 		}  353.  		else { 354. 			clear_nhwindow(WIN_MESSAGE); 355. 			pline("Resuming normal game."); 356. 		}  357.  	}  358.  	return 0; 359. }  360.  #endif 361.  362.  #ifdef WIZARD 363. STATIC_PTR int 364. wiz_wish	/* Unlimited wishes for debug mode by Paul Polderman */ 365. {  366.  	if (wizard) { 367. 	    makewish; 368. 	    (void) encumber_msg; 369. 	} else 370. 	    pline("Unavailable command '^W'."); 371. 	return 0; 372. }  373.   374.  STATIC_PTR int 375. wiz_identify 376. {  377.  	struct obj *obj; 378.  379.  	if (!wizard) 380. 		pline("Unavailable command '^I'."); 381. 	else { 382. 		for (obj = invent; obj; obj = obj->nobj) 383. 			if (!objects[obj->otyp].oc_name_known || !obj->known  384.  						|| !obj->dknown || !obj->bknown) 385. 				(void) identify(obj); 386. 	}  387.  	return 0; 388. }  389.   390.  STATIC_PTR int 391. wiz_map 392. {  393.  	if (wizard)	do_mapping; 394. 	else		pline("Unavailable command '^F'."); 395. 	return 0; 396. }  397.   398.  STATIC_PTR int 399. wiz_genesis 400. {  401.  	if (wizard)	(void) create_particular; 402. 	else		pline("Unavailable command '^G'."); 403. 	return 0; 404. }  405.   406.  STATIC_PTR int 407. wiz_where 408. {  409.  	if (wizard) print_dungeon; 410. 	else	    pline("Unavailable command '^O'."); 411. 	return 0; 412. }  413.   414.  STATIC_PTR int 415. wiz_detect 416. {  417.  	if(wizard)  (void) findit; 418. 	else	    pline("Unavailable command '^E'."); 419. 	return 0; 420. }  421.   422.  STATIC_PTR int 423. wiz_level_tele 424. {  425.  	if (wizard)	level_tele; 426. 	else		pline("Unavailable command '^V'."); 427. 	return 0; 428. }  429.   430.  #endif /* WIZARD */ 431.  432.  /* -enlightenment- */ 433. static winid en_win; 434. static const char 435. 	*You_ = "You ", 436. 	*are  = "are ",  *were  = "were ", 437. 	*have = "have ", *had   = "had ", 438. 	*can  = "can ",  *could = "could "; 439.  440.  #define enl_msg(prefix,present,past,suffix) \ 441. 			enlght_line(prefix, final ? past : present, suffix) 442. #define you_are(attr)	enl_msg(You_,are,were,attr) 443. #define you_have(attr)	enl_msg(You_,have,had,attr) 444. #define you_can(attr)	enl_msg(You_,can,could,attr) 445.  446.  static void 447. enlght_line(start, middle, end) 448. const char *start, *middle, *end; 449. {  450.  	char buf[BUFSZ]; 451.  452.  	Sprintf(buf, "%s%s%s.", start, middle, end); 453. 	putstr(en_win, 0, buf); 454. }  455.   456.  void 457. enlightenment(final) 458. boolean final; 459. {  460.  	int ltmp; 461. 	char buf[BUFSZ]; 462.  463.  	en_win = create_nhwindow(NHW_MENU); 464. 	putstr(en_win, 0, final ? "Final Attributes:" : "Current Attributes:"); 465. 	putstr(en_win, 0, ""); 466.  467.  	/* note: piousness 20 matches MIN_QUEST_ALIGN (quest.h) */ 468. 	if (u.ualign.record >= 20)	you_are("piously aligned"); 469. 	else if (u.ualign.record > 13)	you_are("devoutly aligned"); 470. 	else if (u.ualign.record > 8)	you_are("fervently aligned"); 471. 	else if (u.ualign.record > 3)	you_are("stridently aligned"); 472. 	else if (u.ualign.record == 3)	you_are("aligned"); 473. 	else if (u.ualign.record > 0)	you_are("haltingly aligned"); 474. 	else if (u.ualign.record == 0)	you_are("nominally aligned"); 475. 	else if (u.ualign.record >= -3)	you_have("strayed"); 476. 	else if (u.ualign.record >= -8)	you_have("sinned"); 477. 	else you_have("transgressed"); 478. #ifdef WIZARD 479. 	if (wizard) { 480. 		Sprintf(buf, " %d", u.ualign.record); 481. 		enl_msg("Your alignment ", "is", "was", buf); 482. 	}  483.  #endif 484.  485.  	if (Telepat) you_are("telepathic"); 486. 	if (Searching) you_have("automatic searching"); 487. 	if (Teleportation) you_can("teleport"); 488. 	if (Teleport_control) you_have("teleport control"); 489. 	if (See_invisible) enl_msg(You_, "see", "saw", " invisible"); 490. 	if (Invisible) you_are("invisible"); 491. 	else if (Invis) you_are("invisible to others"); 492. 	if (Fast) you_are((Fast & ~INTRINSIC) ? "very fast" : "fast"); 493. 	if (Stealth) you_are("stealthy"); 494. 	if (Regeneration) enl_msg("You regenerate", "", "d", ""); 495. 	if (Hunger) you_have("hunger"); 496. 	if (Conflict) enl_msg("You cause", "", "d", " conflict"); 497. 	if (Aggravate_monster) enl_msg("You aggravate", "", "d", " monsters"); 498. 	if (Poison_resistance) you_are("poison resistant"); 499. 	if (Fire_resistance) you_are("fire resistant"); 500. 	if (Cold_resistance) you_are("cold resistant"); 501. 	if (Shock_resistance) you_are("shock resistant"); 502. 	if (Sleep_resistance) you_are("sleep resistant"); 503. 	if (Disint_resistance) you_are("disintegration-resistant"); 504. 	if (Protection_from_shape_changers) 505. 		you_are("protected from shape changers"); 506. #ifdef POLYSELF 507. 	if (Polymorph) you_are("polymorphing"); 508. 	if (Polymorph_control) you_have("polymorph control"); 509. #endif 510. 	if (HHalluc_resistance) 511. 		enl_msg("You resist", "", "ed", " hallucinations"); 512. 	if (final) { 513. 		if (Hallucination) you_are("hallucinating"); 514. 		if (Stunned) you_are("stunned"); 515. 		if (Confusion) you_are("confused"); 516. 		if (Sick) you_are("sick"); 517. 		if (Blinded) you_are("blinded"); 518. 	}  519.  	if (Wounded_legs) { 520. 		Sprintf(buf, "wounded %s", makeplural(body_part(LEG))); 521. 		you_have(buf); 522. 	}  523.  	if (Glib) { 524. 		Sprintf(buf, "slippery %s", makeplural(body_part(FINGER))); 525. 		you_have(buf); 526. 	}  527.  	if (Strangled) you_are("being strangled"); 528. 	if (Stoned) you_are("turning to stone"); 529. 	if (Lifesaved) 530. 		enl_msg("Your life ", "will be", "would have been", " saved"); 531. 	if (Adornment) you_are("adorned"); 532. 	if (Warning) you_are("warned"); 533. 	if (Protection) you_are("protected"); 534. 	if (Reflecting) you_have("reflection"); 535. 	if (Levitation) you_are("levitating"); 536. 	if (Fumbling) enl_msg("You fumble", "", "d", ""); 537. 	if (Jumping) you_can("jump"); 538. 	if (Wwalking) you_can("walk on water"); 539. 	if (Magical_breathing) you_can("survive without air"); 540. 	if (Antimagic) you_are("magic-protected"); 541. 	if (Displaced) you_are("displaced"); 542. 	if (Clairvoyant) you_are("clairvoyant"); 543. #ifdef POLYSELF 544. 	if (u.ulycn != -1) { 545. 		Strcpy(buf, an(mons[u.ulycn].mname)); 546. 		you_are(buf); 547. 	}  548.  #endif 549. 	if (Luck) { 550. 	    ltmp = abs((int)Luck); 551. 	    Sprintf(buf, "%s%slucky",  552.  		    ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "",  553.  		    Luck < 0 ? "un" : ""); 554. #ifdef WIZARD 555. 	    if (wizard) Sprintf(eos(buf), " (%d)", Luck); 556. #endif 557. 	    you_are(buf); 558. 	}  559.  #ifdef WIZARD 560. 	 else if (wizard) enl_msg("Your luck ", "is", "was", " zero"); 561. #endif 562. 	ltmp = stone_luck(TRUE); 563. 	if (ltmp > 0) you_have("extra luck"); 564. 	else if (ltmp < 0) you_have("reduced luck"); 565. 	if (carrying(LUCKSTONE)) { 566. 	    ltmp = stone_luck(FALSE); 567. 	    if (ltmp <= 0) 568. 		enl_msg("Bad luck ", "does", "did", " not time out for you"); 569. 	    if (ltmp >= 0) 570. 		enl_msg("Good luck ", "does", "did", " not time out for you"); 571. 	}  572.   573.  	display_nhwindow(en_win, TRUE); 574. 	destroy_nhwindow(en_win); 575. 	return; 576. }  577.   578.  #if defined(WIZARD) || defined(EXPLORE_MODE) 579. STATIC_PTR int 580. wiz_attributes 581. {  582.  	if (wizard || discover) 583. 		enlightenment(FALSE); 584. 	else 585. 		pline("Unavailable command '^X'."); 586. 	return 0; 587. }  588.  #endif /* WIZARD || EXPLORE_MODE */ 589.  590.  #endif /* OVLB */ 591. #ifdef OVL1 592.  593.  #ifndef M  594. # ifndef NHSTDC 595. #  define M(c)		(0x80 | (c)) 596. # else 597. #  define M(c)		((c) - 128) 598. # endif /* NHSTDC */ 599. #endif 600. #ifndef C  601. #define C(c)		(0x1f & (c)) 602. #endif 603.  604.  static const struct func_tab cmdlist[] = { 605. 	{C('d'), dokick},	/* "D" is for door!...? */ 606.  #ifdef WIZARD 607. 	{C('e'), wiz_detect}, 608. 	{C('f'), wiz_map}, 609. 	{C('g'), wiz_genesis}, 610. 	{C('i'), wiz_identify}, 611. #endif 612. 	{C('l'), doredraw}, /* if number_pad is set */ 613. #ifdef WIZARD 614. 	{C('o'), wiz_where}, 615. #endif 616. 	{C('p'), doprev_message}, 617. 	{C('r'), doredraw}, 618. 	{C('t'), dotele}, 619. #ifdef WIZARD 620. 	{C('v'), wiz_level_tele}, 621. 	{C('w'), wiz_wish}, 622. #endif 623. #if defined(WIZARD) || defined(EXPLORE_MODE) 624. 	{C('x'), wiz_attributes}, 625. #endif 626. #ifdef SUSPEND 627. 	{C('z'), dosuspend}, 628. #endif 629. 	{'a', doapply}, 630. 	{'A', doddoremarm}, 631. 	{M('a'), doorganize}, 632. /*	'b', 'B' : go sw */ 633. 	{'c', doclose}, 634. 	{'C', do_mname}, 635. 	{M('c'), dotalk}, 636. 	{'d', dodrop}, 637. 	{'D', doddrop}, 638. 	{M('d'), dodip}, 639. 	{'e', doeat}, 640. 	{'E', doengrave}, 641. /* Soon to be  642. {'f', dofight, "fighting"}, 643. 	{'F', doFight, "fighting"}, 644.  */  645.  	{M('f'), doforce}, 646. /*	'g', 'G' : multiple go */ 647. /*	'h', 'H' : go west */ 648. 	{'h', dohelp}, /* if number_pad is set */ 649. 	{'i', ddoinv}, 650. 	{'I', dotypeinv},		/* Robert Viduya */ 651. 	{M('i'), doinvoke}, 652. /*	'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */ 653. 	{'j', dojump}, /* if number_pad is on */ 654. 	{M('j'), dojump}, 655. 	{'k', dokick}, /* if number_pad is on */ 656. 	{'l', doloot}, /* if number_pad is on */ 657. 	{M('l'), doloot}, 658. /*	'n' prefixes a count if number_pad is on */ 659. #ifdef POLYSELF 660. 	{M('m'), domonability}, 661. #endif /* POLYSELF */ 662. 	{'N', ddocall}, /* if number_pad is on */ 663. 	{M('N'), ddocall}, 664. 	{'o', doopen}, 665. 	{'O', doset}, 666. 	{M('o'), dosacrifice}, 667. 	{'p', dopay}, 668. 	{'P', doputon}, 669. 	{M('p'), dopray}, 670. 	{'q', dodrink}, 671. 	{'Q', done2}, 672. 	{'r', doread}, 673. 	{'R', doremring}, 674. 	{M('r'), dorub}, 675. 	{'s', dosearch, "searching"}, 676. 	{'S', dosave}, 677. 	{M('s'), dosit}, 678. 	{'t', dothrow}, 679. 	{'T', dotakeoff}, 680. 	{M('t'), doturn}, 681. /*	'u', 'U' : go ne */ 682. 	{'u', dountrap}, /* if number_pad is on */ 683. 	{M('u'), dountrap}, 684. 	{'v', doversion}, 685. 	{'V', dohistory}, 686. 	{M('v'), doextversion}, 687. 	{'w', dowield}, 688. 	{'W', dowear}, 689. 	{M('w'), dowipe}, 690. 	{'x', dovspell},			/* Mike Stephenson */ 691. #ifdef EXPLORE_MODE 692. 	{'X', enter_explore_mode}, 693. #endif 694. /*	'y', 'Y' : go nw */ 695. 	{'z', dozap}, 696. 	{'Z', docast}, 697. 	{'<', doup}, 698. 	{'>', dodown}, 699. 	{'/', dowhatis}, 700. 	{'&', dowhatdoes}, 701. 	{'?', dohelp}, 702. #ifdef SHELL 703. 	{'!', dosh}, 704. #endif 705. 	{'.', donull, "waiting"}, 706. 	{' ', donull, "waiting"}, 707. 	{',', dopickup}, 708. 	{':', dolook}, 709. 	{';', doquickwhatis}, 710. 	{'^', doidtrap}, 711. 	{'\\', dodiscovered},		/* Robert Viduya */ 712. 	{'@', dotogglepickup}, 713. 	{WEAPON_SYM,  doprwep}, 714. 	{ARMOR_SYM,  doprarm}, 715. 	{RING_SYM,  doprring}, 716. 	{AMULET_SYM, dopramulet}, 717. 	{TOOL_SYM, doprtool}, 718. 	{GOLD_SYM, doprgold}, 719. 	{SPBOOK_SYM, dovspell},			/* Mike Stephenson */ 720. 	{'#', doextcmd}, 721. 	{0,0,0}  722.  };  723.  #undef M  724. 725. const struct ext_func_tab extcmdlist[] = { 726. 	{"adjust", "adjust inventory letters", doorganize}, 727. 	{"chat", "talk to someone", dotalk},	/* converse? */ 728.  	{"dip", "dip an object into something", dodip}, 729. 	{"force", "force a lock", doforce}, 730. 	{"invoke", "invoke an object's powers", doinvoke}, 731. 	{"jump", "jump to a location", dojump}, 732. 	{"loot", "loot a box on the floor", doloot}, 733. #ifdef POLYSELF 734. 	{"monster", "use a monster's special ability", domonability}, 735. #endif 736. 	{"name", "name an item or type of object", ddocall}, 737. 	{"offer", "offer a sacrifice to the gods", dosacrifice}, 738. 	{"pray", "pray to the gods for help", dopray}, 739. 	{"rub", "rub a lamp", dorub}, 740. 	{"sit", "sit down", dosit}, 741. 	{"turn", "turn undead", doturn}, 742. 	{"untrap", "untrap something", dountrap}, 743. 	{"version", "list compile time options for this version of NetHack", 744. 		doextversion}, 745. #ifdef MAC 746. 	{"window", "clean up windows", SanePositions}, 747. #endif 748. 	{"wipe", "wipe off your face", dowipe}, 749. 	{"?", "get this list of extended commands", doextlist}, 750. 	{NULL, NULL, donull} 751. };  752.   753.  #define unctrl(c)	((c) <= C('z') ? (0x60 | (c)) : (c)) 754. #define unmeta(c)	(0x7f & (c)) 755.  756.   757.  void 758. rhack(cmd) 759. register char *cmd; 760. {  761.  	register const struct func_tab *tlist = cmdlist; 762. 	boolean firsttime = FALSE; 763. 	register int res; 764.  765.  	if(!cmd) { 766. 		firsttime = TRUE; 767. 		flags.nopick = 0; 768. 		cmd = parse; 769. 	}  770.  	if(*cmd == (char)033) { 771. 		flags.move = 0; 772. 		return; 773. 	}  774.  #ifdef REDO 775. 	if (*cmd == DOAGAIN && !in_doagain && saveq[0]) { 776. 		in_doagain = TRUE; 777. 		stail = 0; 778. 		rhack(NULL);	/* read and execute command */ 779. 		in_doagain = FALSE; 780. 		return; 781. 	}  782.  	/* Special case of *cmd == ' ' handled better below */ 783. 	if(!*cmd || *cmd == (char)0377) { 784. #else 785. 	if(!*cmd || *cmd == (char)0377 ||  786.  	   (!flags.rest_on_space && *cmd == ' ')) { 787. #endif 788. 		nhbell; 789. 		flags.move = 0; 790. 		return;		/* probably we just had an interrupt */ 791. 	}  792.  	if(movecmd(*cmd)) { 793. 	walk: 794. 		if(multi) flags.mv = 1; 795. 		domove; 796. 		return; 797. 	}  798.  	if(movecmd(flags.num_pad ? unmeta(*cmd) : lowc(*cmd))) { 799. 		flags.run = 1; 800. 	rush: 801. 		if(firsttime){ 802. 			if(!multi) multi = COLNO; 803. 			u.last_str_turn = 0; 804. 		}  805.  		flags.mv = 1; 806. 		domove; 807. 		return; 808. 	}  809.  	if(*cmd == 'g' && movecmd(cmd[1])) { 810. 		flags.run = 2; 811. 		goto rush; 812. 	}  813.  	if (((*cmd == 'G' || (flags.num_pad && *cmd == '5')) && 814. 	    movecmd(lowc(cmd[1]))) || movecmd(unctrl(*cmd))) { 815. 		flags.run = 3; 816. 		goto rush; 817. 	}  818.  	if((*cmd == 'm' || (flags.num_pad && *cmd == '-')) &&  819.  	    movecmd(cmd[1])) { 820. 		flags.run = 0; 821. 		flags.nopick = 1; 822. 		goto walk; 823. 	}  824.  	if(*cmd == 'M' && movecmd(lowc(cmd[1]))) { 825. 		flags.run = 1; 826. 		flags.nopick = 1; 827. 		goto rush; 828. 	}  829.  	if (flags.num_pad && *cmd == '0') { 830. 		(void)ddoinv;	/* A convenience borrowed from the PC */ 831. 		flags.move = 0; 832. 		multi = 0; 833. 		return; 834. 	}  835.  	while(tlist->f_char) { 836. 		if((*cmd & 0xff) == (tlist->f_char & 0xff)){ 837. 			/* Special case of *cmd == ' ' handled here */ 838. 			if (*cmd == ' ' && !flags.rest_on_space) 839. 				break; 840.  841.  			/* Now control-A can stop lengthy commands */ 842. 			/* in the PC version only -- use ^C-N otherwise */ 843. 			if (tlist->f_text && !occupation && multi) 844. #ifdef GCC_WARN 845. 				set_occupation(tlist->f_funct,  846.  						tlist->f_text, multi); 847. #else 848. 				set_occupation(((struct func_tab *)tlist)->f_funct,  849.  					tlist->f_text, multi); 850. #endif 851. 			res = (*(tlist->f_funct)); 852. 			if(!res) { 853. 				flags.move = 0; 854. 				multi = 0; 855. 			}  856.  			return; 857. 		}  858.  		tlist++; 859. 	}  860.  	{ char expcmd[10]; 861. 	  register char *cp = expcmd; 862. 	  while(*cmd && cp-expcmd < sizeof(expcmd)-2) { 863. 		if(*cmd >= 040 && *cmd < 0177) 864. 			*cp++ = *cmd++; 865. 		else if (*cmd & 0200) { 866. 			*cp++ = 'M'; 867. 			*cp++ = '-'; 868. 			*cp++ = *cmd++ &=~ 0200; 869. 		}  870.  		else { 871. 			*cp++ = '^'; 872. 			*cp++ = *cmd++ ^ 0100; 873. 		}  874.  	  }  875.  	  *cp = 0; 876. 	  Norep("Unknown command '%s'.", expcmd); 877. 	}  878.  	multi = flags.move = 0; 879. 	return; 880. }  881.   882.  int 883. xytod(x, y)	/* convert an x,y pair into a direction code */ 884. schar x, y;  885. { 886.  	register int dd; 887.  888.  	for(dd = 0; dd < 8; dd++) 889. 	    if(x == xdir[dd] && y == ydir[dd]) return dd; 890.  891.  	return -1; 892. }  893.   894.  #ifdef WALKIES 895. void 896. dtoxy(cc,dd)	/* convert a direction code into an x,y pair */ 897. coord *cc; 898. register int dd; 899. {  900.  	cc->x = xdir[dd]; 901. 	cc->y = ydir[dd]; 902. 	return; 903. }  904.  #endif /* WALKIES */ 905.  906.  int 907. movecmd(sym)	/* also sets u.dz, but returns false for <> */ 908. char sym; 909. {  910.  	register const char *dp; 911. 	register const char *sdp = flags.num_pad ? ndir : sdir; 912.  913.  	u.dz = 0; 914. 	if(!(dp = index(sdp, sym))) return 0; 915. 	u.dx = xdir[dp-sdp]; 916. 	u.dy = ydir[dp-sdp]; 917. 	u.dz = zdir[dp-sdp]; 918. #ifdef POLYSELF 919. 	if (u.dx && u.dy && u.umonnum == PM_GRID_BUG) { 920. 		u.dx = u.dy = 0; 921. 		return 0; 922. 	}  923.  #endif 924. 	return !u.dz; 925. }  926.   927.  int 928. getdir(s) 929. const char *s; 930. {  931.  	char dirsym; 932.  933.  #ifdef REDO 934. 	if(in_doagain) 935. 	    dirsym = readchar; 936. 	else 937. #endif 938. 	    dirsym = yn_function (s ? s : "In what direction?", NULL, '\0'); 939. #ifdef REDO 940. 	savech(dirsym); 941. #endif 942. 	if(dirsym == '.' || dirsym == 's') 943. 		u.dx = u.dy = u.dz = 0; 944. 	else if(!movecmd(dirsym) && !u.dz) { 945. 		if(!index(quitchars, dirsym)) 946. 			pline("What a strange direction!"); 947. 		return 0; 948. 	}  949.  	if(!u.dz && (Stunned || (Confusion && !rn2(5)))) confdir; 950. 	return 1; 951. }  952.   953.  #endif /* OVL1 */ 954. #ifdef OVLB 955.  956.  void 957. confdir 958. {  959.  	register int x = 960. #ifdef POLYSELF 961. 		(u.umonnum == PM_GRID_BUG) ? 2*rn2(4) : 962. #endif 963. 							rn2(8); 964. 	u.dx = xdir[x]; 965. 	u.dy = ydir[x]; 966. 	return; 967. }  968.   969.  #endif /* OVLB */ 970. #ifdef OVL0 971.  972.  int 973. isok(x,y) 974. register int x, y;  975. { 976.  	/* x corresponds to curx, so x==1 is the first column. Ach. %% */ 977.  	return x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1; 978. }  979.   980.  static int NEARDATA last_multi; 981.  982.  /*  983.   * convert a MAP window position into a movecmd 984.  */  985.  static int 986. click_to_cmd(x, y, mod) 987.     int x, y, mod; 988. {  989.      x -= u.ux; 990.     y -= u.uy; 991.     /* convert without using floating point, allowing sloppy clicking */ 992.     if(x > 2*abs(y)) 993. 	x = 1, y = 0; 994.     else if(y > 2*abs(x)) 995. 	x = 0, y = 1; 996.     else if(x < -2*abs(y)) 997. 	x = -1, y = 0; 998.     else if(y < -2*abs(x)) 999. 	x = 0, y = -1; 1000.    else 1001. 	x = sgn(x), y = sgn(y); 1002. 1003.     if(x == 0 && y == 0)	/* map click on player to "rest" command */ 1004. 	return '.'; 1005. 1006.     x = xytod(x, y); 1007.    if(mod == CLICK_1) { 1008. 	return (flags.num_pad ? ndir[x] : sdir[x]); 1009.    } else { 1010. 	return (sdir[x] - 'a' + 'A'); /* run command */ 1011.    }  1012. }  1013.  1014. STATIC_OVL char * 1015. parse 1016. { 1017. #ifdef LINT	/* static char in_line[COLNO]; */ 1018. 	char in_line[COLNO]; 1019. #else 1020. 	static char in_line[COLNO]; 1021. #endif 1022. 	register int foo; 1023. 	boolean prezero = FALSE; 1024. 1025. 	multi = 0; 1026. 	flags.move = 1; 1027. 	flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */ 1028.  1029. 	if (!flags.num_pad || (foo = readchar) == 'n') 1030. 	   for  { 1031. 		foo = readchar; 1032. 		if (foo >= '0' && foo <= '9') { 1033. 		   multi = 10 * multi + foo - '0'; 1034. 		   if (multi < 0 || multi > LARGEST_INT) multi = LARGEST_INT; 1035. 		   if (multi > 9) { 1036. 			clear_nhwindow(WIN_MESSAGE); 1037. 			Sprintf(in_line, "Count: %d", multi); 1038. 			pline(in_line); 1039. 			mark_synch; 1040. 		   }  1041. 		    last_multi = multi; 1042. 		   if (!multi && foo == '0') prezero = TRUE; 1043. 		} else break;	/* not a digit */ 1044. 	   }  1045.  1046. 	if (foo == '\033') {   /* esc cancels count (TH) */ 1047. 	   clear_nhwindow(WIN_MESSAGE); 1048. 	   multi = last_multi = 0; 1049. # ifdef REDO 1050. 	} else if (foo == DOAGAIN || in_doagain) { 1051. 	   multi = last_multi; 1052. 	} else { 1053. 	   last_multi = multi; 1054. 	   savech(0);	/* reset input queue */ 1055. 	   savech((char)foo); 1056. # endif 1057. 	} 1058.  1059. 	if (multi) { 1060. 	   multi--; 1061. 	   save_cm = in_line; 1062. 	} else { 1063. 	   save_cm = NULL; 1064. 	} 1065. 	in_line[0] = foo; 1066. 	in_line[1] = '\0'; 1067. 	if (foo == 'g' || foo == 'G' || (flags.num_pad && foo == '5') || 1068. 	    foo == 'm' || foo == 'M') { 1069. 	   foo = readchar; 1070. #ifdef REDO 1071. 	   savech((char)foo); 1072. #endif 1073. 	   in_line[1] = foo; 1074. 	   in_line[2] = 0; 1075. 	} 1076. 	clear_nhwindow(WIN_MESSAGE); 1077. 	if (prezero) in_line[0] = '\033'; 1078. 	return(in_line); 1079. } 1080.  1081. #endif /* OVL0 */ 1082. #ifdef OVLB 1083. 1084. #ifdef UNIX 1085. static 1086. void 1087. end_of_input 1088. { 1089. 	exit_nhwindows("End of input?"); 1090. #ifndef NOSAVEONHANGUP 1091. 	if(!hu) { 1092. 	   hu = TRUE; 1093. 	   (void) dosave0; 1094. 	} 1095. #endif 1096. 	clearlocks; 1097. 	terminate(0); 1098. } 1099. #endif 1100. 1101. #endif /* OVLB */ 1102. #ifdef OVL0 1103. 1104. char 1105. readchar 1106. { 1107. 	register int sym; 1108. 	int x, y, mod; 1109. 1110. #ifdef REDO 1111. 	sym = in_doagain ? Getchar : nh_poskey(&x, &y, &mod); 1112. #else 1113. 	sym = Getchar; 1114. #endif 1115. 1116. #ifdef UNIX 1117. # ifdef NR_OF_EOFS 1118. 	if (sym == EOF) { 1119. 	   register int cnt = NR_OF_EOFS; 1120. 	 /*  1121. 	   * Some SYSV systems seem to return EOFs for various reasons 1122. 	  * (?like when one hits break or for interrupted systemcalls?), 1123. 	  * and we must see several before we quit. 1124. 	  */  1125. 	    do { 1126. 		clearerr(stdin);	/* omit if clearerr is undefined */ 1127. 		sym = Getchar; 1128. 	   } while (--cnt && sym == EOF); 1129. 	} 1130. # endif /* NR_OF_EOFS */ 1131. 	if (sym == EOF) 1132. 	   end_of_input; 1133. #endif /* UNIX */ 1134. 1135. 	if(sym == 0) /* click event */ 1136. 	   sym = click_to_cmd(x, y, mod); 1137. 	return((char) sym); 1138. } 1139. #endif /* OVL0 */ 1140. 1141. /*cmd.c*/