PropertyValue
rdfs:label
  • Source:NetHack 3.1.0/cmd.c
rdfs:comment
  • 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
dcterms:subject
dbkwik:nethack/property/wikiPageUsesTemplate
abstract
  • 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*/