Source:NetHack 1.3d/read.c
Revision as of 06:56, 1 July 2024 by Furey (talk | contribs) (Delete link-to-particular-source instructions. Source code covers that now. "the latest release" -> "newer releases".)
Below is the full text to read.c from the source code of NetHack 1.3d.
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 1.3 87/07/14 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. 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. { extern struct obj *some_armor(); 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. else 167. pline ("You hear %s close by.", 168. (confused) ? "sad wailing" : "maniacal laughter"); 169. #endif 170. break; 171. } 172. case SCR_BLANK_PAPER: 173. if(confused) 174. pline("You see strange patterns on this scroll."); 175. else { 176. pline("This scroll seems to be blank."); 177. #ifdef MARKER 178. pline("No, wait..."); 179. known = TRUE; 180. #endif 181. } 182. break; 183. case SCR_REMOVE_CURSE: 184. #ifdef SPELLS 185. case SPE_REMOVE_CURSE: 186. #endif 187. { register struct obj *obj; 188. if(confused) 189. if (Hallucination) 190. pline("You feel the power of the Force against you!"); 191. else 192. pline("You feel like you need some help."); 193. else 194. if (Hallucination) 195. pline("You feel in touch with the Universal Oneness."); 196. else 197. pline("You feel like someone is helping you."); 198. for(obj = invent; obj ; obj = obj->nobj) 199. if(obj->owornmask) 200. obj->cursed = confused; 201. if(Punished && !confused) { 202. Punished = 0; 203. freeobj(uchain); 204. unpobj(uchain); 205. free((char *) uchain); 206. uball->spe = 0; 207. uball->owornmask &= ~W_BALL; 208. uchain = uball = (struct obj *) 0; 209. } 210. break; 211. } 212. case SCR_CREATE_MONSTER: 213. #ifdef SPELLS 214. case SPE_CREATE_MONSTER: 215. #endif 216. { register int cnt = 1; 217. 218. if(!rn2(73)) cnt += rnd(4); 219. if(confused) cnt += 12; 220. while(cnt--) 221. #ifdef WIZARD 222. if(wizard) { 223. char buf[BUFSZ], cmlet; 224. struct permonst *crmonst; 225. 226. do { 227. pline("What monster to create? "); 228. getlin(buf); 229. } while(strlen(buf) != 1); 230. cmlet = buf[0]; 231. for(crmonst = mons; crmonst->mlet != cmlet && 232. crmonst != PM_EEL; crmonst++) ; 233. (void) makemon(crmonst, u.ux, u.uy); 234. } else 235. #endif /* WIZARD /**/ 236. (void) makemon(confused ? PM_ACID_BLOB : 237. (struct permonst *) 0, u.ux, u.uy); 238. break; 239. } 240. case SCR_ENCHANT_WEAPON: 241. if(uwep && uwep->olet == WEAPON_SYM && confused) { 242. /* olet check added 10/25/86 GAN */ 243. pline("Your %s covered by a shimmering %s shield!", 244. aobjnam(uwep, "are"), 245. Hallucination ? hcolor() : "gold"); 246. uwep->rustfree = 1; 247. } else 248. if(!chwepon(sobj, 1)) /* tests for !uwep */ 249. return(1); 250. break; 251. case SCR_DAMAGE_WEAPON: 252. if(uwep && uwep->olet == WEAPON_SYM && confused) { 253. /* olet check added 10/25/86 GAN */ 254. pline("Your %s %s for a moment.", 255. aobjnam(uwep,"glow"), 256. Hallucination ? hcolor() : "purple"); 257. uwep->rustfree = 0; 258. } else 259. if(!chwepon(sobj, -1)) /* tests for !uwep */ 260. return(1); 261. break; 262. case SCR_TAMING: 263. #ifdef SPELLS 264. case SPE_CHARM_MONSTER: 265. #endif 266. { register int i,j; 267. register int bd = confused ? 5 : 1; 268. register struct monst *mtmp; 269. 270. for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) 271. if(mtmp = m_at(u.ux+i, u.uy+j)) 272. if(!resist(mtmp, sobj->olet, 0, NOTELL)) 273. (void) tamedog(mtmp, (struct obj *) 0); 274. break; 275. } 276. case SCR_GENOCIDE: 277. pline("You have found a scroll of genocide!"); 278. #ifdef SPELLS 279. case SPE_GENOCIDE: 280. #endif 281. known = TRUE; 282. do_genocide(); 283. break; 284. case SCR_LIGHT: 285. if(!Blind) known = TRUE; 286. litroom(!confused); 287. break; 288. case SCR_TELEPORTATION: 289. if(confused) 290. level_tele(); 291. else { 292. #ifdef QUEST 293. register int oux = u.ux, ouy = u.uy; 294. tele(); 295. if(dist(oux, ouy) > 100) known = TRUE; 296. #else 297. register int uroom = inroom(u.ux, u.uy); 298. tele(); 299. if(uroom != inroom(u.ux, u.uy)) known = TRUE; 300. #endif 301. if(Teleport_control) 302. known = TRUE; 303. } 304. break; 305. case SCR_GOLD_DETECTION: 306. /* Unfortunately this code has become slightly less elegant, 307. now that gold and traps no longer are of the same type. */ 308. if(confused) { 309. register struct trap *ttmp; 310. 311. if(!ftrap) { 312. strange_feeling(sobj, "Your toes stop itching."); 313. return(1); 314. } else { 315. for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) 316. if(ttmp->tx != u.ux || ttmp->ty != u.uy) 317. goto outtrapmap; 318. /* only under me - no separate display required */ 319. pline("Your toes itch!"); 320. break; 321. outtrapmap: 322. cls(); 323. for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) 324. at(ttmp->tx, ttmp->ty, Hallucination ? rndobjsym() : '$'); 325. prme(); 326. pline("You feel very greedy!"); 327. } 328. } else { 329. register struct gold *gtmp; 330. 331. if(!fgold) { 332. strange_feeling(sobj, "You feel materially poor."); 333. return(1); 334. } else { 335. known = TRUE; 336. for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) 337. if(gtmp->gx != u.ux || gtmp->gy != u.uy) 338. goto outgoldmap; 339. /* only under me - no separate display required */ 340. pline("You notice some gold between your feet."); 341. break; 342. outgoldmap: 343. cls(); 344. for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) 345. at(gtmp->gx, gtmp->gy, Hallucination ? rndobjsym() : '$'); 346. prme(); 347. pline("You feel very greedy, and sense gold!"); 348. } 349. } 350. /* common sequel */ 351. more(); 352. docrt(); 353. break; 354. case SCR_FOOD_DETECTION: 355. #ifdef SPELLS 356. case SPE_DETECT_FOOD: 357. #endif 358. { register ct = 0, ctu = 0; 359. register struct obj *obj; 360. register char foodsym = confused ? POTION_SYM : FOOD_SYM; 361. 362. for(obj = fobj; obj; obj = obj->nobj) 363. if(obj->olet == foodsym) { 364. if(obj->ox == u.ux && obj->oy == u.uy) ctu++; 365. else ct++; 366. } 367. if(!ct && !ctu) { 368. strange_feeling(sobj,"Your nose twitches."); 369. return(1); 370. } else if(!ct) { 371. known = TRUE; 372. pline("You smell %s close nearby.", 373. confused ? "something" : "food"); 374. 375. } else { 376. known = TRUE; 377. cls(); 378. for(obj = fobj; obj; obj = obj->nobj) 379. if(obj->olet == foodsym) 380. at(obj->ox, obj->oy, Hallucination ? rndobjsym() : 381. FOOD_SYM); 382. prme(); 383. pline("Your nose tingles and you smell %s!", 384. confused ? "something" : "food"); 385. more(); 386. docrt(); 387. } 388. break; 389. } 390. case SCR_IDENTIFY: 391. /* known = TRUE; */ 392. if(confused) 393. pline("You identify this as an identify scroll."); 394. else 395. pline("This is an identify scroll."); 396. useup(sobj); 397. objects[SCR_IDENTIFY].oc_name_known = 1; 398. #ifdef SPELLS 399. case SPE_IDENTIFY: 400. #endif 401. if(!confused) 402. while(!ggetobj("identify", identify, rn2(5) ? 1 : rn2(5)) && invent); 403. return(1); 404. case SCR_MAGIC_MAPPING: 405. known = TRUE; 406. pline("On this scroll %s a map!", confused ? "was" : "is"); 407. #ifdef SPELLS 408. case SPE_MAGIC_MAPPING: 409. #endif 410. do_mapping(); 411. break; 412. case SCR_AMNESIA: 413. { register int zx, zy; 414. 415. known = TRUE; 416. for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++) 417. if(!confused || rn2(7)) 418. if(!cansee(zx,zy)) 419. levl[zx][zy].seen = 0; 420. docrt(); 421. pline("Who was that Maude person anyway?"); 422. #ifdef SPELLS 423. losespells(); 424. #endif 425. break; 426. } 427. case SCR_FIRE: 428. { register int num; 429. register struct monst *mtmp; 430. 431. /* 432. * Note: This case was modified 11/4/86 by DKC to eliminate the problem with 433. * reading a scroll of fire while confused or resistant to fire. Formerly, 434. * the code failed to initialize the variable "num" in these cases, resulting 435. * in monsters being hit for a possibly large (and possibly negative) damage. 436. * The actions taken now are: 437. * If the player is fire resistant, monsters 438. * take the normal damage (1-6 except for Y's and F's), and the player is 439. * unaffected. 440. */ 441. known = TRUE; 442. if(confused) { 443. if(Fire_resistance) 444. pline("Oh look, what a pretty fire in your hands."); 445. else { 446. pline("The scroll catches fire and you burn your hands."); 447. losehp(1, "scroll of fire"); 448. } 449. break; 450. } 451. pline("The scroll erupts in a tower of flame!"); 452. num = rnd(6); 453. if(Fire_resistance) 454. pline("You are uninjured."); 455. else { 456. u.uhpmax -= num; 457. losehp(num, "scroll of fire"); 458. } 459. num = (2*num + 1)/3; 460. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 461. if(dist(mtmp->mx,mtmp->my) < 3) { 462. mtmp->mhp -= num; /* No saving throw! */ 463. if(index("FY", mtmp->data->mlet)) 464. mtmp->mhp -= 3*num; /* this might well kill 'F's */ 465. if(mtmp->mhp < 1) { 466. killed(mtmp); 467. break; /* primitive */ 468. } 469. } 470. } 471. break; 472. } 473. case SCR_PUNISHMENT: 474. known = TRUE; 475. if(confused) { 476. pline("You feel guilty."); 477. break; 478. } 479. pline("You are being punished for your misbehaviour!"); 480. if(Punished){ 481. pline("Your iron ball gets heavier."); 482. uball->owt += 15; 483. break; 484. } 485. Punished = INTRINSIC; 486. setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN); 487. setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL); 488. uball->spe = 1; /* special ball (see save) */ 489. break; 490. default: 491. impossible("What weird effect is this? (%u)", sobj->otyp); 492. } 493. return(0); 494. } 495. 496. identify(otmp) /* also called by newmail() */ 497. register struct obj *otmp; 498. { 499. objects[otmp->otyp].oc_name_known = 1; 500. #ifdef KAA 501. otmp->known = 1; 502. if (otmp->olet != WEAPON_SYM) otmp->dknown = 1; 503. /* Now, the dknown field is special for weapons, indicating blessing. */ 504. #else 505. otmp->known = otmp->dknown = 1; 506. #endif 507. prinv(otmp); 508. return(1); 509. } 510. 511. litroom(on) 512. register boolean on; 513. { 514. register num,zx,zy; 515. 516. /* first produce the text (provided he is not blind) */ 517. if(Blind) goto do_it; 518. if(!on) { 519. if(u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR || 520. !levl[u.ux][u.uy].lit) { 521. pline("It seems even darker in here than before."); 522. return; 523. } else 524. pline("It suddenly becomes dark in here."); 525. } else { 526. if(u.uswallow){ 527. pline("%s's stomach is lit.", Monnam(u.ustuck)); 528. return; 529. } 530. if(!xdnstair){ 531. pline("Nothing Happens."); 532. return; 533. } 534. #ifdef QUEST 535. pline("The cave lights up around you, then fades."); 536. return; 537. #else 538. if(levl[u.ux][u.uy].typ == CORR) { 539. pline("The corridor lights up around you, then fades."); 540. return; 541. } else if(levl[u.ux][u.uy].lit) { 542. pline("The light here seems better now."); 543. return; 544. } else 545. pline("The room is lit."); 546. #endif 547. } 548. 549. do_it: 550. #ifdef QUEST 551. return; 552. #else 553. if(levl[u.ux][u.uy].lit == on) 554. return; 555. if(levl[u.ux][u.uy].typ == DOOR) { 556. if(IS_ROOM(levl[u.ux][u.uy+1].typ)) zy = u.uy+1; 557. else if(IS_ROOM(levl[u.ux][u.uy-1].typ)) zy = u.uy-1; 558. else zy = u.uy; 559. if(IS_ROOM(levl[u.ux+1][u.uy].typ)) zx = u.ux+1; 560. else if(IS_ROOM(levl[u.ux-1][u.uy].typ)) zx = u.ux-1; 561. else zx = u.ux; 562. } else { 563. zx = u.ux; 564. zy = u.uy; 565. } 566. for(seelx = u.ux; (num = levl[seelx-1][zy].typ) != CORR && num != 0; 567. seelx--); 568. for(seehx = u.ux; (num = levl[seehx+1][zy].typ) != CORR && num != 0; 569. seehx++); 570. for(seely = u.uy; (num = levl[zx][seely-1].typ) != CORR && num != 0; 571. seely--); 572. for(seehy = u.uy; (num = levl[zx][seehy+1].typ) != CORR && num != 0; 573. seehy++); 574. for(zy = seely; zy <= seehy; zy++) 575. for(zx = seelx; zx <= seehx; zx++) { 576. levl[zx][zy].lit = on; 577. if(!Blind && dist(zx,zy) > 2) 578. if(on) prl(zx,zy); else nosee(zx,zy); 579. } 580. if(!on) seehx = 0; 581. #endif 582. } 583. 584. /* Test whether we may genocide all monsters with symbol ch */ 585. monstersym(ch) /* arnold@ucsfcgl */ 586. register char ch; 587. { 588. register struct permonst *mp; 589. 590. /* 591. * can't genocide certain monsters 592. */ 593. if (index("12 &:", ch)) return FALSE; 594. 595. if (ch == pm_eel.mlet) return TRUE; 596. for (mp = mons; mp < &mons[CMNUM+2]; mp++) 597. if (mp->mlet == ch) return TRUE; 598. 599. return FALSE; 600. } 601. 602. do_genocide() 603. 604. { 605. extern char genocided[], fut_geno[]; 606. char buf[BUFSZ]; 607. register struct monst *mtmp, *mtmp2; 608. 609. if(Confusion != 0) *buf = u.usym; 610. else do { 611. pline("What monster do you want to genocide (Type the letter)? "); 612. getlin(buf); 613. } 614. 615. while(strlen(buf) != 1 || !monstersym(*buf)); 616. 617. if(!index(fut_geno, *buf)) charcat(fut_geno, *buf); 618. if(!index(genocided, *buf)) charcat(genocided, *buf); 619. else { 620. pline("Such monsters do not exist in this world."); 621. return; 622. } 623. for(mtmp = fmon; mtmp; mtmp = mtmp2){ 624. mtmp2 = mtmp->nmon; 625. if(mtmp->data->mlet == *buf) 626. mondead(mtmp); 627. } 628. pline("Wiped out all %c's.", Hallucination ? '@' : *buf); 629. /* Scare the hallucinating player */ 630. if(*buf == '@') { 631. if(u.usym != '@') pline("You feel dead inside."); 632. killer = "scroll of genocide"; 633. u.uhp = -1; 634. } 635. #ifdef KAA 636. else if (*buf==u.usym) rehumanize(); 637. #endif 638. } 639. 640. do_mapping() 641. { 642. register struct rm *lev; 643. register int num, zx, zy; 644. 645. for(zy = 0; zy < ROWNO; zy++) 646. for(zx = 0; zx < COLNO; zx++) { 647. 648. if((Confusion != 0) && rn2(7)) continue; 649. lev = &(levl[zx][zy]); 650. if((num = lev->typ) == 0) continue; 651. 652. if(num == SCORR) { 653. lev->typ = CORR; 654. #ifdef DGK 655. lev->scrsym = symbol.corr; 656. #else 657. lev->scrsym = CORR_SYM; 658. #endif 659. } else if(num == SDOOR) { 660. lev->typ = DOOR; 661. #ifdef DGK 662. lev->scrsym = symbol.door; 663. #else 664. lev->scrsym = '+'; 665. #endif 666. /* do sth in doors ? */ 667. } else if(lev->seen) continue; 668. #ifndef QUEST 669. if(num != ROOM) 670. #endif 671. { 672. lev->seen = lev->new = 1; 673. if(lev->scrsym == ' ' || !lev->scrsym) newsym(zx,zy); 674. else on_scr(zx,zy); 675. } 676. } 677. } 678. 679. destroy_arm() { 680. 681. if(uarm) { 682. pline("Your armor turns to dust and falls to the floor!"); 683. useup(uarm); 684. } else if(uarmh) { 685. pline("Your helmet turns to dust and is blown away!"); 686. useup(uarmh); 687. } else if(uarmg) { 688. pline("Your gloves vanish!"); 689. useup(uarmg); 690. selftouch("You"); 691. } else if(uarms) { 692. pline("Your shield crumbles away!"); 693. useup(uarms); 694. } else return(0); /* could not destroy anything */ 695. 696. return(1); 697. }