PropertyValue
rdfs:label
  • Source:NetHack 3.2.0/cmd.c
rdfs:comment
  • Below is the full text to cmd.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.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.2.0. To link to a particular line, write [[NetHack 3.2.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.2 95/08/12 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. #include "func_tab.h" 7. /* #define DEBUG /* uncomment for debugging */ 8. 9. /* 10. * Some systems may have getchar() return EOF for various reasons, and 11. * we should not quit before seeing at least NR_OF_EOFS consecutive EOFs. 12. */ 13. #if defined(SYSV) || defined(DGUX) || defined(HPUX) 14. #define NR_OF_EOFS 20 15. #endif 16. 17. #ifdef DEBUG 18. /* 19. * only one "wiz_debug_cmd" routine should be available (in whatever 20. * module you are trying to debug) or things are going to get rather 21. * hard to link :-) 22. */ 23. extern void NDECL(wiz_debug_cmd); 24. #endif 25. 26. #ifdef DUMB /* stuff commented out in extern.h, but needed here */ 27. extern int NDECL(doapply); /**/ 28. extern int NDECL(dorub); /**/ 29. extern int NDECL(dojump); /**/ 30. extern int NDECL(doextlist); /**/ 31. extern int NDECL(dodrop); /**/ 32. extern int NDECL(doddrop); /**/ 33. extern int NDECL(dodown); /**/ 34. extern int NDECL(doup); /**/ 35. extern int NDECL(donull); /**/ 36. extern int NDECL(dowipe); /**/ 37. extern int NDECL(do_mname); /**/ 38. extern int NDECL(ddocall); /**/ 39. extern int NDECL(dotakeoff); /**/ 40. extern int NDECL(doremring); /**/ 41. extern int NDECL(dowear); /**/ 42. extern int NDECL(doputon); /**/ 43. extern int NDECL(doddoremarm); /**/ 44. extern int NDECL(dokick); /**/ 45. extern int NDECL(dothrow); /**/ 46. extern int NDECL(doeat); /**/ 47. extern int NDECL(done2); /**/ 48. extern int NDECL(doengrave); /**/ 49. extern int NDECL(dopickup); /**/ 50. extern int NDECL(ddoinv); /**/ 51. extern int NDECL(dotypeinv); /**/ 52. extern int NDECL(dolook); /**/ 53. extern int NDECL(doprgold); /**/ 54. extern int NDECL(doprwep); /**/ 55. extern int NDECL(doprarm); /**/ 56. extern int NDECL(doprring); /**/ 57. extern int NDECL(dopramulet); /**/ 58. extern int NDECL(doprtool); /**/ 59. extern int NDECL(dosuspend); /**/ 60. extern int NDECL(doforce); /**/ 61. extern int NDECL(doopen); /**/ 62. extern int NDECL(doclose); /**/ 63. extern int NDECL(dosh); /**/ 64. extern int NDECL(dodiscovered); /**/ 65. extern int NDECL(doset); /**/ 66. extern int NDECL(dotogglepickup); /**/ 67. extern int NDECL(dowhatis); /**/ 68. extern int NDECL(doquickwhatis); /**/ 69. extern int NDECL(dowhatdoes); /**/ 70. extern int NDECL(dohelp); /**/ 71. extern int NDECL(dohistory); /**/ 72. extern int NDECL(doloot); /**/ 73. extern int NDECL(dodrink); /**/ 74. extern int NDECL(dodip); /**/ 75. extern int NDECL(dosacrifice); /**/ 76. extern int NDECL(dopray); /**/ 77. extern int NDECL(doturn); /**/ 78. extern int NDECL(doredraw); /**/ 79. extern int NDECL(doread); /**/ 80. extern int NDECL(dosave); /**/ 81. extern int NDECL(dosearch); /**/ 82. extern int NDECL(doidtrap); /**/ 83. extern int NDECL(dopay); /**/ 84. extern int NDECL(dosit); /**/ 85. extern int NDECL(dotalk); /**/ 86. extern int NDECL(docast); /**/ 87. extern int NDECL(dovspell); /**/ 88. extern int NDECL(dotele); /**/ 89. extern int NDECL(dountrap); /**/ 90. extern int NDECL(doversion); /**/ 91. extern int NDECL(doextversion); /**/ 92. extern int NDECL(dowield); /**/ 93. extern int NDECL(dozap); /**/ 94. extern int NDECL(doorganize); /**/ 95. #endif /* DUMB */ 96. 97. #ifdef OVL1 98. static int NDECL((*timed_occ_fn)); 99. #endif /* OVL1 */ 100. 101. STATIC_PTR int NDECL(doprev_message); 102. STATIC_PTR int NDECL(timed_occupation); 103. STATIC_PTR int NDECL(doextcmd); 104. STATIC_PTR int NDECL(domonability); 105. # ifdef WIZARD 106. STATIC_PTR int NDECL(wiz_wish); 107. STATIC_PTR int NDECL(wiz_identify); 108. STATIC_PTR int NDECL(wiz_map); 109. STATIC_PTR int NDECL(wiz_genesis); 110. STATIC_PTR int NDECL(wiz_where); 111. STATIC_PTR int NDECL(wiz_detect); 112. STATIC_PTR int NDECL(wiz_level_tele); 113. STATIC_PTR int NDECL(wiz_show_seenv); 114. STATIC_PTR int NDECL(wiz_show_vision); 115. STATIC_PTR int NDECL(wiz_show_wmodes); 116. #ifdef __BORLANDC__ 117. extern void FDECL(show_borlandc_stats, (winid)); 118. #endif 119. static void FDECL(count_obj, (struct obj *, long *, long *, BOOLEAN_P, BOOLEAN_P)); 120. static void FDECL(obj_chain, (winid, const char *, struct obj *, long *, long *)); 121. static void FDECL(mon_invent_chain, (winid, const char *, struct monst *, long *, long *)); 122. static void FDECL(mon_chain, (winid, const char *, struct monst *, long *, long *)); 123. static void FDECL(contained, (winid, const char *, long *, long *)); 124. STATIC_PTR int NDECL(wiz_show_stats); 125. # endif 126. STATIC_PTR int NDECL(enter_explore_mode); 127. STATIC_PTR int NDECL(wiz_attributes); 128. 129. #ifdef OVLB 130. static void FDECL(enlght_line, (const char *,const char *,const char *)); 131. #ifdef UNIX 132. static void NDECL(end_of_input); 133. #endif 134. #endif /* OVLB */ 135. 136. STATIC_DCL char *NDECL(parse); 137. 138. #ifdef OVL1 139. 140. STATIC_PTR int 141. doprev_message() 142. { 143. return nh_doprev_message(); 144. } 145. 146. /* Count down by decrementing multi */ 147. STATIC_PTR int 148. timed_occupation() { 149. (*timed_occ_fn)(); 150. if (multi > 0) 151. multi--; 152. return multi > 0; 153. } 154. 155. /* If you have moved since initially setting some occupations, they 156. * now shouldn't be able to restart. 157. * 158. * The basic rule is that if you are carrying it, you can continue 159. * since it is with you. If you are acting on something at a distance, 160. * your orientation to it must have changed when you moved. 161. * 162. * The exception to this is taking off items, since they can be taken 163. * off in a number of ways in the intervening time, screwing up ordering. 164. * 165. * Currently: Take off all armor. 166. * Picking Locks / Forcing Chests. 167. */ 168. void 169. reset_occupations() { 170. 171. reset_remarm(); 172. reset_pick(); 173. } 174. 175. /* If a time is given, use it to timeout this function, otherwise the 176. * function times out by its own means. 177. */ 178. void 179. set_occupation(fn, txt, xtime) 180. int NDECL((*fn)); 181. const char *txt; 182. int xtime; 183. { 184. if (xtime) { 185. occupation = timed_occupation; 186. timed_occ_fn = fn; 187. } else 188. occupation = fn; 189. occtxt = txt; 190. occtime = 0; 191. return; 192. } 193. 194. #ifdef REDO 195. 196. static char NDECL(popch); 197. 198. /* Provide a means to redo the last command. The flag `in_doagain' is set 199. * to true while redoing the command. This flag is tested in commands that 200. * require additional input (like `throw' which requires a thing and a 201. * direction), and the input prompt is not shown. Also, while in_doagain is 202. * TRUE, no keystrokes can be saved into the saveq. 203. */ 204. #define BSIZE 20 205. static char pushq[BSIZE], saveq[BSIZE]; 206. static NEARDATA int phead, ptail, shead, stail; 207. 208. static char 209. popch() { 210. /* If occupied, return '\0', letting tgetch know a character should 211. * be read from the keyboard. If the character read is not the 212. * ABORT character (as checked in pcmain.c), that character will be 213. * pushed back on the pushq. 214. */ 215. if (occupation) return '\0'; 216. if (in_doagain) return(char)((shead != stail) ? saveq[stail++] : '\0'); 217. else return(char)((phead != ptail) ? pushq[ptail++] : '\0'); 218. } 219. 220. char 221. pgetchar() { /* curtesy of aeb@cwi.nl */ 222. register int ch; 223. 224. if(!(ch = popch())) 225. ch = nhgetch(); 226. return((char)ch); 227. } 228. 229. /* A ch == 0 resets the pushq */ 230. void 231. pushch(ch) 232. char ch; 233. { 234. if (!ch) 235. phead = ptail = 0; 236. if (phead < BSIZE) 237. pushq[phead++] = ch; 238. return; 239. } 240. 241. /* A ch == 0 resets the saveq. Only save keystrokes when not 242. * replaying a previous command. 243. */ 244. void 245. savech(ch) 246. char ch; 247. { 248. if (!in_doagain) { 249. if (!ch) 250. phead = ptail = shead = stail = 0; 251. else if (shead < BSIZE) 252. saveq[shead++] = ch; 253. } 254. return; 255. } 256. #endif /* REDO */ 257. 258. #endif /* OVL1 */ 259. #ifdef OVLB 260. 261. STATIC_PTR int 262. doextcmd() /* here after # - now read a full-word command */ 263. { 264. int idx, retval; 265. 266. /* keep repeating until we don't run help or quit */ 267. do { 268. idx = get_ext_cmd(); 269. if (idx < 0) return 0; /* quit */ 270. 271. retval = (*extcmdlist[idx].ef_funct)(); 272. } while (extcmdlist[idx].ef_funct == doextlist); 273. 274. return retval; 275. } 276. 277. int 278. doextlist() /* here after #? - now list all full-word commands */ 279. { 280. register const struct ext_func_tab *efp; 281. char buf[BUFSZ]; 282. winid datawin; 283. 284. datawin = create_nhwindow(NHW_TEXT); 285. putstr(datawin, 0, ""); 286. putstr(datawin, 0, " Extended Commands List"); 287. putstr(datawin, 0, ""); 288. putstr(datawin, 0, " Press '#', then type:"); 289. putstr(datawin, 0, ""); 290. 291. for(efp = extcmdlist; efp->ef_txt; efp++) { 292. Sprintf(buf, " %-14s - %s.", efp->ef_txt, efp->ef_desc); 293. putstr(datawin, 0, buf); 294. } 295. display_nhwindow(datawin, FALSE); 296. destroy_nhwindow(datawin); 297. return 0; 298. } 299. 300. STATIC_PTR int 301. domonability() 302. { 303. if (can_breathe(uasmon)) return dobreathe(); 304. else if (attacktype(uasmon, AT_SPIT)) return dospit(); 305. else if (u.usym == S_NYMPH) return doremove(); 306. else if (u.usym == S_UMBER) return doconfuse(); 307. else if (is_were(uasmon)) return dosummon(); 308. else if (webmaker(uasmon)) return dospinweb(); 309. else if (is_hider(uasmon)) return dohide(); 310. else if(u.umonnum == PM_GREMLIN) { 311. if(IS_FOUNTAIN(levl[u.ux][u.uy].typ)) { 312. struct monst *mtmp; 313. if ((mtmp = cloneu()) != 0) { 314. mtmp->mhpmax = (u.mhmax /= 2); 315. You("multiply."); 316. dryup(u.ux,u.uy); 317. } 318. } else pline("There is no fountain here."); 319. } 320. else if (u.usym == S_UNICORN) { 321. use_unicorn_horn((struct obj *)0); 322. return 1; 323. } else if (u.umonnum == PM_MIND_FLAYER) return domindblast(); 324. else if (uasmon->msound == MS_SHRIEK) { 325. You("shriek."); 326. if(u.uburied) 327. pline("Unfortunately sound does not carry well through rock."); 328. else aggravate(); 329. } else if (Upolyd) 330. pline("Any special ability you may have is purely reflexive."); 331. else You("don't have a special ability!"); 332. return 0; 333. } 334. 335. STATIC_PTR int 336. enter_explore_mode() 337. { 338. if(!discover && !wizard) { 339. pline("Beware! From explore mode there will be no return to normal game."); 340. if (yn("Do you want to enter explore mode?") == 'y') { 341. clear_nhwindow(WIN_MESSAGE); 342. You("are now in non-scoring explore mode."); 343. discover = TRUE; 344. } 345. else { 346. clear_nhwindow(WIN_MESSAGE); 347. pline("Resuming normal game."); 348. } 349. } 350. return 0; 351. } 352. 353. #ifdef WIZARD 354. STATIC_PTR int 355. wiz_wish() /* Unlimited wishes for debug mode by Paul Polderman */ 356. { 357. if (wizard) { 358. boolean save_verbose = flags.verbose; 359. 360. flags.verbose = FALSE; 361. makewish(); 362. flags.verbose = save_verbose; 363. (void) encumber_msg(); 364. } else 365. pline("Unavailable command '^W'."); 366. return 0; 367. } 368. 369. STATIC_PTR int 370. wiz_identify() 371. { 372. if (wizard) identify_pack(0); 373. else pline("Unavailable command '^I'."); 374. return 0; 375. } 376. 377. STATIC_PTR int 378. wiz_map() 379. { 380. if (wizard) do_mapping(); 381. else pline("Unavailable command '^F'."); 382. return 0; 383. } 384. 385. STATIC_PTR int 386. wiz_genesis() 387. { 388. if (wizard) (void) create_particular(); 389. else pline("Unavailable command '^G'."); 390. return 0; 391. } 392. 393. STATIC_PTR int 394. wiz_where() 395. { 396. if (wizard) print_dungeon(); 397. else pline("Unavailable command '^O'."); 398. return 0; 399. } 400. 401. STATIC_PTR int 402. wiz_detect() 403. { 404. if(wizard) (void) findit(); 405. else pline("Unavailable command '^E'."); 406. return 0; 407. } 408. 409. STATIC_PTR int 410. wiz_level_tele() 411. { 412. if (wizard) level_tele(); 413. else pline("Unavailable command '^V'."); 414. return 0; 415. } 416. 417. STATIC_PTR int 418. wiz_show_seenv() 419. { 420. winid win; 421. int x, y, v, startx, stopx, curx; 422. char row[COLNO+1]; 423. 424. win = create_nhwindow(NHW_TEXT); 425. /* 426. * Each seenv description takes up 2 characters, so center 427. * the seenv display around the hero. 428. */ 429. startx = max(1, u.ux-(COLNO/4)); 430. stopx = min(startx+(COLNO/2), COLNO); 431. /* can't have a line exactly 80 chars long */ 432. if (stopx - startx == COLNO/2) startx++; 433. 434. for (y = 0; y < ROWNO; y++) { 435. for (x = startx, curx = 0; x < stopx; x++, curx += 2) { 436. if (x == u.ux && y == u.uy) { 437. row[curx] = row[curx+1] = '@'; 438. } else { 439. v = levl[x][y].seenv & 0xff; 440. if (v == 0) 441. row[curx] = row[curx+1] = ' '; 442. else 443. Sprintf(&row[curx], "%02x", v); 444. } 445. } 446. /* remove trailing spaces */ 447. for (x = curx-1; x >= 0; x--) 448. if (row[x] != ' ') break; 449. row[x+1] = '\0'; 450. 451. putstr(win, 0, row); 452. } 453. display_nhwindow(win, TRUE); 454. destroy_nhwindow(win); 455. return 0; 456. } 457. 458. STATIC_PTR int 459. wiz_show_vision() 460. { 461. winid win; 462. int x, y, v; 463. char row[COLNO+1]; 464. 465. win = create_nhwindow(NHW_TEXT); 466. Sprintf(row, "Flags: 0x%x could see, 0x%x in sight, 0x%x temp lit", 467. COULD_SEE, IN_SIGHT, TEMP_LIT); 468. putstr(win, 0, row); 469. putstr(win, 0, ""); 470. for (y = 0; y < ROWNO; y++) { 471. for (x = 1; x < COLNO; x++) { 472. if (x == u.ux && y == u.uy) 473. row[x] = '@'; 474. else { 475. v = viz_array[y][x]; /* data access should be hidden */ 476. if (v == 0) 477. row[x] = ' '; 478. else 479. row[x] = '0' + viz_array[y][x]; 480. } 481. } 482. /* remove trailing spaces */ 483. for (x = COLNO-1; x >= 1; x--) 484. if (row[x] != ' ') break; 485. row[x+1] = '\0'; 486. 487. putstr(win, 0, &row[1]); 488. } 489. display_nhwindow(win, TRUE); 490. destroy_nhwindow(win); 491. return 0; 492. } 493. 494. STATIC_PTR int 495. wiz_show_wmodes() 496. { 497. winid win; 498. int x,y; 499. char row[COLNO+1]; 500. struct rm *lev; 501. 502. win = create_nhwindow(NHW_TEXT); 503. for (y = 0; y < ROWNO; y++) { 504. for (x = 0; x < COLNO; x++) { 505. lev = &levl[x][y]; 506. if (x == u.ux && y == u.uy) 507. row[x] = '@'; 508. if (IS_WALL(lev->typ) || lev->typ == SDOOR) 509. row[x] = '0' + (lev->wall_info & WM_MASK); 510. else if (lev->typ == CORR) 511. row[x] = '#'; 512. else if (IS_ROOM(lev->typ) || IS_DOOR(lev->typ)) 513. row[x] = '.'; 514. else 515. row[x] = 'x'; 516. } 517. row[COLNO] = '\0'; 518. putstr(win, 0, row); 519. } 520. display_nhwindow(win, TRUE); 521. destroy_nhwindow(win); 522. return 0; 523. } 524. 525. #endif /* WIZARD */ 526. 527. /* -enlightenment- */ 528. static winid en_win; 529. static const char 530. *You_ = "You ", 531. *are = "are ", *were = "were ", 532. *have = "have ", *had = "had ", 533. *can = "can ", *could = "could "; 534. 535. #define enl_msg(prefix,present,past,suffix) \ 536. enlght_line(prefix, final ? past : present, suffix) 537. #define you_are(attr) enl_msg(You_,are,were,attr) 538. #define you_have(attr) enl_msg(You_,have,had,attr) 539. #define you_can(attr) enl_msg(You_,can,could,attr) 540. 541. static void 542. enlght_line(start, middle, end) 543. const char *start, *middle, *end; 544. { 545. char buf[BUFSZ]; 546. 547. Sprintf(buf, "%s%s%s.", start, middle, end); 548. putstr(en_win, 0, buf); 549. } 550. 551. void 552. enlightenment(final) 553. int final; /* 0 => still in progress; 1 => over, survived; 2 => dead */ 554. { 555. int ltmp; 556. char buf[BUFSZ]; 557. 558. en_win = create_nhwindow(NHW_MENU); 559. putstr(en_win, 0, final ? "Final Attributes:" : "Current Attributes:"); 560. putstr(en_win, 0, ""); 561. 562. #ifdef ELBERETH 563. if (u.uevent.uhand_of_elbereth) { 564. static const char *hofe_titles[3] = { 565. "the Hand of Elbereth", 566. "the Envoy of Balance", 567. "the Glory of Arioch" 568. }; 569. you_are(hofe_titles[u.uevent.uhand_of_elbereth - 1]); 570. } 571. #endif 572. 573. /* note: piousness 20 matches MIN_QUEST_ALIGN (quest.h) */ 574. if (u.ualign.record >= 20) you_are("piously aligned"); 575. else if (u.ualign.record > 13) you_are("devoutly aligned"); 576. else if (u.ualign.record > 8) you_are("fervently aligned"); 577. else if (u.ualign.record > 3) you_are("stridently aligned"); 578. else if (u.ualign.record == 3) you_are("aligned"); 579. else if (u.ualign.record > 0) you_are("haltingly aligned"); 580. else if (u.ualign.record == 0) you_are("nominally aligned"); 581. else if (u.ualign.record >= -3) you_have("strayed"); 582. else if (u.ualign.record >= -8) you_have("sinned"); 583. else you_have("transgressed"); 584. #ifdef WIZARD 585. if (wizard) { 586. Sprintf(buf, " %d", u.ualign.record); 587. enl_msg("Your alignment ", "is", "was", buf); 588. } 589. #endif 590. 591. if (Telepat) you_are("telepathic"); 592. if (Searching) you_have("automatic searching"); 593. if (Teleportation) you_can("teleport"); 594. if (Teleport_control) you_have("teleport control"); 595. if (See_invisible) enl_msg(You_, "see", "saw", " invisible"); 596. if (Invisible) you_are("invisible"); 597. else if (Invis) you_are("invisible to others"); 598. /* ordinarily "visible" is redundant; this is a special case for 599. the situation when invisibility would be an expected attribute */ 600. else if ((HInvis & I_BLOCKED) != 0L && 601. ((HInvis & ~I_BLOCKED) != 0L || pm_invisible(uasmon))) 602. you_are("visible"); 603. if (Fast) you_are((Fast & ~INTRINSIC) ? "very fast" : "fast"); 604. if (Stealth) you_are("stealthy"); 605. if (Regeneration) enl_msg("You regenerate", "", "d", ""); 606. if (Hunger) enl_msg("You hunger", "", "ed", " rapidly"); 607. if (Conflict) enl_msg("You cause", "", "d", " conflict"); 608. if (Aggravate_monster) enl_msg("You aggravate", "", "d", " monsters"); 609. if (Poison_resistance) you_are("poison resistant"); 610. if (Fire_resistance) you_are("fire resistant"); 611. if (Cold_resistance) you_are("cold resistant"); 612. if (Shock_resistance) you_are("shock resistant"); 613. if (Sleep_resistance) you_are("sleep resistant"); 614. if (Disint_resistance) you_are("disintegration-resistant"); 615. if (Protection_from_shape_changers) 616. you_are("protected from shape changers"); 617. if (Polymorph) you_are("polymorphing"); 618. if (Polymorph_control) you_have("polymorph control"); 619. if (HHalluc_resistance) 620. enl_msg("You resist", "", "ed", " hallucinations"); 621. if (final) { 622. if (Hallucination) you_are("hallucinating"); 623. if (Stunned) you_are("stunned"); 624. if (Confusion) you_are("confused"); 625. if (Sick) { 626. if (u.usick_type & SICK_VOMITABLE) 627. you_are("sick from food poisoning"); 628. if (u.usick_type & SICK_NONVOMITABLE) 629. you_are("sick from illness"); 630. } 631. if (Blinded) you_are("blinded"); 632. } 633. if (Wounded_legs) { 634. Sprintf(buf, "wounded %s", makeplural(body_part(LEG))); 635. you_have(buf); 636. } 637. if (Glib) { 638. Sprintf(buf, "slippery %s", makeplural(body_part(FINGER))); 639. you_have(buf); 640. } 641. if (Strangled) you_are((u.uburied) ? "buried" : "being strangled"); 642. if (Stoned) you_are("turning to stone"); 643. if (Lifesaved) 644. enl_msg("Your life ", "will be", "would have been", " saved"); 645. if (Adornment) you_are("adorned"); 646. if (Warning) you_are("warned"); 647. if (Protection) you_are("protected"); 648. if (Reflecting) you_have("reflection"); 649. if ((HLevitation & (I_SPECIAL|W_ARTI)) != 0L && 650. (HLevitation & ~(I_SPECIAL|W_ARTI|TIMEOUT)) == 0L && 651. !is_floater(uasmon)) you_are("levitating, at will"); 652. else if (Levitation) you_are("levitating"); /* without control */ 653. else if (is_flyer(uasmon)) you_can("fly"); 654. if (Fumbling) enl_msg("You fumble", "", "d", ""); 655. if (Jumping) you_can("jump"); 656. if (Wwalking) you_can("walk on water"); 657. if (passes_walls(uasmon)) you_can("walk through walls"); 658. if (Breathless) you_can("survive without air"); 659. else if (Amphibious) you_can("breathe water"); 660. if (Antimagic) you_are("magic-protected"); 661. if (Displaced) you_are("displaced"); 662. if (Clairvoyant) you_are("clairvoyant"); 663. if (u.ulycn >= LOW_PM) { 664. Strcpy(buf, an(mons[u.ulycn].mname)); 665. you_are(buf); 666. } 667. if (Luck) { 668. ltmp = abs((int)Luck); 669. Sprintf(buf, "%s%slucky", 670. ltmp >= 10 ? "extremely " : ltmp >= 5 ? "very " : "", 671. Luck < 0 ? "un" : ""); 672. #ifdef WIZARD 673. if (wizard) Sprintf(eos(buf), " (%d)", Luck); 674. #endif 675. you_are(buf); 676. } 677. #ifdef WIZARD 678. else if (wizard) enl_msg("Your luck ", "is", "was", " zero"); 679. #endif 680. if (u.moreluck > 0) you_have("extra luck"); 681. else if (u.moreluck < 0) you_have("reduced luck"); 682. if (carrying(LUCKSTONE)) { 683. ltmp = stone_luck(FALSE); 684. if (ltmp <= 0) 685. enl_msg("Bad luck ", "does", "did", " not time out for you"); 686. if (ltmp >= 0) 687. enl_msg("Good luck ", "does", "did", " not time out for you"); 688. } 689. 690. if (u.ugangr) { 691. Sprintf(buf, " %sangry with you", 692. u.ugangr > 6 ? "extremely " : u.ugangr > 3 ? "very " : ""); 693. #ifdef WIZARD 694. if (wizard) Sprintf(eos(buf), " (%d)", u.ugangr); 695. #endif 696. enl_msg(u_gname(), " is", " was", buf); 697. } else 698. /* 699. * We need to suppress this when the game is over, because death 700. * can change the value calculated by can_pray(), potentially 701. * resulting in a false claim that you could have prayed safely. 702. */ 703. if (!final) { 704. #if 0 705. /* "can [not] safely pray" vs "could [not] have safely prayed" */ 706. Sprintf(buf, "%s%ssafely pray%s", can_pray(FALSE) ? "" : "not ", 707. final ? "have " : "", final ? "ed" : ""); 708. #else 709. Sprintf(buf, "%ssafely pray", can_pray(FALSE) ? "" : "not "); 710. #endif 711. #ifdef WIZARD 712. if (wizard) Sprintf(eos(buf), " (%d)", u.ublesscnt); 713. #endif 714. you_can(buf); 715. } 716. 717. { 718. const char *p; 719. 720. buf[0] = '\0'; 721. if (final < 2) { /* still in progress, or quit/escaped/ascended */ 722. p = "survived after being killed "; 723. switch (u.umortality) { 724. case 0: p = !final ? (char *)0 : "survived"; break; 725. case 1: Strcpy(buf, "once"); break; 726. case 2: Strcpy(buf, "twice"); break; 727. case 3: Strcpy(buf, "thrice"); break; 728. default: Sprintf(buf, "%d times", u.umortality); 729. break; 730. } 731. } else { /* game ended in character's death */ 732. p = "are dead"; 733. switch (u.umortality) { 734. case 0: impossible("dead without dying?"); 735. case 1: break; /* just "are dead" */ 736. default: Sprintf(buf, " (%d%s time!)", u.umortality, 737. ordin(u.umortality)); 738. break; 739. } 740. } 741. if (p) enl_msg(You_, "have been killed ", p, buf); 742. } 743. 744. display_nhwindow(en_win, TRUE); 745. destroy_nhwindow(en_win); 746. return; 747. } 748. 749. STATIC_PTR int 750. wiz_attributes() 751. { 752. if (wizard || discover) 753. enlightenment(0); 754. else 755. pline("Unavailable command '^X'."); 756. return 0; 757. } 758. 759. #endif /* OVLB */ 760. #ifdef OVL1 761. 762. #ifndef M 763. # ifndef NHSTDC 764. # define M(c) (0x80 | (c)) 765. # else 766. # define M(c) ((c) - 128) 767. # endif /* NHSTDC */ 768. #endif 769. #ifndef C 770. #define C(c) (0x1f & (c)) 771. #endif 772. 773. static const struct func_tab cmdlist[] = { 774. {C('d'), FALSE, dokick}, /* "D" is for door!...? Msg is in dokick.c */ 775. #ifdef WIZARD 776. {C('e'), TRUE, wiz_detect}, 777. {C('f'), TRUE, wiz_map}, 778. {C('g'), TRUE, wiz_genesis}, 779. {C('i'), TRUE, wiz_identify}, 780. #endif 781. {C('l'), TRUE, doredraw}, /* if number_pad is set */ 782. #ifdef WIZARD 783. {C('o'), TRUE, wiz_where}, 784. #endif 785. {C('p'), TRUE, doprev_message}, 786. {C('r'), TRUE, doredraw}, 787. {C('t'), TRUE, dotele}, 788. #ifdef WIZARD 789. {C('v'), TRUE, wiz_level_tele}, 790. {C('w'), TRUE, wiz_wish}, 791. #endif 792. {C('x'), TRUE, wiz_attributes}, 793. #ifdef SUSPEND 794. {C('z'), TRUE, dosuspend}, 795. #endif 796. {'a', FALSE, doapply}, 797. {'A', FALSE, doddoremarm}, 798. {M('a'), TRUE, doorganize}, 799. /* 'b', 'B' : go sw */ 800. {'c', FALSE, doclose}, 801. {'C', TRUE, do_mname}, 802. {M('c'), TRUE, dotalk}, 803. {'d', FALSE, dodrop}, 804. {'D', FALSE, doddrop}, 805. {M('d'), FALSE, dodip}, 806. {'e', FALSE, doeat}, 807. {'E', FALSE, doengrave}, 808. #ifdef WEAPON_SKILLS 809. {M('e'), TRUE, select_weapon_skill}, 810. #endif /* WEAPON_SKILLS */ 811. /* Soon to be 812. {'f', FALSE, dofight, "fighting"}, 813. {'F', FALSE, doFight, "fighting"}, 814. */ 815. {M('f'), FALSE, doforce}, 816. /* 'g', 'G' : multiple go */ 817. /* 'h', 'H' : go west */ 818. {'h', TRUE, dohelp}, /* if number_pad is set */ 819. {'i', TRUE, ddoinv}, 820. {'I', TRUE, dotypeinv}, /* Robert Viduya */ 821. {M('i'), TRUE, doinvoke}, 822. /* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */ 823. {'j', FALSE, dojump}, /* if number_pad is on */ 824. {M('j'), FALSE, dojump}, 825. {'k', FALSE, dokick}, /* if number_pad is on */ 826. {'l', FALSE, doloot}, /* if number_pad is on */ 827. {M('l'), FALSE, doloot}, 828. /* 'n' prefixes a count if number_pad is on */ 829. {M('m'), TRUE, domonability}, 830. {'N', TRUE, ddocall}, /* if number_pad is on */ 831. {M('n'), TRUE, ddocall}, 832. {M('N'), TRUE, ddocall}, 833. {'o', FALSE, doopen}, 834. {'O', TRUE, doset}, 835. {M('o'), FALSE, dosacrifice}, 836. {'p', FALSE, dopay}, 837. {'P', FALSE, doputon}, 838. {M('p'), TRUE, dopray}, 839. {'q', FALSE, dodrink}, 840. {'Q', TRUE, done2}, 841. #ifdef WEAPON_SKILLS 842. {M('q'), TRUE, check_weapon_skills}, 843. #endif /* WEAPON_SKILLS */ 844. {'r', FALSE, doread}, 845. {'R', FALSE, doremring}, 846. {M('r'), FALSE, dorub}, 847. {'s', TRUE, dosearch, "searching"}, 848. {'S', TRUE, dosave}, 849. {M('s'), FALSE, dosit}, 850. {'t', FALSE, dothrow}, 851. {'T', FALSE, dotakeoff}, 852. {M('t'), TRUE, doturn}, 853. /* 'u', 'U' : go ne */ 854. {'u', FALSE, dountrap}, /* if number_pad is on */ 855. {M('u'), FALSE, dountrap}, 856. {'v', TRUE, doversion}, 857. {'V', TRUE, dohistory}, 858. {M('v'), TRUE, doextversion}, 859. {'w', FALSE, dowield}, 860. {'W', FALSE, dowear}, 861. {M('w'), FALSE, dowipe}, 862. {'x', TRUE, dovspell}, /* Mike Stephenson */ 863. {'X', TRUE, enter_explore_mode}, 864. /* 'y', 'Y' : go nw */ 865. {'z', FALSE, dozap}, 866. {'Z', TRUE, docast}, 867. {'<', FALSE, doup}, 868. {'>', FALSE, dodown}, 869. {'/', TRUE, dowhatis}, 870. {'&', TRUE, dowhatdoes}, 871. {'?', TRUE, dohelp}, 872. {M('?'), TRUE, doextlist}, 873. #ifdef SHELL 874. {'!', TRUE, dosh}, 875. #endif 876. {'.', TRUE, donull, "waiting"}, 877. {' ', TRUE, donull, "waiting"}, 878. {',', FALSE, dopickup}, 879. {':', TRUE, dolook}, 880. {';', TRUE, doquickwhatis}, 881. {'^', TRUE, doidtrap}, 882. {'\\', TRUE, dodiscovered}, /* Robert Viduya */ 883. {'@', TRUE, dotogglepickup}, 884. {WEAPON_SYM, TRUE, doprwep}, 885. {ARMOR_SYM, TRUE, doprarm}, 886. {RING_SYM, TRUE, doprring}, 887. {AMULET_SYM, TRUE, dopramulet}, 888. {TOOL_SYM, TRUE, doprtool}, 889. {GOLD_SYM, TRUE, doprgold}, 890. {SPBOOK_SYM, TRUE, dovspell}, /* Mike Stephenson */ 891. {'#', TRUE, doextcmd}, 892. {0,0,0,0} 893. }; 894. 895. struct ext_func_tab extcmdlist[] = { 896. {"adjust", "adjust inventory letters", doorganize, TRUE}, 897. {"chat", "talk to someone", dotalk, TRUE}, /* converse? */ 898. {"dip", "dip an object into something", dodip, FALSE}, 899. #ifdef WEAPON_SKILLS 900. {"enhance", "advance a weapon skill", select_weapon_skill, TRUE}, 901. #endif /* WEAPON_SKILLS */ 902. {"force", "force a lock", doforce, FALSE}, 903. {"invoke", "invoke an object's powers", doinvoke, TRUE}, 904. {"jump", "jump to a location", dojump, FALSE}, 905. {"loot", "loot a box on the floor", doloot, FALSE}, 906. {"monster", "use a monster's special ability", domonability, TRUE}, 907. {"name", "name an item or type of object", ddocall, TRUE}, 908. {"offer", "offer a sacrifice to the gods", dosacrifice, FALSE}, 909. {"pray", "pray to the gods for help", dopray, TRUE}, 910. #ifdef WEAPON_SKILLS 911. {"qualifications", "check your weapon skills", check_weapon_skills, TRUE}, 912. #endif /* WEAPON_SKILLS */ 913. {"rub", "rub a lamp", dorub, FALSE}, 914. {"sit", "sit down", dosit, FALSE}, 915. {"turn", "turn undead", doturn, TRUE}, 916. {"untrap", "untrap something", dountrap, FALSE}, 917. {"version", "list compile time options for this version of NetHack", 918. doextversion, TRUE}, 919. {"wipe", "wipe off your face", dowipe, FALSE}, 920. {"?", "get this list of extended commands", doextlist, TRUE}, 921. #if defined(WIZARD) 922. /* 923. * There must be a blank entry here for every entry in the table 924. * below. 925. */ 926. {(char *)0, (char *)0, donull, TRUE}, 927. {(char *)0, (char *)0, donull, TRUE}, 928. {(char *)0, (char *)0, donull, TRUE}, 929. {(char *)0, (char *)0, donull, TRUE}, 930. {(char *)0, (char *)0, donull, TRUE}, 931. #ifdef DEBUG 932. {(char *)0, (char *)0, donull, TRUE}, 933. #endif 934. {(char *)0, (char *)0, donull, TRUE}, 935. #endif 936. {(char *)0, (char *)0, donull, TRUE} 937. }; 938. 939. #if defined(WIZARD) 940. static const struct ext_func_tab debug_extcmdlist[] = { 941. {"light sources", "show mobile light sources", wiz_light_sources, TRUE}, 942. {"seenv", "show seen vectors", wiz_show_seenv, TRUE}, 943. {"stats", "show memory statistics", wiz_show_stats, TRUE}, 944. {"timeout", "look at timeout queue", wiz_timeout_queue, TRUE}, 945. {"vision", "show vision array", wiz_show_vision, TRUE}, 946. #ifdef DEBUG 947. {"wizdebug", "wizard debug command", wiz_debug_cmd, TRUE}, 948. #endif 949. {"wmode", "show wall modes", wiz_show_wmodes, TRUE}, 950. {(char *)0, (char *)0, donull, TRUE} 951. }; 952. 953. /* 954. * Insert debug commands into the extended command list. This function 955. * assumes that the last entry will be the help entry. 956. * 957. * You must add entries in ext_func_tab every time you add one to the 958. * debug_extcmdlist(). 959. */ 960. void 961. add_debug_extended_commands() 962. { 963. int i, j, k, n; 964. 965. /* count the # of help entries */ 966. for (n = 0; extcmdlist[n].ef_txt[0] != '?'; n++) 967. ; 968. 969. for (i = 0; debug_extcmdlist[i].ef_txt; i++) { 970. for (j = 0; j < n; j++) 971. if (strcmp(debug_extcmdlist[i].ef_txt, extcmdlist[j].ef_txt) < 0) break; 972. 973. /* insert i'th debug entry into extcmdlist[j], pushing down */ 974. for (k = n; k >= j; --k) 975. extcmdlist[k+1] = extcmdlist[k]; 976. extcmdlist[j] = debug_extcmdlist[i]; 977. n++; /* now an extra entry */ 978. } 979. } 980. 981. 982. static const char *template = "%-18s %4ld %6ld"; 983. static const char *count_str = " count bytes"; 984. static const char *separator = "------------------ ----- ------"; 985. 986. static void 987. count_obj(chain, total_count, total_size, top, recurse) 988. struct obj *chain; 989. long *total_count; 990. long *total_size; 991. boolean top; 992. boolean recurse; 993. { 994. long count, size; 995. struct obj *obj; 996. 997. for (count = size = 0, obj = chain; obj; obj = obj->nobj) { 998. if (top) { 999. count++; 1000. size += sizeof(struct obj) + obj->onamelth; 1001. } 1002. if (recurse && obj->cobj) 1003. count_obj(obj->cobj, total_count, total_size, TRUE, TRUE); 1004. } 1005. *total_count += count; 1006. *total_size += size; 1007. } 1008. 1009. static void 1010. obj_chain(win, src, chain, total_count, total_size) 1011. winid win; 1012. const char *src; 1013. struct obj *chain; 1014. long *total_count; 1015. long *total_size; 1016. { 1017. char buf[BUFSZ]; 1018. long count = 0, size = 0; 1019. 1020. count_obj(chain, &count, &size, TRUE, FALSE); 1021. *total_count += count; 1022. *total_size += size; 1023. Sprintf(buf, template, src, count, size); 1024. putstr(win, 0, buf); 1025. } 1026. 1027. static void 1028. mon_invent_chain(win, src, chain, total_count, total_size) 1029. winid win; 1030. const char *src; 1031. struct monst *chain; 1032. long *total_count; 1033. long *total_size; 1034. { 1035. char buf[BUFSZ]; 1036. long count = 0, size = 0; 1037. struct monst *mon; 1038. 1039. for (mon = chain; mon; mon = mon->nmon) 1040. count_obj(mon->minvent, &count, &size, TRUE, FALSE); 1041. *total_count += count; 1042. *total_size += size; 1043. Sprintf(buf, template, src, count, size); 1044. putstr(win, 0, buf); 1045. } 1046. 1047. static void 1048. contained(win, src, total_count, total_size) 1049. winid win; 1050. const char *src; 1051. long *total_count; 1052. long *total_size; 1053. { 1054. char buf[BUFSZ]; 1055. long count = 0, size = 0; 1056. struct monst *mon; 1057. 1058. count_obj(invent, &count, &size, FALSE, TRUE); 1059. count_obj(fobj, &count, &size, FALSE, TRUE); 1060. count_obj(level.buriedobjlist, &count, &size, FALSE, TRUE); 1061. count_obj(migrating_objs, &count, &size, FALSE, TRUE); 1062. for (mon = fmon; mon; mon = mon->nmon) 1063. count_obj(mon->minvent, &count, &size, FALSE, TRUE); 1064. for (mon = migrating_mons; mon; mon = mon->nmon) 1065. count_obj(mon->minvent, &count, &size, FALSE, TRUE); 1066. 1067. *total_count += count; *total_size += size; 1068. 1069. Sprintf(buf, template, src, count, size); 1070. putstr(win, 0, buf); 1071. } 1072. 1073. static void 1074. mon_chain(win, src, chain, total_count, total_size) 1075. winid win; 1076. const char *src; 1077. struct monst *chain; 1078. long *total_count; 1079. long *total_size; 1080. { 1081. char buf[BUFSZ]; 1082. long count, size; 1083. struct monst *mon; 1084. 1085. for (count = size = 0, mon = chain; mon; mon = mon->nmon) { 1086. count++; 1087. size += sizeof(struct monst) + mon->mxlth + mon->mnamelth; 1088. } 1089. *total_count += count; 1090. *total_size += size; 1091. Sprintf(buf, template, src, count, size); 1092. putstr(win, 0, buf); 1093. } 1094. 1095. /* 1096. * Display memory usage of all monsters and objects on the level. 1097. */ 1098. static int 1099. wiz_show_stats() 1100. { 1101. char buf[BUFSZ]; 1102. winid win; 1103. long total_obj_size = 0, total_obj_count = 0; 1104. long total_mon_size = 0, total_mon_count = 0; 1105. 1106. win = create_nhwindow(NHW_TEXT); 1107. putstr(win, 0, "Current memory statistics:"); 1108. putstr(win, 0, ""); 1109. Sprintf(buf, "Objects, size %d", (int) sizeof(struct obj)); 1110. putstr(win, 0, buf); 1111. putstr(win, 0, ""); 1112. putstr(win, 0, count_str); 1113. 1114. obj_chain(win, "invent", invent, &total_obj_count, &total_obj_size); 1115. obj_chain(win, "fobj", fobj, &total_obj_count, &total_obj_size); 1116. obj_chain(win, "buried", level.buriedobjlist, 1117. &total_obj_count, &total_obj_size); 1118. obj_chain(win, "migrating obj", migrating_objs, 1119. &total_obj_count, &total_obj_size); 1120. mon_invent_chain(win, "minvent", fmon, 1121. &total_obj_count,&total_obj_size); 1122. mon_invent_chain(win, "migrating minvent", migrating_mons, 1123. &total_obj_count, &total_obj_size); 1124. 1125. contained(win, "contained", 1126. &total_obj_count, &total_obj_size); 1127. 1128. putstr(win, 0, separator); 1129. Sprintf(buf, template, "Total", total_obj_count, total_obj_size); 1130. putstr(win, 0, buf); 1131. 1132. putstr(win, 0, ""); 1133. putstr(win, 0, ""); 1134. Sprintf(buf, "Monsters, size %d", (int) sizeof(struct monst)); 1135. putstr(win, 0, buf); 1136. putstr(win, 0, ""); 1137. 1138. mon_chain(win, "fmon", fmon, 1139. &total_mon_count, &total_mon_size); 1140. mon_chain(win, "migrating", migrating_mons, 1141. &total_mon_count, &total_mon_size); 1142. 1143. putstr(win, 0, separator); 1144. Sprintf(buf, template, "Total", total_mon_count, total_mon_size); 1145. putstr(win, 0, buf); 1146. 1147. #ifdef __BORLANDC__ 1148. show_borlandc_stats(win); 1149. #endif 1150. 1151. display_nhwindow(win, FALSE); 1152. destroy_nhwindow(win); 1153. return 0; 1154. } 1155. 1156. void 1157. sanity_check() 1158. { 1159. obj_sanity_check(); 1160. timer_sanity_check(); 1161. } 1162. 1163. #endif /* WIZARD */ 1164. 1165. #define unctrl(c) ((c) <= C('z') ? (0x60 | (c)) : (c)) 1166. #define unmeta(c) (0x7f & (c)) 1167. 1168. 1169. void 1170. rhack(cmd) 1171. register char *cmd; 1172. { 1173. boolean do_walk, do_rush, prefix_seen, bad_command, 1174. firsttime = (cmd == 0); 1175. 1176. if (firsttime) { 1177. flags.nopick = 0; 1178. cmd = parse(); 1179. } 1180. if (*cmd == '\033') { 1181. flags.move = FALSE; 1182. return; 1183. } 1184. #ifdef REDO 1185. if (*cmd == DOAGAIN && !in_doagain && saveq[0]) { 1186. in_doagain = TRUE; 1187. stail = 0; 1188. rhack((char *)0); /* read and execute command */ 1189. in_doagain = FALSE; 1190. return; 1191. } 1192. /* Special case of *cmd == ' ' handled better below */ 1193. if(!*cmd || *cmd == (char)0377) { 1194. #else 1195. if(!*cmd || *cmd == (char)0377 || 1196. (!flags.rest_on_space && *cmd == ' ')) { 1197. #endif 1198. nhbell(); 1199. flags.move = FALSE; 1200. return; /* probably we just had an interrupt */ 1201. } 1202. 1203. /* handle most movement commands */ 1204. do_walk = do_rush = prefix_seen = FALSE; 1205. switch (*cmd) { 1206. case 'g': if (movecmd(cmd[1])) { 1207. flags.run = 2; 1208. do_rush = TRUE; 1209. } else 1210. prefix_seen = TRUE; 1211. break; 1212. case '5': if (!flags.num_pad) break; /* else FALLTHRU */ 1213. case 'G': if (movecmd(lowc(cmd[1]))) { 1214. flags.run = 3; 1215. do_rush = TRUE; 1216. } else 1217. prefix_seen = TRUE; 1218. break; 1219. case '-': if (!flags.num_pad) break; /* else FALLTHRU */ 1220. case 'm': if (movecmd(cmd[1]) || u.dz) { 1221. flags.run = 0; 1222. flags.nopick = 1; 1223. if (!u.dz) do_walk = TRUE; 1224. else cmd[0] = cmd[1]; /* "m<" or "m>" */ 1225. } else 1226. prefix_seen = TRUE; 1227. break; 1228. case 'M': if (movecmd(lowc(cmd[1]))) { 1229. flags.run = 1; 1230. flags.nopick = 1; 1231. do_rush = TRUE; 1232. } else 1233. prefix_seen = TRUE; 1234. break; 1235. case '0': if (!flags.num_pad) break; 1236. (void)ddoinv(); /* a convenience borrowed from the PC */ 1237. flags.move = FALSE; 1238. multi = 0; 1239. return; 1240. default: if (movecmd(*cmd)) { /* ordinary movement */ 1241. do_walk = TRUE; 1242. } else if (movecmd(flags.num_pad ? 1243. unmeta(*cmd) : lowc(*cmd))) { 1244. flags.run = 1; 1245. do_rush = TRUE; 1246. } else if (movecmd(unctrl(*cmd))) { 1247. flags.run = 3; 1248. do_rush = TRUE; 1249. } 1250. break; 1251. } 1252. if (do_walk) { 1253. if (multi) flags.mv = TRUE; 1254. domove(); 1255. return; 1256. } else if (do_rush) { 1257. if (firsttime) { 1258. if (!multi) multi = max(COLNO,ROWNO); 1259. u.last_str_turn = 0; 1260. } 1261. flags.mv = TRUE; 1262. domove(); 1263. return; 1265. /* don't report "unknown command" for change of heart... */ 1266. bad_command = FALSE; 1267. } else if (*cmd == ' ' && !flags.rest_on_space) { 1268. bad_command = TRUE; /* skip cmdlist[] loop */ 1269. 1270. /* handle all other commands */ 1271. } else { 1272. register const struct func_tab *tlist; 1273. int res, NDECL((*func)); 1274. 1275. for (tlist = cmdlist; tlist->f_char; tlist++) { 1276. if ((*cmd & 0xff) != (tlist->f_char & 0xff)) continue; 1277. 1278. if (u.uburied && !tlist->can_if_buried) { 1279. You_cant("do that while you are buried!"); 1280. res = 0; 1281. } else { 1282. /* we discard 'const' because some compilers seem to have 1283. trouble with the pointer passed to set_occupation() */ 1284. func = ((struct func_tab *)tlist)->f_funct; 1285. if (tlist->f_text && !occupation && multi) 1286. set_occupation(func, tlist->f_text, multi); 1287. res = (*func)(); /* perform the command */ 1288. } 1289. if (!res) { 1290. flags.move = FALSE; 1291. multi = 0; 1292. } 1293. return; 1294. } 1295. /* if we reach here, cmd wasn't found in cmdlist[] */ 1296. bad_command = TRUE; 1297. } 1298. 1299. if (bad_command) { 1300. char expcmd[10]; 1301. register char *cp = expcmd; 1302. 1303. while (*cmd && (int)(cp - expcmd) < (int)(sizeof expcmd - 3)) { 1304. if (*cmd >= 040 && *cmd < 0177) { 1305. *cp++ = *cmd++; 1306. } else if (*cmd & 0200) { 1307. *cp++ = 'M'; 1308. *cp++ = '-'; 1309. *cp++ = *cmd++ &= ~0200; 1310. } else { 1311. *cp++ = '^'; 1312. *cp++ = *cmd++ ^ 0100; 1313. } 1314. } 1315. *cp = '\0'; 1316. Norep("Unknown command '%s'.", expcmd); 1317. } 1318. /* didn't move */ 1319. flags.move = FALSE; 1320. multi = 0; 1321. return; 1322. } 1323. 1324. int 1325. xytod(x, y) /* convert an x,y pair into a direction code */ 1326. schar x, y; 1327. { 1328. register int dd; 1329. 1330. for(dd = 0; dd < 8; dd++) 1331. if(x == xdir[dd] && y == ydir[dd]) return dd; 1332. 1333. return -1; 1334. } 1335. 1336. void 1337. dtoxy(cc,dd) /* convert a direction code into an x,y pair */ 1338. coord *cc; 1339. register int dd; 1340. { 1341. cc->x = xdir[dd]; 1342. cc->y = ydir[dd]; 1343. return; 1344. } 1345. 1346. int 1347. movecmd(sym) /* also sets u.dz, but returns false for <> */ 1348. char sym; 1349. { 1350. register const char *dp; 1351. register const char *sdp; 1352. if(flags.num_pad) sdp = ndir; else sdp = sdir; /* DICE workaround */ 1353. 1354. u.dz = 0; 1355. if(!(dp = index(sdp, sym))) return 0; 1356. u.dx = xdir[dp-sdp]; 1357. u.dy = ydir[dp-sdp]; 1358. u.dz = zdir[dp-sdp]; 1359. if (u.dx && u.dy && u.umonnum == PM_GRID_BUG) { 1360. u.dx = u.dy = 0; 1361. return 0; 1362. } 1363. return !u.dz; 1364. } 1365. 1366. int 1367. getdir(s) 1368. const char *s; 1369. { 1370. char dirsym; 1371. 1372. #ifdef REDO 1373. if(in_doagain) 1374. dirsym = readchar(); 1375. else 1376. #endif 1377. dirsym = yn_function (s ? s : "In what direction?", 1378. (char *)0, '\0'); 1379. #ifdef REDO 1380. savech(dirsym); 1381. #endif 1382. if(dirsym == '.' || dirsym == 's') 1383. u.dx = u.dy = u.dz = 0; 1384. else if(!movecmd(dirsym) && !u.dz) { 1385. if(!index(quitchars, dirsym)) 1386. pline("What a strange direction!"); 1387. return 0; 1388. } 1389. if(!u.dz && (Stunned || (Confusion && !rn2(5)))) confdir(); 1390. return 1; 1391. } 1392. 1393. #endif /* OVL1 */ 1394. #ifdef OVLB 1395. 1396. void 1397. confdir() 1398. { 1399. register int x = (u.umonnum == PM_GRID_BUG) ? 2*rn2(4) : rn2(8); 1400. u.dx = xdir[x]; 1401. u.dy = ydir[x]; 1402. return; 1403. } 1404. 1405. #endif /* OVLB */ 1406. #ifdef OVL0 1407. 1408. int 1409. isok(x,y) 1410. register int x, y; 1411. { 1412. /* x corresponds to curx, so x==1 is the first column. Ach. %% */ 1413. return x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1; 1414. } 1415. 1416. static NEARDATA int last_multi; 1417. 1418. /* 1419. * convert a MAP window position into a movecmd 1420. */ 1421. int 1422. click_to_cmd(x, y, mod) 1423. int x, y, mod; 1424. { 1425. x -= u.ux; 1426. y -= u.uy; 1427. /* convert without using floating point, allowing sloppy clicking */ 1428. if(x > 2*abs(y)) 1429. x = 1, y = 0; 1430. else if(y > 2*abs(x)) 1431. x = 0, y = 1; 1432. else if(x < -2*abs(y)) 1433. x = -1, y = 0; 1434. else if(y < -2*abs(x)) 1435. x = 0, y = -1; 1436. else 1437. x = sgn(x), y = sgn(y); 1438. 1439. if(x == 0 && y == 0) /* map click on player to "rest" command */ 1440. return '.'; 1441. 1442. x = xytod(x, y); 1443. if(mod == CLICK_1) { 1444. return (flags.num_pad ? ndir[x] : sdir[x]); 1445. } else { 1446. return (flags.num_pad ? M(ndir[x]) : 1447. (sdir[x] - 'a' + 'A')); /* run command */ 1448. } 1449. } 1450. 1451. STATIC_OVL char * 1452. parse() 1453. { 1454. #ifdef LINT /* static char in_line[COLNO]; */ 1455. char in_line[COLNO]; 1456. #else 1457. static char in_line[COLNO]; 1458. #endif 1459. register int foo; 1460. boolean prezero = FALSE; 1461. 1462. multi = 0; 1463. flags.move = 1; 1464. flush_screen(1); /* Flush screen buffer. Put the cursor on the hero. */ 1465. 1466. if (!flags.num_pad || (foo = readchar()) == 'n') 1467. for (;;) { 1468. foo = readchar(); 1469. if (foo >= '0' && foo <= '9') { 1470. multi = 10 * multi + foo - '0'; 1471. if (multi < 0 || multi >= LARGEST_INT) multi = LARGEST_INT; 1472. if (multi > 9) { 1473. clear_nhwindow(WIN_MESSAGE); 1474. Sprintf(in_line, "Count: %d", multi); 1475. pline(in_line); 1476. mark_synch(); 1477. } 1478. last_multi = multi; 1479. if (!multi && foo == '0') prezero = TRUE; 1480. } else break; /* not a digit */ 1481. } 1482. 1483. if (foo == '\033') { /* esc cancels count (TH) */ 1484. clear_nhwindow(WIN_MESSAGE); 1485. multi = last_multi = 0; 1486. # ifdef REDO 1487. } else if (foo == DOAGAIN || in_doagain) { 1488. multi = last_multi; 1489. } else { 1490. last_multi = multi; 1491. savech(0); /* reset input queue */ 1492. savech((char)foo); 1493. # endif 1494. } 1495. 1496. if (multi) { 1497. multi--; 1498. save_cm = in_line; 1499. } else { 1500. save_cm = (char *)0; 1501. } 1502. in_line[0] = foo; 1503. in_line[1] = '\0'; 1504. if (foo == 'g' || foo == 'G' || (flags.num_pad && foo == '5') || 1505. foo == 'm' || foo == 'M') { 1506. foo = readchar(); 1507. #ifdef REDO 1508. savech((char)foo); 1509. #endif 1510. in_line[1] = foo; 1511. in_line[2] = 0; 1512. } 1513. clear_nhwindow(WIN_MESSAGE); 1514. if (prezero) in_line[0] = '\033'; 1515. return(in_line); 1516. } 1517. 1518. #endif /* OVL0 */ 1519. #ifdef OVLB 1520. 1521. #ifdef UNIX 1522. static 1523. void 1524. end_of_input() 1525. { 1526. exit_nhwindows("End of input?"); 1527. #ifndef NOSAVEONHANGUP 1528. if (!program_state.done_hup++) 1529. (void) dosave0(); 1530. #endif 1531. clearlocks(); 1532. terminate(EXIT_SUCCESS); 1533. } 1534. #endif 1535. 1536. #endif /* OVLB */ 1537. #ifdef OVL0 1538. 1539. char 1540. readchar() 1541. { 1542. register int sym; 1543. int x, y, mod; 1544. 1545. #ifdef REDO 1546. sym = in_doagain ? Getchar() : nh_poskey(&x, &y, &mod); 1547. #else 1548. sym = Getchar(); 1549. #endif 1550. 1551. #ifdef UNIX 1552. # ifdef NR_OF_EOFS 1553. if (sym == EOF) { 1554. register int cnt = NR_OF_EOFS; 1555. /* 1556. * Some SYSV systems seem to return EOFs for various reasons 1557. * (?like when one hits break or for interrupted systemcalls?), 1558. * and we must see several before we quit. 1559. */ 1560. do { 1561. clearerr(stdin); /* omit if clearerr is undefined */ 1562. sym = Getchar(); 1563. } while (--cnt && sym == EOF); 1564. } 1565. # endif /* NR_OF_EOFS */ 1566. if (sym == EOF) 1567. end_of_input(); 1568. #endif /* UNIX */ 1569. 1570. if(sym == 0) /* click event */ 1571. sym = click_to_cmd(x, y, mod); 1572. return((char) sym); 1573. } 1574. #endif /* OVL0 */ 1575. 1576. /*cmd.c*/