Source:NetHack 3.0.0/cmd.c

Below is the full text to cmd.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.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.0	88/10/24 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.   #ifdef DUMB	/* stuff commented out in extern.h, but needed here */ 9.   extern int doapply; /**/ 10.  extern int dorub; /**/ 11.  extern int dojump; /**/ 12.  extern int doextlist; /**/ 13.  extern int dodrop; /**/ 14.  extern int doddrop; /**/ 15.  extern int dodown; /**/ 16.  extern int doup; /**/ 17.  extern int donull; /**/ 18.  extern int dowipe; /**/ 19.  extern int do_mname; /**/ 20.  extern int ddocall; /**/ 21.  extern int dotakeoff; /**/ 22.  extern int doremring; /**/ 23.  extern int dowear; /**/ 24.  extern int doputon; /**/ 25.  extern int doddoremarm; /**/ 26.  extern int dokick; /**/ 27.  extern int dothrow; /**/ 28.  extern int doeat; /**/ 29.  extern int done2; /**/ 30.  extern int doengrave; /**/ 31.  extern int dopickup; /**/ 32.  extern int ddoinv; /**/ 33.  extern int dotypeinv; /**/ 34.  extern int dolook; /**/ 35.  extern int doprgold; /**/ 36.  extern int doprwep; /**/ 37.  extern int doprarm; /**/ 38.  extern int doprring; /**/ 39.  extern int dopramulet; /**/ 40.  extern int doprtool; /**/ 41.  extern int dosuspend; /**/ 42.  extern int doforce; /**/ 43.  extern int doopen; /**/ 44.  extern int doclose; /**/ 45.  extern int dosh; /**/ 46.  extern int dodiscovered; /**/ 47.  extern int doset; /**/ 48.  extern int dotogglepickup; /**/ 49.  extern int dowhatis; /**/ 50.  extern int dowhatdoes; /**/ 51.  extern int dohelp; /**/ 52.  extern int dohistory; /**/ 53.  extern int dosh; /**/ 54.  extern int doloot; /**/ 55.  extern int dodrink; /**/ 56.  extern int dodip; /**/ 57.  extern int dosacrifice; /**/ 58.  extern int dopray; /**/ 59.  extern int doturn; /**/ 60.  extern int doredraw; /**/ 61.  extern int doread; /**/ 62.  extern int dosave; /**/ 63.  extern int dosave0; /**/ 64.  extern int dosearch; /**/ 65.  extern int dosearch0 P((int)); /**/ 66.  extern int doidtrap; /**/ 67.  extern int dopay; /**/ 68.  extern int dosit; /**/ 69.  extern int dotalk; /**/ 70.  extern int docast; /**/ 71.  extern int dovspell; /**/ 72.  extern int doredotopl; /**/ 73.  extern int dotele; /**/ 74.  extern int dountrap; /**/ 75.  extern int doversion; /**/ 76.  extern int dowield; /**/ 77.  extern int dozap; /**/ 78.  #endif /* DUMB */ 79.   80.   static int (*timed_occ_fn); 81.  #ifdef POLYSELF 82.  static int domonability; 83.  #endif 84.   85.   /* Count down by decrementing multi */ 86.  static int 87.  timed_occupation { 88.  	(*timed_occ_fn); 89.  	if (multi > 0) 90.  		multi--; 91.  	return multi > 0; 92.  }  93.    94.   /* If a time is given, use it to timeout this function, otherwise the 95.   * function times out by its own means. 96.   */  97.   void 98.  set_occupation(fn, txt, xtime) 99.  int (*fn); 100. char *txt; 101. int xtime; 102. {  103.  	if (xtime) { 104. 		occupation = timed_occupation; 105. 		timed_occ_fn = fn; 106. 	} else 107. 		occupation = fn; 108. 	occtxt = txt; 109. 	occtime = 0; 110. 	return; 111. }  112.   113.  #ifdef REDO 114. /* Provide a means to redo the last command. The flag `in_doagain' is set 115.  * to true while redoing the command. This flag is tested in commands that 116.  * require additional input (like `throw' which requires a thing and a  117.   * direction), and the input prompt is not shown. Also, while in_doagain is 118. * TRUE, no keystrokes can be saved into the saveq. 119.  */  120.  #define BSIZE 20 121. static char pushq[BSIZE], saveq[BSIZE]; 122. static int phead, ptail, shead, stail; 123.  124.  static char 125. popch { 126. 	/* If occupied, return 0, letting tgetch know a character should 127. 	 * be read from the keyboard. If the character read is not the 128. 	 * ABORT character (as checked in pcmain.c), that character will be  129. * pushed back on the pushq. 130. 	 */  131.  	if (occupation) return 0; 132. 	if (in_doagain) return (shead != stail) ? saveq[stail++] : 0; 133. 	else		return (phead != ptail) ? pushq[ptail++] : 0; 134. }  135.   136.  char 137. pgetchar {		/* curtesy of aeb@cwi.nl */ 138. 	register int ch; 139.  140.  	if(!(ch = popch)) 141. 		ch = tgetch; 142. 	return(ch); 143. }  144.   145.  /* A ch == 0 resets the pushq */ 146. void 147. pushch(ch) 148. char ch; 149. {  150.  	if (!ch) 151. 		phead = ptail = 0; 152. 	if (phead < BSIZE) 153. 		pushq[phead++] = ch; 154. 	return; 155. }  156.   157.  /* A ch == 0 resets the saveq. Only save keystrokes when not 158.  * replaying a previous command. 159.  */  160.  void 161. savech(ch) 162. char ch; 163. {  164.  	if (!in_doagain) { 165. 		if (!ch) 166. 			phead = ptail = shead = stail = 0; 167. 		else if (shead < BSIZE) 168. 			saveq[shead++] = ch; 169. 	}  170.  	return; 171. }  172.  #endif /* REDO */ 173.  174.  static int 175. doextcmd	/* here after # - now read a full-word command */ 176. {  177.  	char buf[BUFSZ]; 178. 	register struct ext_func_tab *efp = extcmdlist; 179. again: 180. 	pline("# "); 181. #ifdef COM_COMPL 182. 	get_ext_cmd(buf); 183. #else 184. 	getlin(buf); 185. #endif 186. 	clrlin; 187. 	if(buf[0] == '\0' || buf[0] == '\033') 188. 		return 0; 189. 	if(buf[0] == '?') { 190. 		(void) doextlist; 191. 		goto again; 192. 	}  193.  	while(efp->ef_txt) { 194. 		if(!strcmp(efp->ef_txt, buf)) 195. 			return (*(efp->ef_funct)); 196. 		efp++; 197. 	}  198.  	pline("%s: unknown extended command.", buf); 199. 	return 0; 200. }  201.   202.  int 203. doextlist	/* here after #? - now list all full-word commands */ 204. {  205.  	register struct ext_func_tab *efp = extcmdlist; 206. 	char     buf[BUFSZ]; 207.  208.  	set_pager(0); 209. 	if(page_line("") ||  210.  	   page_line("            Extended Commands List") ||  211.  	   page_line("") ||  212.  	   page_line("    Press '#', then type (first letter only):") ||  213.  	   page_line(""))					 goto quit; 214.  215.  	while(efp->ef_txt) { 216.  217.  		Sprintf(buf, "    %-8s  - %s.", efp->ef_txt, efp->ef_desc); 218. 		if(page_line(buf)) goto quit; 219. 		efp++; 220. 	}  221.  	set_pager(1); 222. 	return 0; 223. quit: 224. 	set_pager(2); 225. 	return 0; 226. }  227.   228.  #ifdef POLYSELF 229. static int 230. domonability 231. {  232.  	if (can_breathe(uasmon)) return dobreathe; 233. 	else if (attacktype(uasmon, AT_SPIT)) return dospit; 234. 	else if (u.usym == S_NYMPH) return doremove; 235. 	else if (u.usym == S_UMBER) return doconfuse; 236. 	else if (is_were(uasmon)) return dosummon; 237. 	else if (webmaker(uasmon)) return dospinweb; 238. 	else if (is_hider(uasmon)) return dohide; 239. 	else if (u.umonnum >= 0) 240. 		pline("Any special ability you may have is purely reflexive."); 241. 	else You("don't have a special ability!"); 242. 	return 0; 243. }  244.  #endif 245.  246.  #ifdef WIZARD 247. static int 248. wiz_wish	/* Unlimited wishes for wizard mode by Paul Polderman */ 249. {  250.  	if (wizard)	makewish; 251. 	else		pline("Unavailable command '^W'."); 252. 	return 0; 253. }  254.   255.  static int 256. wiz_identify 257. {  258.  	struct obj *obj; 259.  260.  	if (!wizard) 261. 		pline("Unavailable command '^I'."); 262. 	else { 263. 		for (obj = invent; obj; obj = obj->nobj) 264. 			if (!objects[obj->otyp].oc_name_known || !obj->known  265.  						|| !obj->dknown || !obj->bknown) 266. 				(void) identify(obj); 267. 	}  268.  	return 0; 269. }  270.   271.  static int 272. wiz_map 273. {  274.  	if (wizard)	do_mapping; 275. 	else		pline("Unavailable command '^F'."); 276. 	return 0; 277. }  278.   279.  static int 280. wiz_genesis 281. {  282.  	if (wizard)	(void) create_particular; 283. 	else		pline("Unavailable command '^G'."); 284. 	return 0; 285. }  286.   287.  static int 288. wiz_where 289. {  290.  	if (wizard) { 291. 		pline("Medusa:%d  Wiz:%d  Big:%d", medusa_level, wiz_level, bigroom_level); 292. #ifdef STRONGHOLD 293. #  ifdef MUSIC 294. 		pline("Castle:%d (tune %s)  Tower:%d-%d",  295.  		      stronghold_level, tune, tower_level, tower_level+2); 296. #  else 297. 		pline("Castle:%d  Tower:%d-%d",  298.  		      stronghold_level, tower_level, tower_level+2); 299. #  endif 300. #endif 301. #ifdef REINCARNATION 302. 		pline("Rogue:%d", rogue_level); 303. #endif 304. #ifdef ORACLE 305. 		pline("Oracle:%d", oracle_level); 306. #endif 307. 	}  308.  	else	pline("Unavailable command '^O'."); 309. 	return 0; 310. }  311.   312.  static int 313. wiz_detect 314. {  315.  	if(wizard)  (void) findit; 316. 	else	    pline("Unavailable command '^E'."); 317. 	return 0; 318. }  319.   320.  static int 321. wiz_level_tele 322. {  323.  	if (wizard)	level_tele; 324. 	else		pline("Unavailable command '^V'."); 325. 	return 0; 326. }  327.   328.  #endif /* WIZARD */ 329.  330.  void 331. enlightenment { 332.  333.  	cornline(0, "Current Attributes:"); 334.  335.  	if (u.ualign == 0) cornline(1, "You are nominally aligned."); 336. 	else if (u.ualign > 3) cornline(1, "You are stridently aligned."); 337. 	else if (u.ualign > 0) cornline(1, "You are haltingly aligned."); 338. 	else cornline(1, "You have strayed."); 339.  340.  	if (Adornment) cornline(1, "You are adorned."); 341. 	if (Teleportation) cornline(1, "You can teleport."); 342. 	if (Regeneration) cornline(1, "You regenerate."); 343. 	if (Searching) cornline(1, "You have automatic searching."); 344. 	if (See_invisible) cornline(1, "You see invisible."); 345. 	if (Stealth) cornline(1, "You are stealthy."); 346. 	if (Levitation) cornline(1, "You are levitating."); 347. 	if (Hunger) cornline(1, "You have hunger."); 348. 	if (Aggravate_monster) cornline(1, "You aggravate monsters."); 349. 	if (Poison_resistance) cornline(1, "You are poison resistant."); 350. 	if (Fire_resistance) cornline(1, "You are fire resistant."); 351. 	if (Cold_resistance) cornline(1, "You are cold resistant."); 352. 	if (Shock_resistance) cornline(1, "You are shock resistant."); 353. 	if (Sleep_resistance) cornline(1, "You are sleep resistant."); 354. 	if (Disint_resistance) cornline(1, "You are disintegration-resistant."); 355. 	if (Protection_from_shape_changers) 356. 		cornline(1, "You are protected from shape changers."); 357. 	if (Conflict) cornline(1, "You cause conflict."); 358. 	if (Protection) cornline(1, "You are protected."); 359. 	if (Warning) cornline(1, "You are warned."); 360. 	if (Teleport_control) cornline(1, "You have teleport control."); 361. 	if (Polymorph) cornline(1, "You are polymorphing."); 362. 	if (Polymorph_control) cornline(1, "You have polymorph control."); 363. 	if (Telepat) cornline(1, "You are telepathic."); 364. 	if (Fast) cornline(1, "You are fast."); 365. 	/* if (Stunned) cornline(1, "You are stunned."); */ 366. 	/* if (Confusion) cornline(1, "You are confused."); */ 367. 	/* if (Sick) cornline(1, "You are sick."); */ 368. 	/* if (Blinded) cornline(1, "You are blinded."); */ 369. 	if (Invisible) cornline(1, "You are invisible."); 370. 	else if (Invis) cornline(1, "You are invisible to others."); 371. 	if (Wounded_legs) { 372. 		char buf[41]; 373.  374.  		Sprintf(buf, "You have wounded %s.",  375.  						makeplural(body_part(LEG))); 376. 		cornline(1, buf); 377. 	}  378.  	if (Stoned) cornline(1, "You are turning to stone."); 379. 	/* if (Hallucination) cornline(1, "You are hallucinating."); */ 380. 	if (Glib) { 381. 		char buf[41]; 382.  383.  		Sprintf(buf, "You have slippery %s.",  384.  						makeplural(body_part(FINGER))); 385. 		cornline(1, buf); 386. 	}  387.  	if (Reflecting) cornline(1, "You have reflection."); 388. 	if (Strangled) cornline(1, "You are being strangled."); 389. 	if (Lifesaved) cornline(1, "Your life will be saved."); 390. 	if (Fumbling) cornline(1, "You fumble."); 391. 	if (Jumping) cornline(1, "You can jump."); 392. 	if (Wwalking) cornline(1, "You can walk on water."); 393. 	if (Antimagic) cornline(1, "You are magic-protected."); 394. 	if (Displaced) cornline(1, "You are displaced."); 395. 	if (Clairvoyant) cornline(1, "You are clairvoyant."); 396. 	if (stone_luck(TRUE) > 0) cornline(1, "You have extra luck."); 397. 	if (stone_luck(TRUE) < 0) cornline(1, "You have reduced luck."); 398. 	if (carrying(LUCKSTONE)) { 399. 		if (stone_luck(FALSE) <= 0) 400. 			cornline(1, "Bad luck does not time out for you."); 401. 		if (stone_luck(FALSE) >= 0) 402. 			cornline(1, "Good luck does not time out for you."); 403. 	}  404.   405.  	cornline(2, ""); 406. 	return; 407. }  408.   409.  #if defined(WIZARD) || defined(EXPLORE_MODE) 410. static int 411. wiz_attributes 412. {  413.  	if (wizard || discover) 414. 		enlightenment; 415. 	else 416. 		pline("Unavailable command '^X'."); 417. 	return 0; 418. }  419.  #endif /* WIZARD || EXPLORE_MODE */ 420.  421.  const struct func_tab cmdlist[]={ 422. 	{'\004', /* ^D */ dokick},	/* "D" is for door!...? */ 423.  #ifdef WIZARD 424. 	{'\005', /* ^E */ wiz_detect}, 425. 	{'\006', /* ^F */ wiz_map}, 426. 	{'\007', /* ^G */ wiz_genesis}, 427. 	{'\011', /* ^I */ wiz_identify}, 428. 	{'\017', /* ^O */ wiz_where}, 429. #endif 430. 	{'\020', /* ^P */ doredotopl}, 431. 	{'\022', /* ^R */ doredraw}, 432. 	{'\024', /* ^T */ dotele}, 433. #ifdef WIZARD 434. 	{'\026', /* ^V */ wiz_level_tele}, 435. 	{'\027', /* ^W */ wiz_wish}, 436. #endif 437. #if defined(WIZARD) || defined(EXPLORE_MODE) 438. 	{'\030', /* ^X */ wiz_attributes}, 439. #endif 440. #ifdef SUSPEND 441. 	{'\032', /* ^Z */ dosuspend}, 442. #endif 443. 	{'a', doapply}, 444. 	{'A', doddoremarm}, 445. /*	'b', 'B' : go sw */ 446. 	{'c', doclose}, 447. 	{'C', do_mname}, 448. 	{'d', dodrop}, 449. 	{'D', doddrop}, 450. 	{'e', doeat}, 451. 	{'E', doengrave}, 452. /* Soon to be  453. {'f', dofight, "fighting"}, 454. 	{'F', doFight, "fighting"}, 455.  */  456.  /*	'g', 'G' : multiple go */ 457. /*	'h', 'H' : go west */ 458. 	{'h', dohelp}, /* if number_pad is set */ 459. 	{'i', ddoinv}, 460. 	{'I', dotypeinv},		/* Robert Viduya */ 461. /*	'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */ 462. 	{'j', dojump}, /* if number_pad is on */ 463. 	{'k', dokick}, /* if number_pad is on */ 464. 	{'l', doloot}, /* if number_pad is on */ 465. /*	'n' prefixes a count if number_pad is on */ 466. 	{'N', ddocall}, /* if number_pad is on */ 467. 	{'o', doopen}, 468. 	{'O', doset}, 469. 	{'p', dopay}, 470. 	{'P', doputon}, 471. 	{'q', dodrink}, 472. 	{'Q', done2}, 473. 	{'r', doread}, 474. 	{'R', doremring}, 475. 	{'s', dosearch, "searching"}, 476. 	{'S', dosave}, 477. 	{'t', dothrow}, 478. 	{'T', dotakeoff}, 479. /*	'u', 'U' : go ne */ 480. 	{'u', dountrap}, /* if number_pad is on */ 481. 	{'v', doversion}, 482. 	{'V', dohistory}, 483. 	{'w', dowield}, 484. 	{'W', dowear}, 485. #ifdef SPELLS 486. 	{'x', dovspell},			/* Mike Stephenson */ 487. #endif 488. /*	'y', 'Y' : go nw */ 489. 	{'z', dozap}, 490. #ifdef SPELLS 491. 	{'Z', docast}, 492. #endif 493. 	{'<', doup}, 494. 	{'>', dodown}, 495. 	{'/', dowhatis}, 496. 	{'&', dowhatdoes}, 497. 	{'?', dohelp}, 498. #ifdef SHELL 499. 	{'!', dosh}, 500. #endif 501. 	{'.', donull, "waiting"}, 502. 	{' ', donull, "waiting"}, 503. 	{',', dopickup}, 504. 	{':', dolook}, 505. 	{'^', doidtrap}, 506. 	{'\\', dodiscovered},		/* Robert Viduya */ 507. 	{'@', dotogglepickup}, 508. 	{WEAPON_SYM,  doprwep}, 509. 	{ARMOR_SYM,  doprarm}, 510. 	{RING_SYM,  doprring}, 511. 	{AMULET_SYM, dopramulet}, 512. 	{TOOL_SYM, doprtool}, 513. 	{GOLD_SYM, doprgold}, 514. #ifdef SPELLS 515. 	{SPBOOK_SYM, dovspell},			/* Mike Stephenson */ 516. #endif 517. 	{'#', doextcmd}, 518. 	{0,0,0}  519.  };  520.   521.  const struct ext_func_tab extcmdlist[] = { 522. 	"chat", "talk to someone", dotalk,	/* converse? */ 523.  	"dip", "dip an object into something", dodip, 524. 	"force", "force the lock on a chest", doforce, 525. 	"jump", "jump to a location", dojump, 526. 	"loot", "loot a box on the floor", doloot, 527. #ifdef POLYSELF 528. 	"monster", "use a monster's special ability", domonability, 529. #endif 530. 	"name", "name an item or type of object", ddocall, 531. #ifdef THEOLOGY 532. 	"offer", "offer a sacrifice to the gods", dosacrifice, 533. 	"pray", "pray to the gods for help", dopray, 534. #endif 535. 	"rub", "rub a lamp", dorub, 536. 	"sit", "sit down", dosit, 537. 	"turn", "turn undead", doturn, 538. 	"untrap", "untrap a trapped object", dountrap, 539. 	"wipe", "wipe your face off", dowipe, 540. 	"?", "get this list of extended commands", doextlist, 541. 	NULL, NULL, donull 542. };  543.   544.  char 545. unctrl(sym) 546. char sym; 547. {  548.      return (sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym; 549. }  550.   551.  void 552. rhack(cmd) 553. register char *cmd; 554. {  555.  	register struct func_tab *tlist = cmdlist; 556. 	boolean firsttime = FALSE; 557. 	register int res; 558.  559.  	if(!cmd) { 560. 		firsttime = TRUE; 561. 		flags.nopick = 0; 562. 		cmd = parse; 563. 	}  564.  	if(*cmd == (char)033) { 565. 		flags.move = 0; 566. 		return; 567. 	}  568.  #ifdef REDO 569. 	if (*cmd == DOAGAIN && !in_doagain && saveq[0]) { 570. 		in_doagain = TRUE; 571. 		stail = 0; 572. 		rhack(NULL);	/* read and execute command */ 573. 		in_doagain = FALSE; 574. 		return; 575. 	}  576.  	/* Special case of *cmd == ' ' handled better below */ 577. 	if(!*cmd || *cmd == (char)0377) { 578. #else 579. 	if(!*cmd || *cmd == (char)0377 || (flags.no_rest_on_space && *cmd == ' ')){ 580. #endif 581. 		bell; 582. 		flags.move = 0; 583. 		return;		/* probably we just had an interrupt */ 584. 	}  585.  	if(movecmd(*cmd)) { 586. 	walk: 587. 		if(multi) flags.mv = 1; 588. 		domove; 589. 		return; 590. 	}  591.  	if(!flags.num_pad && movecmd(lowc(*cmd))) { 592. 		flags.run = 1; 593. 	rush: 594. 		if(firsttime){ 595. 			if(!multi) multi = COLNO; 596. 			u.last_str_turn = 0; 597. 		}  598.  		flags.mv = 1; 599. 		domove; 600. 		return; 601. 	}  602.  	if(*cmd == 'g' && movecmd(cmd[1])) { 603. 		flags.run = 2; 604. 		goto rush; 605. 	}  606.  	if(((*cmd == 'G' || (flags.num_pad && *cmd == '5')) && 607. 	    movecmd(lowc(cmd[1]))) || movecmd(unctrl(*cmd))) { 608. 		flags.run = 3; 609. 		goto rush; 610. 	}  611.  	if(*cmd == 'm' && movecmd(cmd[1])) { 612. 		flags.run = 0; 613. 		flags.nopick = 1; 614. 		goto walk; 615. 	}  616.  	if(*cmd == 'M' && movecmd(lowc(cmd[1]))) { 617. 		flags.run = 1; 618. 		flags.nopick = 1; 619. 		goto rush; 620. 	}  621.  	while(tlist->f_char) { 622. 		if(*cmd == tlist->f_char){ 623. 			/* Special case of *cmd == ' ' handled here */ 624. 			if (*cmd == ' ' && flags.no_rest_on_space) 625. 				break; 626.  627.  			/* Now control-A can stop lengthy commands */ 628. 			/* in the PC version only -- use ^C-N otherwise */ 629. 			if (tlist->f_text && !occupation && multi) 630. 				set_occupation(tlist->f_funct, tlist->f_text,  631.  					multi); 632. 			res = (*(tlist->f_funct)); 633. 			if(!res) { 634. 				flags.move = 0; 635. 				multi = 0; 636. 			}  637.  			return; 638. 		}  639.  		tlist++; 640. 	}  641.  	{ char expcmd[10]; 642. 	  register char *cp = expcmd; 643. 	  while(*cmd && cp-expcmd < sizeof(expcmd)-2) { 644. 		if(*cmd >= 040 && *cmd < 0177) 645. 			*cp++ = *cmd++; 646. 		else { 647. 			*cp++ = '^'; 648. 			*cp++ = *cmd++ ^ 0100; 649. 		}  650.  	  }  651.  	  *cp++ = 0; 652. 	  pline("Unknown command '%s'.", expcmd); 653. 	}  654.  	multi = flags.move = 0; 655. 	return; 656. }  657.   658.  char 659. lowc(sym) 660. char sym; 661. {  662.      return (sym >= 'A' && sym <= 'Z') ? sym+'a'-'A' : sym; 663. }  664.   665.  /* 'rogue'-like direction commands */ 666. const char sdir[] = "hykulnjb><"; 667. const char ndir[] = "47896321><"; 668. const schar xdir[10] = { -1,-1, 0, 1, 1, 1, 0,-1, 0, 0 }; 669. const schar ydir[10] = {  0,-1,-1,-1, 0, 1, 1, 1, 0, 0 }; 670. const schar zdir[10] = {  0, 0, 0, 0, 0, 0, 0, 0, 1,-1 }; 671.  672.  #ifdef WALKIES 673. int 674. xytod(x, y)	/* convert an x,y pair into a direction code */ 675. schar x, y;  676. { 677.  	register int dd; 678.  679.  	for(dd = 0; dd < 8; dd++) 680. 	    if(x == xdir[dd] && y == ydir[dd]) return dd; 681.  682.  	return -1; 683. }  684.   685.  void 686. dtoxy(cc,dd)	/* convert a direction code into an x,y pair */ 687. coord *cc; 688. register int dd; 689. {  690.  	cc->x = xdir[dd]; 691. 	cc->y = ydir[dd]; 692. 	return; 693. }  694.  #endif /* WALKIES */ 695.  696.  int 697. movecmd(sym)	/* also sets u.dz, but returns false for <> */ 698. char sym; 699. {  700.  	register char *dp, *sdp = flags.num_pad ? ndir : sdir; 701.  702.  	u.dz = 0; 703. 	if(!(dp = index(sdp, sym))) return 0; 704. 	u.dx = xdir[dp-sdp]; 705. 	u.dy = ydir[dp-sdp]; 706. 	u.dz = zdir[dp-sdp]; 707. 	return !u.dz; 708. }  709.   710.  int 711. getdir(s) 712. boolean s;  713. { 714.  	char dirsym; 715.  716.  #ifdef REDO 717. 	if (!in_doagain) 718. #endif 719. 	    if(s) pline("In what direction? "); 720. 	dirsym = readchar; 721. #ifdef REDO 722. 	savech(dirsym); 723. #endif 724. 	if(dirsym == '.' || dirsym == 's') 725. 		u.dx = u.dy = u.dz = 0; 726. 	else if(!movecmd(dirsym) && !u.dz) { 727. 		if(!index(quitchars, dirsym)) 728. 			pline("What a strange direction!"); 729. 		return 0; 730. 	}  731.  	if(!u.dz && (Stunned || (Confusion && !rn2(5)))) confdir; 732. 	return 1; 733. }  734.   735.  void 736. confdir 737. {  738.  	register int x = rn2(8); 739. 	u.dx = xdir[x]; 740. 	u.dy = ydir[x]; 741. 	return; 742. }  743.   744.  int 745. isok(x,y) 746. register int x, y;  747. { 748.  	/* x corresponds to curx, so x==1 is the first column. Ach. %% */ 749.  	return x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1; 750. }