abstract
| - Below is the full text to read.c from the source code of NetHack 1.3d. To link to a particular line, write [[NetHack 1.3d/read.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code 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. }
|