abstract
| - Below is the full text to read.c from the source code of NetHack 2.3e. To link to a particular line, write [[NetHack 2.3e/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 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. }
|