abstract
| - Below is the full text to read.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/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 3.1 92/12/10 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include "hack.h" 6. 7. /* elven armor vibrates warningly when enchanted beyond a limit */ 8. #define is_elven_armor(optr) ((optr)->otyp == ELVEN_LEATHER_HELM\ 9. || (optr)->otyp == ELVEN_MITHRIL_COAT\ 10. || (optr)->otyp == ELVEN_CLOAK\ 11. || (optr)->otyp == ELVEN_SHIELD\ 12. || (optr)->otyp == ELVEN_BOOTS) 13. 14. #ifdef OVLB 15. 16. boolean known; 17. 18. static const char NEARDATA readable[] = 19. { ALL_CLASSES, SCROLL_CLASS, SPBOOK_CLASS, 0 }; 20. static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 }; 21. 22. static void FDECL(wand_explode, (struct obj *)); 23. static void NDECL(do_class_genocide); 24. static void FDECL(stripspe,(struct obj *)); 25. static void FDECL(p_glow1,(struct obj *)); 26. static void FDECL(p_glow2,(struct obj *,const char *)); 27. static void FDECL(forget,(BOOLEAN_P)); 28. 29. #endif /* OVLB */ 30. 31. #ifndef OVERLAY 32. STATIC_DCL void FDECL(set_lit, (int,int,genericptr_t)); 33. #endif 34. 35. #ifdef OVLB 36. 37. int 38. doread() 39. { 40. register struct obj *scroll; 41. register boolean confused; 42. 43. known = FALSE; 44. if(check_capacity(NULL)) return (0); 45. scroll = getobj(readable, "read"); 46. if(!scroll) return(0); 47. 48. /* outrumor has its own blindness check */ 49. if(scroll->otyp == FORTUNE_COOKIE) { 50. if(flags.verbose) 51. You("break up the cookie and throw away the pieces."); 52. outrumor(bcsign(scroll), TRUE); 53. useup(scroll); 54. return(1); 55. } else if (scroll->oclass != SCROLL_CLASS 56. && scroll->oclass != SPBOOK_CLASS) { 57. pline(silly_thing_to, "read"); 58. return(0); 59. } else if (Blind) { 60. const char *what = 0; 61. if (scroll->oclass == SPBOOK_CLASS) 62. what = "mystic runes"; 63. else if (!scroll->dknown) 64. what = "formula on the scroll"; 65. if (what) { 66. pline("Being blind, you cannot read the %s.", what); 67. return(0); 68. } 69. } 70. 71. confused = (Confusion != 0); 72. if(scroll->oclass == SPBOOK_CLASS) { 73. if(confused) { 74. You("cannot grasp the meaning of this tome."); 75. return(0); 76. } else 77. return(study_book(scroll)); 78. } 79. #ifndef NO_SIGNAL 80. scroll->in_use = TRUE; /* scroll, not spellbook, now being read */ 81. #endif 82. if(scroll->otyp != SCR_BLANK_PAPER) { 83. if(Blind) 84. pline("As you pronounce the formula on it, the scroll disappears."); 85. else 86. pline("As you read the scroll, it disappears."); 87. if(confused) { 88. if (Hallucination) 89. pline("Being so trippy, you screw up...."); 90. else 91. pline("Being confused, you mispronounce the magic words...."); 92. } 93. } 94. if(!seffects(scroll)) { 95. if(!objects[scroll->otyp].oc_name_known) { 96. if(known) { 97. makeknown(scroll->otyp); 98. more_experienced(0,10); 99. } else if(!objects[scroll->otyp].oc_uname) 100. docall(scroll); 101. } 102. if(scroll->otyp != SCR_BLANK_PAPER) 103. useup(scroll); 104. #ifndef NO_SIGNAL 105. else scroll->in_use = FALSE; 106. #endif 107. } 108. return(1); 109. } 110. 111. static void 112. stripspe(obj) 113. register struct obj *obj; 114. { 115. if (obj->blessed) pline(nothing_happens); 116. else { 117. if (obj->spe > 0) { 118. obj->spe = 0; 119. if (obj->otyp == OIL_LAMP || obj->otyp == BRASS_LANTERN) 120. obj->age = 0; 121. Your("%s vibrates briefly.",xname(obj)); 122. } else pline(nothing_happens); 123. } 124. } 125. 126. static void 127. p_glow1(otmp) 128. register struct obj *otmp; 129. { 130. Your("%s %s briefly.", xname(otmp), 131. Blind ? "vibrates" : "glows"); 132. } 133. 134. static void 135. p_glow2(otmp,color) 136. register struct obj *otmp; 137. register const char *color; 138. { 139. Your("%s %s%s for a moment.", 140. xname(otmp), 141. Blind ? "vibrates" : "glows ", 142. Blind ? (const char *)"" : Hallucination ? hcolor() : color); 143. } 144. 145. /* 146. * recharge an object; curse_bless is -1 if the recharging implement 147. * was cursed, +1 if blessed, 0 otherwise. 148. */ 149. void 150. recharge(obj, curse_bless) 151. struct obj *obj; 152. int curse_bless; 153. { 154. register int n; 155. boolean is_cursed, is_blessed; 156. 157. is_cursed = curse_bless < 0; 158. is_blessed = curse_bless > 0; 159. 160. if (obj->oclass == WAND_CLASS) { 161. if (obj->otyp == WAN_WISHING) { 162. if (obj->recharged) { /* recharged once already? */ 163. wand_explode(obj); 164. return; 165. } 166. if (is_cursed) stripspe(obj); 167. else if (is_blessed) { 168. if (obj->spe != 3) { 169. obj->spe = 3; 170. p_glow2(obj,blue); 171. } else { 172. wand_explode(obj); 173. return; 174. } 175. } else { 176. if (obj->spe < 3) { 177. obj->spe++; 178. p_glow2(obj,blue); 179. } else pline(nothing_happens); 180. } 181. obj->recharged = 1; /* another recharging disallowed */ 182. } else { 183. if (is_cursed) stripspe(obj); 184. else if (is_blessed) { 185. if (objects[obj->otyp].oc_dir == NODIR) { 186. n = rn1(5,11); 187. if (obj->spe < n) obj->spe = n; 188. else obj->spe++; 189. } else { 190. n = rn1(5,4); 191. if (obj->spe < n) obj->spe = n; 192. else obj->spe++; 193. } 194. p_glow2(obj,blue); 195. } else { 196. obj->spe++; 197. p_glow1(obj); 198. } 199. } 200. } else if (obj->oclass == RING_CLASS && 201. objects[obj->otyp].oc_charged) { 202. /* charging does not affect ring's curse/bless status */ 203. int s = is_blessed ? rnd(3) : is_cursed ? -rnd(2) : 1; 204. boolean is_on = (obj == uleft || obj == uright); 205. 206. /* destruction depends on current state, not adjustment */ 207. if (obj->spe > rn2(7) || obj->spe <= -5) { 208. Your("%s pulsates momentarily, then explodes!", 209. xname(obj)); 210. if (is_on) Ring_gone(obj); 211. s = rnd(3 * abs(obj->spe)); /* amount of damage */ 212. useup(obj); 213. losehp(s, "exploding ring", KILLED_BY_AN); 214. } else { 215. long mask = is_on ? (obj == uleft ? LEFT_RING : 216. RIGHT_RING) : 0L; 217. Your("%s spins %sclockwise for a moment.", 218. xname(obj), s < 0 ? "counter" : ""); 219. /* cause attributes and/or properties to be updated */ 220. if (is_on) Ring_off(obj); 221. obj->spe += s; /* update the ring while it's off */ 222. if (is_on) setworn(obj, mask), Ring_on(obj); 223. /* oartifact: if a touch-sensitive artifact ring is 224. ever created the above will need to be revised */ 225. } 226. } else { 227. switch(obj->otyp) { 228. case MAGIC_MARKER: 229. if (is_cursed) stripspe(obj); 230. else if (obj->recharged) { 231. if (obj->spe < 3) 232. Your("marker seems permanently dried out."); 233. else 234. pline(nothing_happens); 235. } else if (is_blessed) { 236. n = obj->spe; 237. if (n < 50) obj->spe = 50; 238. if (n >= 50 && n < 75) obj->spe = 75; 239. if (n >= 75) obj->spe += 10; 240. p_glow2(obj,blue); 241. obj->recharged = 1; 242. } else { 243. if (obj->spe < 50) obj->spe = 50; 244. else obj->spe++; 245. p_glow2(obj,White); 246. obj->recharged = 1; 247. } 248. break; 249. case OIL_LAMP: 250. case BRASS_LANTERN: 251. if (is_cursed) { 252. stripspe(obj); 253. if (obj->lamplit) { 254. if (!Blind) 255. pline("%s goes out!", The(xname(obj))); 256. obj->lamplit = 0; 257. check_lamps(); 258. } 259. } else if (is_blessed) { 260. obj->spe = 1; 261. obj->age = 1500; 262. p_glow2(obj,blue); 263. } else { 264. obj->spe = 1; 265. obj->age += 750; 266. if (obj->age > 1500) obj->age = 1500; 267. p_glow1(obj); 268. } 269. break; 270. case CRYSTAL_BALL: 271. if (is_cursed) stripspe(obj); 272. else if (is_blessed) { 273. obj->spe = 6; 274. p_glow2(obj,blue); 275. } else { 276. if (obj->spe < 5) { 277. obj->spe++; 278. p_glow1(obj); 279. } else pline(nothing_happens); 280. } 281. break; 282. case HORN_OF_PLENTY: 283. case BAG_OF_TRICKS: 284. if (is_cursed) stripspe(obj); 285. else if (is_blessed) { 286. if (obj->spe <= 10) 287. obj->spe += rn1(10, 6); 288. else obj->spe += rn1(5, 6); 289. p_glow2(obj,blue); 290. } else { 291. obj->spe += rnd(5); 292. p_glow1(obj); 293. } 294. break; 295. default: 296. You("have a feeling of loss."); 297. break; 298. } /* switch */ 299. } 300. } 301. 302. /* 303. * forget some things (e.g. after reading a scroll of amnesia). abs(howmuch) 304. * controls the level of forgetfulness; 0 == part of the map, 1 == all of 305. * of map, 2 == part of map + spells, 3 == all of map + spells. 306. */ 307. 308. static void 309. forget(howmuch) 310. boolean howmuch; 311. { 312. register int zx, zy; 313. register struct trap *trap; 314. 315. if (Punished) u.bc_felt = 0; /* forget felt ball&chain */ 316. 317. known = TRUE; 318. for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++) 319. if (howmuch & 1 || rn2(7)) { 320. /* Zonk all memory of this location. */ 321. levl[zx][zy].seen = levl[zx][zy].waslit = 0; 322. levl[zx][zy].glyph = cmap_to_glyph(S_stone); 323. } 324. 325. /* forget all traps (except the one the hero is in :-) */ 326. for (trap = ftrap; trap; trap = trap->ntrap) 327. if (trap->tx != u.ux || trap->ty != u.uy) trap->tseen = 0; 328. 329. /* 330. * Make sure that what was seen is restored correctly. To do this, 331. * we need to go blind for an instant --- turn off the display, 332. * then restart it. All this work is needed to correctly handle 333. * walls which are stone on one side and wall on the other. Turning 334. * off the seen bit above will make the wall revert to stone, but 335. * there are cases where we don't want this to happen. The easiest 336. * thing to do is to run it through the vision system again, which 337. * is always correct. 338. */ 339. docrt(); /* this correctly will reset vision */ 340. 341. if(howmuch & 2) losespells(); 342. } 343. 344. int 345. seffects(sobj) 346. register struct obj *sobj; 347. { 348. register int cval; 349. register boolean confused = (Confusion != 0); 350. register struct obj *otmp; 351. 352. exercise(A_WIS, TRUE); /* just for trying */ 353. switch(sobj->otyp) { 354. #ifdef MAIL 355. case SCR_MAIL: 356. known = TRUE; 357. if (sobj->spe) 358. pline("This seems to be junk mail addressed to the finder of the Eye of Larn."); 359. /* note to the puzzled: the game Larn actually sends you junk 360. * mail if you win! 361. */ 362. else readmail(sobj); 363. break; 364. #endif 365. case SCR_ENCHANT_ARMOR: 366. { 367. register schar s; 368. otmp = some_armor(); 369. if(!otmp) { 370. strange_feeling(sobj, 371. !Blind ? "Your skin glows then fades." : 372. "Your skin feels warm for a moment."); 373. exercise(A_CON, !sobj->cursed); 374. exercise(A_STR, !sobj->cursed); 375. return(1); 376. } 377. if(confused) { 378. otmp->oerodeproof = !(sobj->cursed); 379. if(Blind) { 380. otmp->rknown = FALSE; 381. Your("%s feels warm for a moment.", 382. xname(otmp)); 383. } else { 384. otmp->rknown = TRUE; 385. Your("%s is covered by a %s %s %s!", 386. xname(otmp), 387. sobj->cursed ? "mottled" : "shimmering", 388. Hallucination ? hcolor() : 389. sobj->cursed ? Black : golden, 390. sobj->cursed ? "glow" : 391. (is_shield(otmp) ? "layer" : "shield")); 392. } 393. if (otmp->oerodeproof && otmp->oeroded) { 394. otmp->oeroded = 0; 395. Your("%s %ss good as new!", 396. xname(otmp), Blind ? "feel" : "look"); 397. } 398. break; 399. } 400. if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3)) 401. && rn2(otmp->spe) && !sobj->cursed) { 402. Your("%s violently %s%s for a while, then evaporates.", 403. xname(otmp), 404. Blind ? "vibrates" : "glows ", 405. Blind ? nul : Hallucination ? hcolor() : silver); 406. if(is_cloak(otmp)) (void) Cloak_off(); 407. if(is_boots(otmp)) (void) Boots_off(); 408. if(is_helmet(otmp)) (void) Helmet_off(); 409. if(is_gloves(otmp)) (void) Gloves_off(); 410. if(is_shield(otmp)) (void) Shield_off(); 411. if(otmp == uarm) (void) Armor_gone(); 412. useup(otmp); 413. break; 414. } 415. s = sobj->cursed ? -1 : 416. otmp->spe >= 9 ? (rn2(otmp->spe) == 0) : 417. sobj->blessed ? rnd(3-otmp->spe/3) : 1; 418. if (s >= 0 && otmp->otyp >= GRAY_DRAGON_SCALES && 419. otmp->otyp <= YELLOW_DRAGON_SCALES) { 420. /* dragon scales get turned into dragon scale mail */ 421. Your("%s merges and hardens!", xname(otmp)); 422. setworn((struct obj *)0, W_ARM); 423. /* assumes same order */ 424. otmp->otyp = GRAY_DRAGON_SCALE_MAIL + 425. otmp->otyp - GRAY_DRAGON_SCALES; 426. otmp->cursed = 0; 427. if (sobj->blessed) { 428. otmp->spe++; 429. otmp->blessed = 1; 430. } 431. otmp->known = 1; 432. setworn(otmp, W_ARM); 433. break; 434. } 435. Your("%s %s%s%s for a %s.", 436. xname(otmp), 437. s == 0 ? "violently " : nul, 438. Blind ? "vibrates" : "glows ", 439. Blind ? nul : Hallucination ? hcolor() : 440. sobj->cursed ? Black : silver, 441. (s*s>1) ? "while" : "moment"); 442. otmp->cursed = sobj->cursed; 443. if (!otmp->blessed || sobj->cursed) 444. otmp->blessed = sobj->blessed; 445. if (s) { 446. otmp->spe += s; 447. adj_abon(otmp, s); 448. } 449. 450. /* an elven magic clue, cookie@keebler */ 451. if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3)) 452. && (is_elven_armor(otmp) || !rn2(7))) 453. Your("%s suddenly vibrates %s.", 454. xname(otmp), 455. Blind ? "again" : "unexpectedly"); 456. break; 457. } 458. case SCR_DESTROY_ARMOR: 459. { 460. otmp = some_armor(); 461. if(confused) { 462. if(!otmp) { 463. strange_feeling(sobj,"Your bones itch."); 464. exercise(A_STR, FALSE); 465. exercise(A_CON, FALSE); 466. return(1); 467. } 468. otmp->oerodeproof = sobj->cursed; 469. p_glow2(otmp,purple); 470. break; 471. } 472. if(!sobj->cursed || !otmp || !otmp->cursed) { 473. if(!destroy_arm(otmp)) { 474. strange_feeling(sobj,"Your skin itches."); 475. exercise(A_STR, FALSE); 476. exercise(A_CON, FALSE); 477. return(1); 478. } 479. } else { /* armor and scroll both cursed */ 480. Your("%s vibrates.", xname(otmp)); 481. if (otmp->spe >= -6) otmp->spe--; 482. make_stunned(HStun + rn1(10, 10), TRUE); 483. } 484. } 485. break; 486. case SCR_CONFUSE_MONSTER: 487. case SPE_CONFUSE_MONSTER: 488. if(u.usym != S_HUMAN || sobj->cursed) { 489. if(!HConfusion) You("feel confused."); 490. make_confused(HConfusion + rnd(100),FALSE); 491. } else if(confused) { 492. if(!sobj->blessed) { 493. Your("%s begin to %s%s.", 494. makeplural(body_part(HAND)), 495. Blind ? "tingle" : "glow ", 496. Blind ? nul : Hallucination ? hcolor() : purple); 497. make_confused(HConfusion + rnd(100),FALSE); 498. } else { 499. pline("A %s%s surrounds your %s.", 500. Blind ? nul : Hallucination ? hcolor() : red, 501. Blind ? "faint buzz" : " glow", 502. body_part(HEAD)); 503. make_confused(0L,TRUE); 504. } 505. } else { 506. if (!sobj->blessed) { 507. Your("%s%s %s%s.", 508. makeplural(body_part(HAND)), 509. Blind ? "" : " begin to glow", 510. Blind ? (const char *)"tingle" : Hallucination ? hcolor() : red, 511. u.umconf ? " even more" : ""); 512. u.umconf++; 513. } else { 514. if (Blind) 515. Your("%s tingle %s sharply.", 516. makeplural(body_part(HAND)), 517. u.umconf ? "even more" : "very"); 518. else 519. Your("%s glow a%s brilliant %s.", 520. makeplural(body_part(HAND)), 521. u.umconf ? "n even more" : "", 522. Hallucination ? hcolor() : red); 523. u.umconf += rn1(8, 2); 524. } 525. } 526. break; 527. case SCR_SCARE_MONSTER: 528. case SPE_CAUSE_FEAR: 529. { register int ct = 0; 530. register struct monst *mtmp; 531. 532. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 533. if(cansee(mtmp->mx,mtmp->my)) { 534. if(confused || sobj->cursed) { 535. mtmp->mflee = mtmp->mfrozen = mtmp->msleep = 0; 536. mtmp->mcanmove = 1; 537. } else 538. if (! resist(mtmp, sobj->oclass, 0, NOTELL)) 539. mtmp->mflee = 1; 540. if(!mtmp->mtame) ct++; /* pets don't laugh at you */ 541. } 542. if(!ct) 543. You("hear %s in the distance.", 544. (confused || sobj->cursed) ? "sad wailing" : 545. "maniacal laughter"); 546. else if(sobj->otyp == SCR_SCARE_MONSTER) 547. You("hear %s close by.", 548. (confused || sobj->cursed) ? "sad wailing" : 549. "maniacal laughter"); 550. break; 551. } 552. case SCR_BLANK_PAPER: 553. if (Blind) 554. You("don't remember there being any magic words on this scroll."); 555. else 556. pline("This scroll seems to be blank."); 557. known = TRUE; 558. break; 559. case SCR_REMOVE_CURSE: 560. case SPE_REMOVE_CURSE: 561. { register struct obj *obj; 562. if(confused) 563. if (Hallucination) 564. You("feel the power of the Force against you!"); 565. else 566. You("feel like you need some help."); 567. else 568. if (Hallucination) 569. You("feel in touch with the Universal Oneness."); 570. else 571. You("feel like someone is helping you."); 572. 573. if(sobj->cursed) pline("The scroll disintegrates."); 574. else { 575. for(obj = invent; obj ; obj = obj->nobj) 576. if(sobj->blessed || obj->owornmask || 577. (obj->otyp == LOADSTONE)) { 578. if(confused) blessorcurse(obj, 2); 579. else uncurse(obj); 580. } 581. } 582. if(Punished && !confused) unpunish(); 583. break; 584. } 585. case SCR_CREATE_MONSTER: 586. #if defined(WIZARD) || defined(EXPLORE_MODE) 587. if (wizard || discover) 588. known = TRUE; 589. #endif /* WIZARD || EXPLORE_MODE */ 590. case SPE_CREATE_MONSTER: 591. { register int cnt = 1; 592. 593. if(!rn2(73) && !sobj->blessed) cnt += rnd(4); 594. if(confused || sobj->cursed) cnt += 12; 595. while(cnt--) { 596. #if defined(WIZARD) || defined(EXPLORE_MODE) 597. if((!wizard && !discover) || !create_particular()) 598. #endif /* WIZARD || EXPLORE_MODE */ 599. (void) makemon (confused ? &mons[PM_ACID_BLOB] : 600. (struct permonst *) 0, u.ux, u.uy); 601. } 602. break; 603. } 604. /* break; /*NOTREACHED*/ 605. case SCR_ENCHANT_WEAPON: 606. if(uwep && (uwep->oclass == WEAPON_CLASS || 607. uwep->otyp == PICK_AXE || 608. uwep->otyp == UNICORN_HORN) && confused) { 609. /* oclass check added 10/25/86 GAN */ 610. uwep->oerodeproof = !(sobj->cursed); 611. if(Blind) { 612. uwep->rknown = FALSE; 613. Your("weapon feels warm for a moment."); 614. } else { 615. uwep->rknown = TRUE; 616. Your("%s covered by a %s %s %s!", 617. aobjnam(uwep, "are"), 618. sobj->cursed ? "mottled" : "shimmering", 619. Hallucination ? hcolor() : 620. sobj->cursed ? purple : golden, 621. sobj->cursed ? "glow" : "shield"); 622. } 623. if (uwep->oerodeproof && uwep->oeroded) { 624. uwep->oeroded = 0; 625. Your("%s good as new!", 626. aobjnam(uwep, Blind ? "feel" : "look")); 627. } 628. } else return !chwepon(sobj, 629. sobj->cursed ? -1 : 630. !uwep ? 1 : 631. uwep->spe >= 9 ? (rn2(uwep->spe) == 0) : 632. sobj->blessed ? rnd(3-uwep->spe/3) : 1); 633. break; 634. case SCR_TAMING: 635. case SPE_CHARM_MONSTER: 636. { register int i,j; 637. register int bd = confused ? 5 : 1; 638. register struct monst *mtmp; 639. 640. for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) 641. if(isok(u.ux+i, u.uy+j) && (mtmp = m_at(u.ux+i, u.uy+j))) { 642. if(sobj->cursed) { 643. if(!mtmp->mtame) mtmp->mpeaceful = 0; 644. } else { 645. if (mtmp->isshk) { 646. if (!mtmp->mpeaceful) { 647. pline("%s calms down.", Monnam(mtmp)); 648. mtmp->mpeaceful = 1; 649. } 650. } else if(!resist(mtmp, sobj->oclass, 0, NOTELL)) 651. (void) tamedog(mtmp, (struct obj *) 0); 652. } 653. } 654. break; 655. } 656. case SCR_GENOCIDE: 657. You("have found a scroll of genocide!"); 658. known = TRUE; 659. if (sobj->blessed) do_class_genocide(); 660. else do_genocide(!sobj->cursed | (2 * !!Confusion)); 661. break; 662. case SCR_LIGHT: 663. if(!Blind) known = TRUE; 664. litroom(!confused && !sobj->cursed, sobj); 665. break; 666. case SCR_TELEPORTATION: 667. if(confused || sobj->cursed) level_tele(); 668. else { 669. if (sobj->blessed && !Teleport_control) { 670. known = TRUE; 671. if (yn("Do you wish to teleport?")=='n') 672. break; 673. } 674. tele(); 675. if(Teleport_control || !couldsee(u.ux0, u.uy0) || 676. (distu(u.ux0, u.uy0) >= 16)) 677. known = TRUE; 678. } 679. break; 680. case SCR_GOLD_DETECTION: 681. if (confused || sobj->cursed) return(trap_detect(sobj)); 682. else return(gold_detect(sobj)); 683. case SCR_FOOD_DETECTION: 684. case SPE_DETECT_FOOD: 685. if (food_detect(sobj)) 686. return(1); /* nothing detected */ 687. break; 688. case SPE_IDENTIFY: 689. cval = rn2(5); 690. goto id; 691. case SCR_IDENTIFY: 692. /* known = TRUE; */ 693. if(confused) 694. You("identify this as an identify scroll."); 695. else 696. pline("This is an identify scroll."); 697. if (sobj->blessed || (!sobj->cursed && !rn2(5))) 698. cval = rn2(5); 699. /* Note: if rn2(5)==0, identify all items */ 700. else cval = 1; 701. useup(sobj); 702. makeknown(SCR_IDENTIFY); 703. id: 704. if(invent && !confused) { 705. int ret; 706. do { 707. ret = ggetobj("identify", identify, cval); 708. } while(cval && (cval -= ret)); 709. } 710. return(1); 711. case SCR_CHARGING: 712. if (confused) { 713. You("feel charged up!"); 714. if (u.uen < u.uenmax) 715. u.uen = u.uenmax; 716. else 717. u.uen = (u.uenmax += d(5,4)); 718. flags.botl = 1; 719. break; 720. } 721. known = TRUE; 722. pline("This is a charging scroll."); 723. otmp = getobj(all_count, "charge"); 724. if (!otmp) break; 725. recharge(otmp, sobj->cursed ? -1 : (sobj->blessed ? 1 : 0)); 726. break; 727. case SCR_MAGIC_MAPPING: 728. if (level.flags.nommap) { 729. Your("mind is filled with crazy lines!"); 730. if (Hallucination) 731. pline("Wow! Modern art."); 732. else 733. Your("head spins in bewilderment."); 734. make_confused(HConfusion + rnd(30), FALSE); 735. break; 736. } 737. known = TRUE; 738. case SPE_MAGIC_MAPPING: 739. if (level.flags.nommap) { 740. Your("head spins as something blocks the spell!"); 741. make_confused(HConfusion + rnd(30), FALSE); 742. break; 743. } 744. pline("A map coalesces in your mind!"); 745. cval = (sobj->cursed && !confused); 746. if(cval) HConfusion = 1; /* to screw up map */ 747. do_mapping(); 748. if(cval) { 749. HConfusion = 0; /* restore */ 750. pline("Unfortunately, you can't grasp the details."); 751. } 752. break; 753. case SCR_AMNESIA: 754. known = TRUE; 755. forget( ((!sobj->blessed) << 1) | (!confused || sobj->cursed) ); 756. if (Hallucination) /* Ommmmmm! */ 757. Your("mind releases itself from mundane concerns."); 758. else if (!strncmpi(plname, "Maud", 4)) 759. pline("As your mind turns inward on itself, you forget everything else."); 760. else if (rn2(2)) 761. pline("Who was that Maud person anyway?"); 762. else 763. pline("Thinking of Maud you forget everything else."); 764. exercise(A_WIS, FALSE); 765. break; 766. case SCR_FIRE: 767. /* 768. * Note: Modifications have been made as of 3.0 to allow for 769. * some damage under all potential cases. 770. */ 771. cval = bcsign(sobj); 772. useup(sobj); 773. makeknown(SCR_FIRE); 774. if(confused) { 775. if(Fire_resistance) { 776. shieldeff(u.ux, u.uy); 777. if(!Blind) 778. pline("Oh, look, what a pretty fire in your %s.", 779. makeplural(body_part(HAND))); 780. else You("feel a pleasant warmth in your %s.", 781. makeplural(body_part(HAND))); 782. } else { 783. pline("The scroll catches fire and you burn your %s.", 784. makeplural(body_part(HAND))); 785. losehp(1, "scroll of fire", KILLED_BY_AN); 786. } 787. return(1); 788. } 789. if (Underwater) 790. pline("The water around you vaporizes violently!"); 791. else 792. pline("The scroll erupts in a tower of flame!"); 793. explode(u.ux, u.uy, 11, (2*(rn1(3, 3) + 2 * cval) + 1)/3, 794. SCROLL_CLASS); 795. return(1); 796. case SCR_PUNISHMENT: 797. known = TRUE; 798. if(confused || sobj->blessed) { 799. You("feel guilty."); 800. break; 801. } 802. punish(sobj); 803. break; 804. default: 805. impossible("What weird effect is this? (%u)", sobj->otyp); 806. } 807. return(0); 808. } 809. 810. static void 811. wand_explode(obj) 812. register struct obj *obj; 813. { 814. Your("%s vibrates violently, and explodes!",xname(obj)); 815. nhbell(); 816. losehp(rn2(2*(u.uhpmax+1)/3),"exploding wand", KILLED_BY_AN); 817. useup(obj); 818. exercise(A_STR, FALSE); 819. } 820. 821. /* 822. * Low-level lit-field update routine. 823. */ 824. STATIC_PTR void 825. set_lit(x,y,val) 826. int x, y; 827. genericptr_t val; 828. { 829. levl[x][y].lit = (val == (genericptr_t)-1) ? 0 : 1; 830. return; 831. } 832. 833. void 834. litroom(on,obj) 835. register boolean on; 836. struct obj *obj; 837. { 838. /* first produce the text (provided you're not blind) */ 839. if(Blind) goto do_it; 840. if(!on) { 841. if(u.uswallow) { 842. pline("It seems even darker in here than before."); 843. return; 844. } 845. You("are surrounded by darkness!"); 846. } else { 847. if(u.uswallow){ 848. if (is_animal(u.ustuck->data)) 849. pline("%s stomach is lit.", 850. s_suffix(Monnam(u.ustuck))); 851. else 852. if (is_whirly(u.ustuck->data)) 853. pline("%s shines briefly.", 854. Monnam(u.ustuck)); 855. else 856. pline("%s glistens.", Monnam(u.ustuck)); 857. return; 858. } 859. pline("A lit field surrounds you!"); 860. } 861. 862. do_it: 863. /* No-op in water - can only see the adjacent squares and that's it! */ 864. if (Underwater || Is_waterlevel(&u.uz)) return; 865. /* 866. * If we are darkening the room and the hero is punished but not 867. * blind, then we have to pick up and replace the ball and chain so 868. * that we don't remember them if they are out of sight. 869. */ 870. if (Punished && !on && !Blind) 871. move_bc(1, 0, uball->ox, uball->oy, uchain->ox, uchain->oy); 872. 873. #ifdef REINCARNATION 874. if (Is_rogue_level(&u.uz)) { 875. /* Can't use do_clear_area because MAX_RADIUS is too small */ 876. /* rogue lighting must light the entire room */ 877. int rnum = levl[u.ux][u.uy].roomno - ROOMOFFSET; 878. int rx, ry; 879. if(rnum >= 0) { 880. for(rx = rooms[rnum].lx-1; rx <= rooms[rnum].hx+1; rx++) 881. for(ry = rooms[rnum].ly-1; ry <= rooms[rnum].hy+1; ry++) 882. set_lit(rx, ry, (genericptr_t)((on)? 1 : -1)); 883. rooms[rnum].rlit = on; 884. } 885. /* hallways remain dark on the rogue level */ 886. } else 887. #endif 888. do_clear_area(u.ux,u.uy, 889. (obj && obj->oclass==SCROLL_CLASS && obj->blessed) ? 9 : 5, 890. set_lit, (genericptr_t)((on)? 1 : -1)); 891. 892. /* 893. * If we are not blind, then force a redraw on all positions in sight 894. * by temporarily blinding the hero. The vision recalculation will 895. * correctly update all previously seen positions *and* correctly 896. * set the waslit bit [could be messed up from above]. 897. */ 898. if (!Blind) { 899. vision_recalc(2); 900. 901. /* replace ball&chain */ 902. if (Punished && !on) 903. move_bc(0, 0, uball->ox, uball->oy, uchain->ox, uchain->oy); 904. } 905. 906. vision_full_recalc = 1; /* delayed vision recalculation */ 907. } 908. 909. static void 910. do_class_genocide() 911. { 912. register int i, j, immunecnt, gonecnt, goodcnt, class; 913. char buf[BUFSZ]; 914. 915. for(j=0; ; j++) { 916. if (j >= 5) { 917. pline(thats_enough_tries); 918. return; 919. } 920. do { 921. getlin("What class of monsters do you wish to genocide? [type a letter]", 922. buf); 923. } while (buf[0]=='\033' || strlen(buf) != 1); 924. immunecnt = gonecnt = goodcnt = 0; 925. class = def_char_to_monclass(buf[0]); 926. for(i = 0; i < NUMMONS; i++) { 927. if(mons[i].mlet == class) { 928. if (!(mons[i].geno & G_GENO)) immunecnt++; 929. else if(mons[i].geno & G_GENOD) gonecnt++; 930. else goodcnt++; 931. } 932. } 933. if (!goodcnt && class != S_HUMAN) { 934. if (gonecnt) 935. pline("All such monsters are already nonexistent."); 936. else if (immunecnt) 937. You("aren't permitted to genocide such monsters."); 938. else 939. pline("That symbol does not represent any monster."); 940. continue; 941. } 942. for(i = 0; i < NUMMONS; i++) { 943. if(mons[i].mlet == class) { 944. register struct monst *mtmp, *mtmp2; 945. char *n = makeplural(mons[i].mname); 946. 947. if (&mons[i]==player_mon() || ((mons[i].geno & G_GENO) 948. && !(mons[i].geno & G_GENOD))) { 949. /* This check must be first since player monsters might 950. * have G_GENOD or !G_GENO. 951. */ 952. pline("Wiped out all %s.", n); 953. if (&mons[i] == player_mon()) { 954. u.uhp = -1; 955. killer_format = KILLED_BY_AN; 956. killer = "scroll of genocide"; 957. #ifdef POLYSELF 958. if (u.umonnum >= 0) 959. You("feel dead inside."); 960. else 961. #endif 962. done(GENOCIDED); 963. } 964. /* for simplicity (and fairness) let's avoid 965. * alignment changes here... 966. */ 967. #ifdef POLYSELF 968. if (i==u.umonnum) rehumanize(); 969. #endif 970. mons[i].geno |= G_GENOD; 971. for(mtmp = fmon; mtmp; mtmp = mtmp2) { 972. mtmp2 = mtmp->nmon; 973. if(mtmp->data == &mons[i]) 974. mondead(mtmp); 975. } 976. } else if (mons[i].geno & G_GENOD) 977. pline("All %s are already nonexistent.", n); 978. else 979. You("aren't permitted to genocide %s%s.", 980. i == PM_WIZARD_OF_YENDOR ? "the " : "", 981. type_is_pname(&mons[i]) ? mons[i].mname : (const char *)n); 982. } 983. } 984. return; 985. } 986. } 987. 988. #define REALLY 1 989. #define PLAYER 2 990. void 991. do_genocide(how) 992. int how; 993. /* 0 = no genocide; create monsters (cursed scroll) */ 994. /* 1 = normal genocide */ 995. /* 3 = forced genocide of player */ 996. { 997. char buf[BUFSZ]; 998. register int i, j, killplayer = 0; 999. register struct permonst *ptr; 1000. register struct monst *mtmp, *mtmp2; 1001. 1002. if (how & PLAYER) { 1003. ptr = player_mon(); 1004. Strcpy(buf, ptr->mname); 1005. killplayer++; 1006. } else { 1007. for(j = 0; ; j++) { 1008. if(j >= 5) { 1009. pline(thats_enough_tries); 1010. return; 1011. } 1012. getlin("What monster do you want to genocide? [type the name]", 1013. buf); 1014. 1015. i = name_to_mon(buf); 1016. if(i == -1 || (mons[i].geno & G_GENOD)) { 1017. pline("Such creatures do not exist in this world."); 1018. continue; 1019. } 1020. ptr = &mons[i]; 1021. if (ptr == player_mon()) { 1022. killplayer++; 1023. goto deadmeat; 1024. } 1025. if (is_human(ptr)) adjalign(-sgn(u.ualign.type)); 1026. if (is_demon(ptr)) adjalign(sgn(u.ualign.type)); 1027. 1028. if(!(ptr->geno & G_GENO)) { 1029. if(flags.soundok) { 1030. if(flags.verbose) 1031. pline("A thunderous voice booms though the caverns:"); 1032. pline("\"No, mortal! That will not be done.\""); 1033. } 1034. continue; 1035. } 1036. break; 1037. } 1038. } 1039. deadmeat: 1040. if (Hallucination) { 1041. #ifdef POLYSELF 1042. if (u.umonnum != -1) 1043. Strcpy(buf,uasmon->mname); 1044. else 1045. #endif 1046. { 1047. Strcpy(buf, pl_character); 1048. buf[0] += 'a' - 'A'; 1049. } 1050. } else Strcpy(buf,ptr->mname); /* make sure we have standard singular */ 1051. if (how & REALLY) { 1052. pline("Wiped out all %s.", makeplural(buf)); 1053. if(killplayer) { 1054. u.uhp = -1; 1055. killer_format = KILLED_BY_AN; 1056. killer = "genocide spell"; 1057. #ifdef POLYSELF 1058. /* Polymorphed characters will die as soon as they're rehumanized. */ 1059. if(u.umonnum >= 0) You("feel dead inside."); 1060. else 1061. #endif 1062. done(GENOCIDED); 1063. return; 1064. } 1065. #ifdef POLYSELF 1066. else if (ptr == uasmon) rehumanize(); 1067. #endif 1068. ptr->geno |= G_GENOD; 1069. for(mtmp = fmon; mtmp; mtmp = mtmp2) { 1070. mtmp2 = mtmp->nmon; 1071. if(mtmp->data == ptr) 1072. mondead(mtmp); 1073. } 1074. } else if (!(ptr->geno & G_EXTINCT)) { 1075. pline("Sent in some %s.", makeplural(buf)); 1076. j = rn1(3, 4); 1077. for(i=1; i<=j; i++) { 1078. struct monst *mmon = makemon(ptr, u.ux, u.uy); 1079. struct obj *otmp; 1080. 1081. while ((otmp = mmon->minvent) != 0) { 1082. mmon->minvent = otmp->nobj; 1083. dealloc_obj(otmp); 1084. } 1085. } 1086. } 1087. } 1088. 1089. #endif /* OVLB */ 1090. #ifdef OVLB 1091. 1092. void 1093. punish(sobj) 1094. register struct obj *sobj; 1095. { 1096. You("are being punished for your misbehavior!"); 1097. if(Punished){ 1098. Your("iron ball gets heavier."); 1099. uball->owt += 160 * (1 + sobj->cursed); 1100. return; 1101. } 1102. setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN); 1103. setworn(mkobj(BALL_CLASS, TRUE), W_BALL); 1104. uball->spe = 1; /* special ball (see save) */ 1105. 1106. /* 1107. * Place ball & chain if not swallowed. If swallowed, the ball & 1108. * chain variables will be set at the next call to placebc(). 1109. */ 1110. if (!u.uswallow) { 1111. placebc(); 1112. if (Blind) set_bc(1); /* set up ball and chain variables */ 1113. newsym(u.ux,u.uy); /* see ball&chain if can't see self */ 1114. } 1115. } 1116. 1117. void 1118. unpunish() 1119. { /* remove the ball and chain */ 1120. freeobj(uchain); 1121. newsym(uchain->ox,uchain->oy); 1122. dealloc_obj(uchain); 1123. setworn((struct obj *)0, W_CHAIN); 1124. uball->spe = 0; 1125. setworn((struct obj *)0, W_BALL); 1126. } 1127. 1128. /* some creatures have special data structures that only make sense in their 1129. * normal locations -- if the player tries to create one elsewhere, or to revive 1130. * one, the disoriented creature becomes a zombie 1131. */ 1132. boolean 1133. cant_create(mtype) 1134. int *mtype; 1135. { 1136. 1137. if (*mtype==PM_GUARD || *mtype==PM_SHOPKEEPER 1138. || *mtype==PM_ALIGNED_PRIEST || *mtype==PM_ANGEL) { 1139. *mtype = PM_HUMAN_ZOMBIE; 1140. return TRUE; 1141. } 1142. return FALSE; 1143. } 1144. 1145. #if defined(WIZARD) || defined(EXPLORE_MODE) 1146. boolean 1147. create_particular() 1148. { 1149. char buf[BUFSZ]; 1150. int which, tries = 0; 1151. 1152. do { 1153. getlin("Create what kind of monster? [type the name]", buf); 1154. which = name_to_mon(buf); 1155. if (which < 0) pline("I've never heard of such monsters."); 1156. else break; 1157. } while (++tries < 5); 1158. if (tries == 5) pline(thats_enough_tries); 1159. else { 1160. if (!(mons[which].geno & G_GENOD) && cant_create(&which) && 1161. !Blind) { 1162. if (mons[which].geno & G_GENOD) 1163. pline("An image of the creature forms, wavers momentarily, then fades."); 1164. else 1165. pline("The disoriented creature's eyes slowly glaze over."); 1166. } 1167. (void) makemon(&mons[which], u.ux, u.uy); 1168. return TRUE; 1169. } 1170. return FALSE; 1171. } 1172. #endif /* WIZARD || EXPLORE_MODE */ 1173. 1174. #endif /* OVLB */ 1175. 1176. /*read.c*/
|