Source:NetHack 2.3e/read.c
Jump to navigation
Jump to search
Below is the full text to read.c from the source code of NetHack 2.3e.
Warning! This is the source code from an old release. For newer releases, see Source code
Screenshots and source code from Hack are used under the CWI license.
1. /* SCCS Id: @(#)read.c 2.3 88/01/21 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. 4. #include "hack.h" 5. 6. extern struct monst *makemon(); 7. extern struct permonst pm_eel; 8. extern struct obj *mkobj_at(); 9. char *hcolor(); 10. boolean known; 11. int identify(); 12. 13. doread() { 14. register struct obj *scroll; 15. register boolean confused = (Confusion != 0); 16. 17. known = FALSE; 18. scroll = getobj("#-?", "read"); /* "#-" added by GAN 10/22/86 */ 19. if(!scroll) return(0); 20. 21. /* below added to allow reading of fortune cookies */ 22. if(scroll->otyp == FORTUNE_COOKIE) { 23. if(Blind) { 24. pline("This cookie has a scrap of paper inside!"); 25. pline("What a pity, that you cannot read it!"); 26. } else 27. outrumor(); 28. useup(scroll); 29. return(1); 30. } else 31. if(scroll->olet != SCROLL_SYM) { 32. pline("That is a silly thing to read."); 33. return(0); 34. } 35. 36. if(!scroll->dknown && Blind) { 37. pline("Being blind, you cannot read the formula on the scroll."); 38. return(0); 39. } 40. if(Blind) 41. pline("As you pronounce the formula on it, the scroll disappears."); 42. else 43. pline("As you read the scroll, it disappears."); 44. if(confused) { 45. if (Hallucination) 46. pline("Being so trippy, you screw up ... "); 47. else 48. pline("Being confused, you mispronounce the magic words ... "); 49. } 50. if(!seffects(scroll)) { 51. if(!objects[scroll->otyp].oc_name_known) { 52. if(known && !confused) { 53. objects[scroll->otyp].oc_name_known = 1; 54. more_experienced(0,10); 55. } else if(!objects[scroll->otyp].oc_uname) 56. docall(scroll); 57. } 58. #ifdef MARKER 59. if(!(scroll->otyp == SCR_BLANK_PAPER) || confused) 60. #endif 61. useup(scroll); 62. } 63. return(1); 64. } 65. 66. seffects(sobj) 67. register struct obj *sobj; 68. { 69. extern struct obj *some_armor(); 70. register boolean confused = (Confusion != 0); 71. 72. switch(sobj->otyp) { 73. #ifdef MAIL 74. case SCR_MAIL: 75. readmail(/* scroll */); 76. break; 77. #endif 78. case SCR_ENCHANT_ARMOR: 79. { 80. register struct obj *otmp = some_armor(); 81. if(!otmp) { 82. strange_feeling(sobj,"Your skin glows then fades."); 83. return(1); 84. } 85. if(confused) { 86. pline("Your %s is covered by a shimmering %s %s!", 87. objects[otmp->otyp].oc_name, Hallucination ? hcolor() : 88. "gold", (otmp->otyp == SHIELD ? "layer" : "shield")); 89. otmp->rustfree = 1; 90. break; 91. } 92. #ifdef KAA 93. if(otmp->spe > (otmp->otyp == ELFIN_CHAIN_MAIL ? 5 : 3) 94. && rn2(otmp->spe)) { 95. #else 96. if(otmp->spe > 3 && rn2(otmp->spe)) { 97. #endif 98. pline("Your %s glows violently %s for a while, then evaporates.", 99. objects[otmp->otyp].oc_name, 100. Hallucination ? hcolor() : "green"); 101. useup(otmp); 102. break; 103. } 104. pline("Your %s glows %s for a moment.", 105. objects[otmp->otyp].oc_name, 106. Hallucination ? hcolor() : "green"); 107. otmp->cursed = 0; 108. otmp->spe++; 109. break; 110. } 111. case SCR_DESTROY_ARMOR: 112. if(confused) { 113. register struct obj *otmp = some_armor(); 114. if(!otmp) { 115. strange_feeling(sobj,"Your bones itch."); 116. return(1); 117. } 118. pline("Your %s glows %s for a moment.", 119. objects[otmp->otyp].oc_name, 120. Hallucination ? hcolor() : "purple"); 121. otmp->rustfree = 0; 122. break; 123. } 124. if(!destroy_arm()) { 125. strange_feeling(sobj,"Your skin itches."); 126. return(1); 127. } 128. break; 129. case SCR_CONFUSE_MONSTER: 130. #ifdef SPELLS 131. case SPE_CONFUSE_MONSTER: 132. #endif 133. if(u.usym != '@') { 134. pline("You feel confused."); 135. HConfusion += rnd(100); 136. } else if(confused) { 137. pline("Your hands begin to glow %s.", 138. Hallucination ? hcolor() : "purple"); 139. HConfusion += rnd(100); 140. } else { 141. pline("Your hands begin to glow %s.", 142. Hallucination ? hcolor() : "blue"); 143. u.umconf = 1; 144. } 145. break; 146. case SCR_SCARE_MONSTER: 147. #ifdef SPELLS 148. case SPE_CAUSE_FEAR: 149. #endif 150. { register int ct = 0; 151. register struct monst *mtmp; 152. 153. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 154. if(cansee(mtmp->mx,mtmp->my)) { 155. if(confused) 156. mtmp->mflee = mtmp->mfroz = mtmp->msleep = 0; 157. else 158. if (! resist(mtmp, sobj->olet, 0, NOTELL)) 159. mtmp->mflee = 1; 160. ct++; 161. } 162. if(!ct) 163. pline("You hear %s in the distance.", 164. (confused) ? "sad wailing" : "maniacal laughter"); 165. #ifdef KAA 166. # ifdef SPELLS 167. else if(sobj->otyp == SCR_SCARE_MONSTER) 168. # endif 169. pline ("You hear %s close by.", 170. (confused) ? "sad wailing" : "maniacal laughter"); 171. #endif 172. break; 173. } 174. case SCR_BLANK_PAPER: 175. if(confused) 176. pline("You see strange patterns on this scroll."); 177. else { 178. pline("This scroll seems to be blank."); 179. #ifdef MARKER 180. pline("No, wait..."); 181. known = TRUE; 182. #endif 183. } 184. break; 185. case SCR_REMOVE_CURSE: 186. #ifdef SPELLS 187. case SPE_REMOVE_CURSE: 188. #endif 189. { register struct obj *obj; 190. if(confused) 191. if (Hallucination) 192. pline("You feel the power of the Force against you!"); 193. else 194. pline("You feel like you need some help."); 195. else 196. if (Hallucination) 197. pline("You feel in touch with the Universal Oneness."); 198. else 199. pline("You feel like someone is helping you."); 200. for(obj = invent; obj ; obj = obj->nobj) 201. if(obj->owornmask) 202. obj->cursed = confused; 203. if(Punished && !confused) { 204. Punished = 0; 205. freeobj(uchain); 206. unpobj(uchain); 207. free((char *) uchain); 208. uball->spe = 0; 209. uball->owornmask &= ~W_BALL; 210. uchain = uball = (struct obj *) 0; 211. } 212. break; 213. } 214. case SCR_CREATE_MONSTER: 215. #ifdef SPELLS 216. case SPE_CREATE_MONSTER: 217. #endif 218. { register int cnt = 1; 219. 220. if(!rn2(73)) cnt += rnd(4); 221. if(confused) cnt += 12; 222. while(cnt--) 223. #ifdef WIZARD 224. if(wizard) { 225. char buf[BUFSZ], cmlet; 226. struct permonst *crmonst; 227. 228. do { 229. pline("What monster to create? "); 230. getlin(buf); 231. } while(strlen(buf) != 1); 232. cmlet = buf[0]; 233. for(crmonst = mons; crmonst->mlet != cmlet && 234. crmonst != PM_EEL; crmonst++) ; 235. (void) makemon(crmonst, u.ux, u.uy); 236. } else 237. #endif /* WIZARD /**/ 238. (void) makemon(confused ? PM_ACID_BLOB : 239. (struct permonst *) 0, u.ux, u.uy); 240. break; 241. } 242. case SCR_ENCHANT_WEAPON: 243. if(uwep && uwep->olet == WEAPON_SYM && confused) { 244. /* olet check added 10/25/86 GAN */ 245. pline("Your %s covered by a shimmering %s shield!", 246. aobjnam(uwep, "are"), 247. Hallucination ? hcolor() : "gold"); 248. uwep->rustfree = 1; 249. } else 250. if(!chwepon(sobj, 1)) /* tests for !uwep */ 251. return(1); 252. break; 253. case SCR_DAMAGE_WEAPON: 254. if(uwep && uwep->olet == WEAPON_SYM && confused) { 255. /* olet check added 10/25/86 GAN */ 256. pline("Your %s %s for a moment.", 257. aobjnam(uwep,"glow"), 258. Hallucination ? hcolor() : "purple"); 259. uwep->rustfree = 0; 260. } else 261. if(!chwepon(sobj, -1)) /* tests for !uwep */ 262. return(1); 263. break; 264. case SCR_TAMING: 265. #ifdef SPELLS 266. case SPE_CHARM_MONSTER: 267. #endif 268. { register int i,j; 269. register int bd = confused ? 5 : 1; 270. register struct monst *mtmp; 271. 272. for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) 273. if(mtmp = m_at(u.ux+i, u.uy+j)) 274. if(!resist(mtmp, sobj->olet, 0, NOTELL)) 275. (void) tamedog(mtmp, (struct obj *) 0); 276. break; 277. } 278. case SCR_GENOCIDE: 279. pline("You have found a scroll of genocide!"); 280. #ifdef SPELLS 281. case SPE_GENOCIDE: 282. #endif 283. known = TRUE; 284. do_genocide(); 285. break; 286. case SCR_LIGHT: 287. if(!Blind) known = TRUE; 288. litroom(!confused); 289. break; 290. case SCR_TELEPORTATION: 291. if(confused) 292. level_tele(); 293. else { 294. #ifdef QUEST 295. register int oux = u.ux, ouy = u.uy; 296. tele(); 297. if(dist(oux, ouy) > 100) known = TRUE; 298. #else 299. register int uroom = inroom(u.ux, u.uy); 300. tele(); 301. if(uroom != inroom(u.ux, u.uy)) known = TRUE; 302. #endif 303. if(Teleport_control) 304. known = TRUE; 305. } 306. break; 307. case SCR_GOLD_DETECTION: 308. /* Unfortunately this code has become slightly less elegant, 309. now that gold and traps no longer are of the same type. */ 310. if(confused) { 311. register struct trap *ttmp; 312. 313. if(!ftrap) { 314. strange_feeling(sobj, "Your toes stop itching."); 315. return(1); 316. } else { 317. for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) 318. if(ttmp->tx != u.ux || ttmp->ty != u.uy) 319. goto outtrapmap; 320. /* only under me - no separate display required */ 321. pline("Your toes itch!"); 322. break; 323. outtrapmap: 324. cls(); 325. for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) 326. at(ttmp->tx, ttmp->ty, Hallucination ? rndobjsym() : GOLD_SYM); 327. prme(); 328. pline("You feel very greedy!"); 329. } 330. } else { 331. register struct gold *gtmp; 332. 333. if(!fgold) { 334. strange_feeling(sobj, "You feel materially poor."); 335. return(1); 336. } else { 337. known = TRUE; 338. for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) 339. if(gtmp->gx != u.ux || gtmp->gy != u.uy) 340. goto outgoldmap; 341. /* only under me - no separate display required */ 342. pline("You notice some gold between your feet."); 343. break; 344. outgoldmap: 345. cls(); 346. for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) 347. at(gtmp->gx, gtmp->gy, Hallucination ? rndobjsym() : GOLD_SYM); 348. prme(); 349. pline("You feel very greedy, and sense gold!"); 350. } 351. } 352. /* common sequel */ 353. more(); 354. docrt(); 355. break; 356. case SCR_FOOD_DETECTION: 357. #ifdef SPELLS 358. case SPE_DETECT_FOOD: 359. #endif 360. { register ct = 0, ctu = 0; 361. register struct obj *obj; 362. register char foodsym = confused ? POTION_SYM : FOOD_SYM; 363. 364. for(obj = fobj; obj; obj = obj->nobj) 365. if(obj->olet == foodsym) { 366. if(obj->ox == u.ux && obj->oy == u.uy) ctu++; 367. else ct++; 368. } 369. if(!ct && !ctu) { 370. strange_feeling(sobj,"Your nose twitches."); 371. return(1); 372. } else if(!ct) { 373. known = TRUE; 374. pline("You smell %s close nearby.", 375. confused ? "something" : "food"); 376. 377. } else { 378. known = TRUE; 379. cls(); 380. for(obj = fobj; obj; obj = obj->nobj) 381. if(obj->olet == foodsym) 382. at(obj->ox, obj->oy, Hallucination ? rndobjsym() : 383. FOOD_SYM); 384. prme(); 385. pline("Your nose tingles and you smell %s!", 386. confused ? "something" : "food"); 387. more(); 388. docrt(); 389. } 390. break; 391. } 392. case SCR_IDENTIFY: 393. /* known = TRUE; */ 394. if(confused) 395. pline("You identify this as an identify scroll."); 396. else 397. pline("This is an identify scroll."); 398. useup(sobj); 399. objects[SCR_IDENTIFY].oc_name_known = 1; 400. #ifdef SPELLS 401. case SPE_IDENTIFY: 402. #endif 403. if(!confused) 404. while(!ggetobj("identify", identify, rn2(5) ? 1 : rn2(5)) && invent); 405. return(1); 406. case SCR_MAGIC_MAPPING: 407. known = TRUE; 408. pline("On this scroll %s a map!", confused ? "was" : "is"); 409. #ifdef SPELLS 410. case SPE_MAGIC_MAPPING: 411. #endif 412. do_mapping(); 413. break; 414. case SCR_AMNESIA: 415. { register int zx, zy; 416. 417. known = TRUE; 418. for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++) 419. if(!confused || rn2(7)) 420. if(!cansee(zx,zy)) 421. levl[zx][zy].seen = 0; 422. docrt(); 423. pline("Who was that Maude person anyway?"); 424. #ifdef SPELLS 425. losespells(); 426. #endif 427. break; 428. } 429. case SCR_FIRE: 430. { register int num; 431. register struct monst *mtmp; 432. 433. /* 434. * Note: This case was modified 11/4/86 by DKC to eliminate the problem with 435. * reading a scroll of fire while confused or resistant to fire. Formerly, 436. * the code failed to initialize the variable "num" in these cases, resulting 437. * in monsters being hit for a possibly large (and possibly negative) damage. 438. * The actions taken now are: 439. * If the player is fire resistant, monsters 440. * take the normal damage (1-6 except for Y's and F's), and the player is 441. * unaffected. 442. */ 443. known = TRUE; 444. if(confused) { 445. if(Fire_resistance) 446. pline("Oh look, what a pretty fire in your hands."); 447. else { 448. pline("The scroll catches fire and you burn your hands."); 449. losehp(1, "scroll of fire"); 450. } 451. break; 452. } 453. pline("The scroll erupts in a tower of flame!"); 454. num = rnd(6); 455. if(Fire_resistance) 456. pline("You are uninjured."); 457. else { 458. u.uhpmax -= num; 459. losehp(num, "scroll of fire"); 460. } 461. num = (2*num + 1)/3; 462. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 463. if(dist(mtmp->mx,mtmp->my) < 3) { 464. mtmp->mhp -= num; /* No saving throw! */ 465. if(index("FY", mtmp->data->mlet)) 466. mtmp->mhp -= 3*num; /* this might well kill 'F's */ 467. if(mtmp->mhp < 1) { 468. killed(mtmp); 469. break; /* primitive */ 470. } 471. } 472. } 473. break; 474. } 475. case SCR_PUNISHMENT: 476. known = TRUE; 477. if(confused) { 478. pline("You feel guilty."); 479. break; 480. } 481. pline("You are being punished for your misbehavior!"); 482. if(Punished){ 483. pline("Your iron ball gets heavier."); 484. uball->owt += 15; 485. break; 486. } 487. Punished = INTRINSIC; 488. setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN); 489. setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL); 490. uball->spe = 1; /* special ball (see save) */ 491. break; 492. default: 493. impossible("What weird effect is this? (%u)", sobj->otyp); 494. } 495. return(0); 496. } 497. 498. identify(otmp) /* also called by newmail() */ 499. register struct obj *otmp; 500. { 501. objects[otmp->otyp].oc_name_known = 1; 502. #ifdef KAA 503. otmp->known = 1; 504. if (otmp->olet != WEAPON_SYM) otmp->dknown = 1; 505. /* Now, the dknown field is special for weapons, indicating blessing. */ 506. #else 507. otmp->known = otmp->dknown = 1; 508. #endif 509. prinv(otmp); 510. return(1); 511. } 512. 513. litroom(on) 514. register boolean on; 515. { 516. register num,zx,zy; 517. 518. /* first produce the text (provided he is not blind) */ 519. if(Blind) goto do_it; 520. if(!on) { 521. if(u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR || 522. !levl[u.ux][u.uy].lit) { 523. pline("It seems even darker in here than before."); 524. return; 525. } else 526. pline("It suddenly becomes dark in here."); 527. } else { 528. if(u.uswallow){ 529. pline("%s's stomach is lit.", Monnam(u.ustuck)); 530. return; 531. } 532. if(!xdnstair){ 533. pline("Nothing Happens."); 534. return; 535. } 536. #ifdef QUEST 537. pline("The cave lights up around you, then fades."); 538. return; 539. #else 540. if(levl[u.ux][u.uy].typ == CORR) { 541. pline("The corridor lights up around you, then fades."); 542. return; 543. } else if(levl[u.ux][u.uy].lit) { 544. pline("The light here seems better now."); 545. return; 546. } else 547. pline("The room is lit."); 548. #endif 549. } 550. 551. do_it: 552. #ifdef QUEST 553. return; 554. #else 555. if(levl[u.ux][u.uy].lit == on) 556. return; 557. if(levl[u.ux][u.uy].typ == DOOR) { 558. if(IS_ROOM(levl[u.ux][u.uy+1].typ)) zy = u.uy+1; 559. else if(IS_ROOM(levl[u.ux][u.uy-1].typ)) zy = u.uy-1; 560. else zy = u.uy; 561. if(IS_ROOM(levl[u.ux+1][u.uy].typ)) zx = u.ux+1; 562. else if(IS_ROOM(levl[u.ux-1][u.uy].typ)) zx = u.ux-1; 563. else zx = u.ux; 564. } else { 565. zx = u.ux; 566. zy = u.uy; 567. } 568. for(seelx = u.ux; (num = levl[seelx-1][zy].typ) != CORR && num != 0; 569. seelx--); 570. for(seehx = u.ux; (num = levl[seehx+1][zy].typ) != CORR && num != 0; 571. seehx++); 572. for(seely = u.uy; (num = levl[zx][seely-1].typ) != CORR && num != 0; 573. seely--); 574. for(seehy = u.uy; (num = levl[zx][seehy+1].typ) != CORR && num != 0; 575. seehy++); 576. for(zy = seely; zy <= seehy; zy++) 577. for(zx = seelx; zx <= seehx; zx++) { 578. levl[zx][zy].lit = on; 579. if(!Blind && dist(zx,zy) > 2) 580. if(on) prl(zx,zy); else nosee(zx,zy); 581. } 582. if(!on) seehx = 0; 583. #endif 584. } 585. 586. /* Test whether we may genocide all monsters with symbol ch */ 587. monstersym(ch) /* arnold@ucsfcgl */ 588. register char ch; 589. { 590. register struct permonst *mp; 591. 592. /* 593. * can't genocide certain monsters 594. */ 595. #ifdef SAC 596. if (index("123 &:", ch)) return FALSE; 597. #else 598. if (index("12 &:", ch)) return FALSE; 599. #endif 600. if (ch == pm_eel.mlet) return TRUE; 601. for (mp = mons; mp < &mons[CMNUM+2]; mp++) 602. if (mp->mlet == ch) return TRUE; 603. 604. return FALSE; 605. } 606. 607. do_genocide() { 608. extern char genocided[], fut_geno[]; 609. char buf[BUFSZ]; 610. register struct monst *mtmp, *mtmp2; 611. 612. if(Confusion != 0) *buf = u.usym; 613. else do { 614. pline("What monster do you want to genocide (Type the letter)? "); 615. getlin(buf); 616. } 617. 618. while(strlen(buf) != 1 || !monstersym(*buf)); 619. 620. if(!index(fut_geno, *buf)) charcat(fut_geno, *buf); 621. if(!index(genocided, *buf)) charcat(genocided, *buf); 622. else { 623. pline("Such monsters do not exist in this world."); 624. return; 625. } 626. for(mtmp = fmon; mtmp; mtmp = mtmp2){ 627. mtmp2 = mtmp->nmon; 628. if(mtmp->data->mlet == *buf) 629. mondead(mtmp); 630. } 631. pline("Wiped out all %c's.", Hallucination ? '@' : *buf); 632. /* Scare the hallucinating player */ 633. if(*buf == '@') { 634. u.uhp = -1; 635. killer = "scroll of genocide"; 636. /* A polymorphed character will die as soon as he is rehumanized. */ 637. if(u.usym != '@') pline("You feel dead inside."); 638. else done("died"); 639. } 640. #ifdef KAA 641. else if (*buf==u.usym) rehumanize(); 642. #endif 643. } 644. 645. do_mapping() 646. { 647. register struct rm *lev; 648. register int num, zx, zy; 649. 650. for(zy = 0; zy < ROWNO; zy++) 651. for(zx = 0; zx < COLNO; zx++) { 652. 653. if((Confusion != 0) && rn2(7)) continue; 654. lev = &(levl[zx][zy]); 655. if((num = lev->typ) == 0) continue; 656. 657. if(num == SCORR) { 658. lev->typ = CORR; 659. lev->scrsym = CORR_SYM; 660. } else if(num == SDOOR) { 661. lev->typ = DOOR; 662. lev->scrsym = DOOR_SYM; 663. /* do sth in doors ? */ 664. } else if(lev->seen) continue; 665. #ifndef QUEST 666. if(num != ROOM) 667. #endif 668. { 669. lev->seen = lev->new = 1; 670. if(lev->scrsym == STONE_SYM || !lev->scrsym) 671. newsym(zx,zy); 672. else on_scr(zx,zy); 673. } 674. } 675. } 676. 677. destroy_arm() { 678. 679. if(uarm) { 680. pline("Your armor turns to dust and falls to the floor!"); 681. useup(uarm); 682. #ifdef SHIRT 683. } else if(uarmu) { 684. pline("Your shirt crumbles into tiny threads and falls apart!"); 685. useup(uarmu); 686. #endif 687. } else if(uarmh) { 688. pline("Your helmet turns to dust and is blown away!"); 689. useup(uarmh); 690. } else if(uarmg) { 691. pline("Your gloves vanish!"); 692. useup(uarmg); 693. selftouch("You"); 694. } else if(uarms) { 695. pline("Your shield crumbles away!"); 696. useup(uarms); 697. } else return(0); /* could not destroy anything */ 698. 699. return(1); 700. }