abstract
| - Below is the full text to cmd.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/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 2.3 88/01/21 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include "hack.h" 5. #include "func_tab.h" 6. 7. int doredraw(),doredotopl(),dodrop(),dodrink(),doread(),dosearch(),dopickup(), 8. doversion(),doweararm(),dowearring(),doremarm(),doddoremarm(),doremring(), 9. dopay(),doapply(),dosave(),dowield(),ddoinv(),dozap(),ddocall(),dowhatis(), 10. doengrave(),dotele(),dohelp(),doeat(),doddrop(),do_mname(),doidtrap(), 11. doprwep(),doprarm(),doprring(),doprgold(),dodiscovered(),dotypeinv(),dolook(), 12. doset(),doup(), dodown(), done1(), donull(), dothrow(), doextcmd(), dodip(), 13. dopray(), doextlist(), dorub(); 14. 15. #ifdef THEOLOGY 16. int dosacrifice (); 17. #endif; 18. 19. #ifdef WIZARD 20. int wiz_wish(), wiz_identify(), wiz_map(), wiz_detect(), wiz_attributes(); 21. #endif 22. #ifdef NEWCLASS 23. int dosit(), doturn(); 24. #endif 25. #ifdef SPELLS 26. int docast(), dovspell(), doxcribe(); 27. #endif 28. #ifdef SHELL 29. int dosh(); 30. #endif 31. #ifdef SUSPEND 32. int dosuspend(); 33. #endif 34. #ifdef KAA 35. int doremove(), dobreathe(); 36. # ifdef KOPS 37. int dowipe(); 38. # endif 39. #endif 40. 41. int rndobjsym(), rndmonsym(); 42. char *hcolor(), *rndmonnam(), *defmonnam(); 43. 44. extern char *occtxt; 45. extern int (*occupation)(); 46. 47. #ifdef DGKMOD 48. int dotogglepickup(), doMSCversion(); 49. # ifdef DEBUG 50. int dodebug(); 51. # endif 52. 53. static int (*timed_occ_fn)(); 54. 55. /* Count down by decrementing multi */ 56. timed_occupation() { 57. (*timed_occ_fn)(); 58. if (multi > 0) 59. multi--; 60. return (multi > 0); 61. } 62. 63. /* If a time is given, use it to timeout this function, otherwise the 64. * function times out by its own means. 65. */ 66. void 67. set_occupation(fn, txt, time) 68. int (*fn)(); 69. char *txt; 70. { 71. if (time) { 72. occupation = timed_occupation; 73. timed_occ_fn = fn; 74. } else 75. occupation = fn; 76. occtxt = txt; 77. occtime = 0; 78. } 79. #endif /* DGKMOD */ 80. 81. #ifdef REDO 82. /* Provide a means to redo the last command. The flag `in_doagain' is set 83. * to true while redoing the command. This flag is tested in commands that 84. * require additional input (like `throw' which requires a thing and a 85. * direction), and the input prompt is not shown. Also, while in_doagain is 86. * TRUE, no keystrokes can be saved into the saveq. 87. */ 88. #define BSIZE 20 89. static char pushq[BSIZE], saveq[BSIZE]; 90. static int phead, ptail, shead, stail; 91. extern int in_doagain; 92. 93. char 94. popch() { 95. /* If occupied, return 0, letting tgetch know a character should 96. * be read from the keyboard. If the character read is not the 97. * ABORT character (as checked in main.c), that character will be 98. * pushed back on the pushq. 99. */ 100. if (occupation) return(0); 101. if (in_doagain) return ((shead != stail) ? saveq[stail++] : 0); 102. else return ((phead != ptail) ? pushq[ptail++] : 0); 103. } 104. 105. /* A ch == 0 resets the pushq */ 106. void 107. pushch(ch) 108. char ch; 109. { 110. if (!ch) 111. phead = ptail = 0; 112. if (phead < BSIZE) 113. pushq[phead++] = ch; 114. } 115. 116. /* A ch == 0 resets the saveq. Only save keystrokes when not 117. * replaying a previous command. 118. */ 119. void 120. savech(ch) 121. char ch; 122. { 123. if (!in_doagain) { 124. if (!ch) 125. phead = ptail = shead = stail = 0; 126. else if (shead < BSIZE) 127. saveq[shead++] = ch; 128. } 129. } 130. #endif /* REDO */ 131. 132. struct func_tab cmdlist[]={ 133. #if defined(DGKMOD) && defined(DEBUG_DOESNT_WORK) 134. {'\004', /* ^D */ dodebug}, /* generic debug function */ 135. #endif 136. #ifdef WIZARD 137. {'\005', /* ^E */ wiz_detect}, 138. {'\006', /* ^F */ wiz_map}, 139. {'\011', /* ^I */ wiz_identify}, 140. #endif 141. {'\020', /* ^P */ doredotopl}, 142. {'\022', /* ^R */ doredraw}, 143. {'\024', /* ^T */ dotele}, 144. #ifdef WIZARD 145. {'\027', /* ^W */ wiz_wish}, 146. {'\030', /* ^X */ wiz_attributes}, 147. #endif 148. #ifdef SUSPEND 149. {'\032', /* ^Z */ dosuspend}, 150. #endif 151. {'a', doapply}, 152. {'A', doddoremarm}, 153. /* 'b', 'B' : go sw */ 154. {'c', ddocall}, 155. {'C', do_mname}, 156. {'d', dodrop}, 157. {'D', doddrop}, 158. {'e', doeat}, 159. {'E', doengrave}, 160. /* Soon to be 161. {'f', dofight, "fighting"}, 162. {'F', doFight, "fighting"}, 163. */ 164. /* 'g', 'G' : multiple go */ 165. /* 'h', 'H' : go west */ 166. {'I', dotypeinv}, /* Robert Viduya */ 167. {'i', ddoinv}, 168. /* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */ 169. /* 'o', doopen, */ 170. {'O', doset}, 171. {'p', dopay}, 172. {'P', dowearring}, 173. {'q', dodrink}, 174. {'Q', done1}, 175. {'r', doread}, 176. {'R', doremring}, 177. {'s', dosearch, "searching"}, 178. {'S', dosave}, 179. {'t', dothrow}, 180. {'T', doremarm}, 181. /* 'u', 'U' : go ne */ 182. {'v', doversion}, 183. {'w', dowield}, 184. {'W', doweararm}, 185. #ifdef SPELLS 186. {'x', dovspell}, /* Mike Stephenson */ 187. {'X', doxcribe}, /* Mike Stephenson */ 188. #endif 189. /* 'y', 'Y' : go nw */ 190. {'z', dozap}, 191. #ifdef SPELLS 192. {'Z', docast}, 193. #endif 194. {'<', doup}, 195. {'>', dodown}, 196. {'/', dowhatis}, 197. {'?', dohelp}, 198. #ifdef SHELL 199. {'!', dosh}, 200. #endif 201. {'.', donull, "waiting"}, 202. {' ', donull, "waiting"}, 203. {',', dopickup}, 204. {':', dolook}, 205. {'^', doidtrap}, 206. {'\\', dodiscovered}, /* Robert Viduya */ 207. #ifdef DGKMOD 208. {'@', dotogglepickup}, 209. {'V', doMSCversion}, 210. #endif 211. {WEAPON_SYM, doprwep}, 212. {ARMOR_SYM, doprarm}, 213. {RING_SYM, doprring}, 214. {GOLD_SYM, doprgold}, 215. {'#', doextcmd}, 216. {0,0,0} 217. }; 218. 219. struct ext_func_tab extcmdlist[] = { 220. #ifdef KAA 221. "breathe", "breathe fire like a red dragon", dobreathe, 222. #endif 223. #ifdef SPELLS 224. "cast", "cast a spell", docast, 225. #endif 226. "dip", "dip an object into something", dodip, 227. #ifdef PRAYERS 228. #ifdef THEOLOGY 229. "sacrifice", "offer a sacrifice to the gods", dosacrifice, 230. #endif 231. "pray", "pray to the gods for help", dopray, 232. #endif 233. #ifdef KAA 234. "remove", "remove a cursed item", doremove, 235. #endif 236. #ifdef NEWCLASS 237. "rub", "rub a lamp", dorub, 238. "sit", "sit down", dosit, 239. "turn", "turn undead", doturn, 240. #endif 241. #if defined(KOPS) && defined(KAA) 242. "wipe", "wipe your face off", dowipe, 243. #endif 244. "?", "get this list of extended commands", doextlist, 245. (char *) 0, (char *) 0, donull 246. }; 247. 248. extern char *parse(), lowc(), unctrl(), quitchars[]; 249. 250. rhack(cmd) 251. register char *cmd; 252. { 253. register struct func_tab *tlist = cmdlist; 254. boolean firsttime = FALSE; 255. register res; 256. 257. if(!cmd) { 258. firsttime = TRUE; 259. flags.nopick = 0; 260. cmd = parse(); 261. } 262. #ifdef REDO 263. if (*cmd == DOAGAIN && !in_doagain && saveq[0]) { 264. in_doagain = TRUE; 265. stail = 0; 266. rhack((char *) 0); /* read and execute command */ 267. in_doagain = FALSE; 268. return; 269. } 270. 271. /* Special case of *cmd == ' ' handled better below */ 272. if(!*cmd || *cmd == (char)0377) { 273. #else 274. if(!*cmd || *cmd == (char)0377 || (flags.no_rest_on_space && *cmd == ' ')){ 275. #endif 276. bell(); 277. flags.move = 0; 278. return; /* probably we just had an interrupt */ 279. } 280. if(movecmd(*cmd)) { 281. walk: 282. if(multi) flags.mv = 1; 283. domove(); 284. return; 285. } 286. if(movecmd(lowc(*cmd))) { 287. flags.run = 1; 288. rush: 289. if(firsttime){ 290. if(!multi) multi = COLNO; 291. u.last_str_turn = 0; 292. } 293. flags.mv = 1; 294. #ifdef QUEST 295. if(flags.run >= 4) finddir(); 296. if(firsttime){ 297. u.ux0 = u.ux + u.dx; 298. u.uy0 = u.uy + u.dy; 299. } 300. #endif 301. domove(); 302. return; 303. } 304. if((*cmd == 'g' && movecmd(cmd[1])) || movecmd(unctrl(*cmd))) { 305. flags.run = 2; 306. goto rush; 307. } 308. if(*cmd == 'G' && movecmd(lowc(cmd[1]))) { 309. flags.run = 3; 310. goto rush; 311. } 312. if(*cmd == 'm' && movecmd(cmd[1])) { 313. flags.run = 0; 314. flags.nopick = 1; 315. goto walk; 316. } 317. if(*cmd == 'M' && movecmd(lowc(cmd[1]))) { 318. flags.run = 1; 319. flags.nopick = 1; 320. goto rush; 321. } 322. #ifdef QUEST 323. if(*cmd == cmd[1] && (*cmd == 'g' || *cmd == 'G')) { 324. flags.run = 4; 325. if(*cmd == 'G') flags.run += 2; 326. if(cmd[2] == '-') flags.run += 1; 327. goto rush; 328. } 329. #endif 330. while(tlist->f_char) { 331. if(*cmd == tlist->f_char){ 332. #ifdef DGKMOD 333. /* Special case of *cmd == ' ' handled here */ 334. if (*cmd == ' ' && flags.no_rest_on_space) 335. break; 336. 337. /* Now control-A can stop lengthy commands */ 338. if (tlist->f_text && !occupation && multi) 339. set_occupation(tlist->f_funct, tlist->f_text, 340. multi); 341. #endif 342. res = (*(tlist->f_funct))(); 343. if(!res) { 344. flags.move = 0; 345. multi = 0; 346. } 347. return; 348. } 349. tlist++; 350. } 351. { char expcmd[10]; 352. register char *cp = expcmd; 353. while(*cmd && cp-expcmd < sizeof(expcmd)-2) { 354. if(*cmd >= 040 && *cmd < 0177) 355. *cp++ = *cmd++; 356. else { 357. *cp++ = '^'; 358. *cp++ = *cmd++ ^ 0100; 359. } 360. } 361. *cp++ = 0; 362. pline("Unknown command '%s'.", expcmd); 363. } 364. multi = flags.move = 0; 365. return; 366. } 367. 368. doextcmd() /* here after # - now read a full-word command */ 369. { 370. char buf[BUFSZ]; 371. register struct ext_func_tab *efp = extcmdlist; 372. 373. pline("# "); 374. #ifdef COM_COMPL 375. get_ext_cmd(buf); 376. #else 377. getlin(buf); 378. #endif 379. clrlin(); 380. if(buf[0] == '\033') 381. return(0); 382. while(efp->ef_txt) { 383. if(!strcmp(efp->ef_txt, buf)) 384. return((*(efp->ef_funct))()); 385. efp++; 386. } 387. pline("%s: unknown command.", buf); 388. return(0); 389. } 390. 391. doextlist() /* here after #? - now list all full-word commands */ 392. { 393. register struct ext_func_tab *efp = extcmdlist; 394. char buf[BUFSZ]; 395. 396. set_pager(0); 397. if(page_line("") || 398. page_line(" Extended Command Set:") || 399. page_line("")) goto quit; 400. 401. while(efp->ef_txt) { 402. 403. (void)sprintf(buf, " %-8s - %s.", efp->ef_txt, efp->ef_desc); 404. if(page_line(buf)) goto quit; 405. efp++; 406. } 407. set_pager(1); 408. return(0); 409. quit: 410. set_pager(2); 411. return(0); 412. } 413. 414. char 415. lowc(sym) 416. char sym; 417. { 418. return( (sym >= 'A' && sym <= 'Z') ? sym+'a'-'A' : sym ); 419. } 420. 421. char 422. unctrl(sym) 423. char sym; 424. { 425. return( (sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym ); 426. } 427. 428. /* 'rogue'-like direction commands */ 429. char sdir[] = "hykulnjb><"; 430. schar xdir[10] = { -1,-1, 0, 1, 1, 1, 0,-1, 0, 0 }; 431. schar ydir[10] = { 0,-1,-1,-1, 0, 1, 1, 1, 0, 0 }; 432. schar zdir[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 1,-1 }; 433. 434. movecmd(sym) /* also sets u.dz, but returns false for <> */ 435. char sym; 436. { 437. register char *dp; 438. 439. u.dz = 0; 440. if(!(dp = index(sdir, sym))) return(0); 441. u.dx = xdir[dp-sdir]; 442. u.dy = ydir[dp-sdir]; 443. u.dz = zdir[dp-sdir]; 444. return(!u.dz); 445. } 446. 447. getdir(s) 448. boolean s; 449. { 450. char dirsym; 451. 452. #ifdef REDO 453. if (!in_doagain) 454. #endif 455. if(s) pline("In what direction?"); 456. dirsym = readchar(); 457. #ifdef REDO 458. savech(dirsym); 459. #endif 460. #ifdef KAA 461. if(dirsym == '.' || dirsym == 's') 462. u.dx = u.dy = u.dz = 0; 463. else 464. #endif 465. if(!movecmd(dirsym) && !u.dz) { 466. if(!index(quitchars, dirsym)) 467. pline("What a strange direction!"); 468. return(0); 469. } 470. if(Confusion && !u.dz) confdir(); 471. return(1); 472. } 473. 474. confdir() 475. { 476. register x = rn2(8); 477. u.dx = xdir[x]; 478. u.dy = ydir[x]; 479. } 480. 481. #ifdef QUEST 482. finddir(){ 483. register int i, ui = u.di; 484. for(i = 0; i <= 8; i++){ 485. if(flags.run & 1) ui++; else ui += 7; 486. ui %= 8; 487. if(i == 8){ 488. pline("Not near a wall."); 489. flags.move = multi = 0; 490. return(0); 491. } 492. if(!isroom(u.ux+xdir[ui], u.uy+ydir[ui])) 493. break; 494. } 495. for(i = 0; i <= 8; i++){ 496. if(flags.run & 1) ui += 7; else ui++; 497. ui %= 8; 498. if(i == 8){ 499. pline("Not near a room."); 500. flags.move = multi = 0; 501. return(0); 502. } 503. if(isroom(u.ux+xdir[ui], u.uy+ydir[ui])) 504. break; 505. } 506. u.di = ui; 507. u.dx = xdir[ui]; 508. u.dy = ydir[ui]; 509. } 510. 511. isroom(x,y) register x,y; { /* what about POOL? */ 512. return(isok(x,y) && (levl[x][y].typ == ROOM || 513. (levl[x][y].typ >= LDOOR && flags.run >= 6))); 514. } 515. #endif /* QUEST /**/ 516. 517. isok(x,y) register x,y; { 518. /* x corresponds to curx, so x==1 is the first column. Ach. %% */ 519. return(x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1); 520. } 521. 522. #ifdef WIZARD 523. int wiz_wish() /* Unlimited wishes for wizard mode by Paul Polderman */ 524. { 525. if (!wizard) { 526. pline("Alas! You are not allowed to make a wish."); 527. pline("Nice try though..."); 528. } else 529. makewish(); 530. return(0); 531. } 532. 533. int wiz_identify() 534. { 535. struct obj *obj; 536. 537. if (!wizard) 538. pline("You don't have the proper identity!"); 539. else { 540. for (obj = invent; obj; obj = obj->nobj) 541. if (!objects[obj->otyp].oc_name_known || !obj->known) 542. identify(obj); 543. } 544. return(0); 545. } 546. 547. int wiz_map() 548. { 549. if (wizard) do_mapping(); 550. else pline("If you want a map, you'll have to make one yourself!"); 551. } 552. 553. int wiz_detect() 554. { 555. if(wizard) { 556. if(!findit()) return; 557. } else pline("Don't ask me where anything is, I only work here!"); 558. } 559. 560. int wiz_attributes() 561. { 562. char buf[BUFSZ]; 563. 564. if (!wizard) { 565. pline("Alas! You are not allowed see attributes."); 566. pline("Nice try though..."); 567. return; 568. } 569. 570. set_pager(0); 571. if(page_line("Current Attributes:") || page_line("")) goto quit; 572. 573. if (Adornment) { 574. (void) sprintf(buf, "You are adorned."); 575. if(page_line(buf)) goto quit; 576. } 577. if (Teleportation) { 578. (void) sprintf(buf, "You can teleport."); 579. if(page_line(buf)) goto quit; 580. } 581. if (Regeneration) { 582. (void) sprintf(buf, "You regenerate."); 583. if(page_line(buf)) goto quit; 584. } 585. if (Searching) { 586. (void) sprintf(buf, "You have searching."); 587. if(page_line(buf)) goto quit; 588. } 589. if (See_invisible) { 590. (void) sprintf(buf, "You see invisible."); 591. if(page_line(buf)) goto quit; 592. } 593. if (Stealth) { 594. (void) sprintf(buf, "You have stealth."); 595. if(page_line(buf)) goto quit; 596. } 597. if (Levitation) { 598. (void) sprintf(buf, "You are levitated."); 599. if(page_line(buf)) goto quit; 600. } 601. if (Poison_resistance) { 602. (void) sprintf(buf, "You are poison resistant."); 603. if(page_line(buf)) goto quit; 604. } 605. if (Aggravate_monster) { 606. (void) sprintf(buf, "You aggravate monsters."); 607. if(page_line(buf)) goto quit; 608. } 609. if (Hunger) { 610. (void) sprintf(buf, "You have hunger."); 611. if(page_line(buf)) goto quit; 612. } 613. if (Fire_resistance) { 614. (void) sprintf(buf, "You are fire resistant."); 615. if(page_line(buf)) goto quit; 616. } 617. if (Cold_resistance) { 618. (void) sprintf(buf, "You are cold resistant."); 619. if(page_line(buf)) goto quit; 620. } 621. if (Protection_from_shape_changers) { 622. (void) sprintf(buf, "You are protected from shape changers."); 623. if(page_line(buf)) goto quit; 624. } 625. if (Conflict) { 626. (void) sprintf(buf, "You cause conflict."); 627. if(page_line(buf)) goto quit; 628. } 629. if (Gain_strength) { 630. (void) sprintf(buf, "You have extra strength."); 631. if(page_line(buf)) goto quit; 632. } 633. if (Increase_damage) { 634. (void) sprintf(buf, "You cause extra damage."); 635. if(page_line(buf)) goto quit; 636. } 637. if (Protection) { 638. (void) sprintf(buf, "You are protected."); 639. if(page_line(buf)) goto quit; 640. } 641. if (Warning) { 642. (void) sprintf(buf, "You are warned."); 643. if(page_line(buf)) goto quit; 644. } 645. if (Teleport_control) { 646. (void) sprintf(buf, "You have teleport control."); 647. if(page_line(buf)) goto quit; 648. } 649. if (Polymorph) { 650. (void) sprintf(buf, "You are polymorphing."); 651. if(page_line(buf)) goto quit; 652. } 653. if (Polymorph_control) { 654. (void) sprintf(buf, "You have polymorph control."); 655. if(page_line(buf)) goto quit; 656. } 657. if (Shock_resistance) { 658. (void) sprintf(buf, "You are shock resistant."); 659. if(page_line(buf)) goto quit; 660. } 661. if (Telepat) { 662. (void) sprintf(buf, "You have telepathy."); 663. if(page_line(buf)) goto quit; 664. } 665. if (Fast) { 666. (void) sprintf(buf, "You are fast."); 667. if(page_line(buf)) goto quit; 668. } 669. if (Confusion) { 670. (void) sprintf(buf, "You are confused."); 671. if(page_line(buf)) goto quit; 672. } 673. if (Invisible) { 674. (void) sprintf(buf, "You are invisible."); 675. if(page_line(buf)) goto quit; 676. } 677. if (Glib) { 678. (void) sprintf(buf, "You are glib."); 679. if(page_line(buf)) goto quit; 680. } 681. if (Punished) { 682. (void) sprintf(buf, "You are punished."); 683. if(page_line(buf)) goto quit; 684. } 685. if (Sick) { 686. (void) sprintf(buf, "You are sick."); 687. if(page_line(buf)) goto quit; 688. } 689. if (Blinded) { 690. (void) sprintf(buf, "You are blinded."); 691. if(page_line(buf)) goto quit; 692. } 693. if (Wounded_legs) { 694. (void) sprintf(buf, "You have wounded legs."); 695. if(page_line(buf)) goto quit; 696. } 697. if (Stoned) { 698. (void) sprintf(buf, "You are stoned."); 699. if(page_line(buf)) goto quit; 700. } 701. if (Hallucination) { 702. (void) sprintf(buf, "You are hallucinated."); 703. if(page_line(buf)) goto quit; 704. } 705. if (Blindfolded) { 706. (void) sprintf(buf, "You are blindfolded."); 707. if(page_line(buf)) goto quit; 708. } 709. if (Badged) { 710. (void) sprintf(buf, "You are badged."); 711. if(page_line(buf)) goto quit; 712. } 713. 714. set_pager(1); 715. return(0); 716. quit: 717. set_pager(2); 718. return(0); 719. } 720. #endif /* WIZARD */
|