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