PropertyValue
rdfs:label
  • Source:NetHack 3.3.0/read.c
rdfs:comment
  • Below is the full text to read.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.0/read.c#line123]], for example. Warning! This is the source code from an old release. For the latest release, see Source code
dcterms:subject
dbkwik:nethack/property/wikiPageUsesTemplate
abstract
  • Below is the full text to read.c from the source code of NetHack 3.3.0. To link to a particular line, write [[NetHack 3.3.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.3 1999/11/29 */ 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. /* KMH -- Copied from pray.c; this really belongs in a header file */ 8. #define DEVOUT 14 9. #define STRIDENT 4 10. 11. #define Your_Own_Role(mndx) \ 12. ((mndx) == urole.malenum || \ 13. (urole.femalenum != NON_PM && (mndx) == urole.femalenum)) 14. #define Your_Own_Race(mndx) \ 15. ((mndx) == urace.malenum || \ 16. (urace.femalenum != NON_PM && (mndx) == urace.femalenum)) 17. 18. #ifdef OVLB 19. 20. /* elven armor vibrates warningly when enchanted beyond a limit */ 21. #define is_elven_armor(optr) ((optr)->otyp == ELVEN_LEATHER_HELM\ 22. || (optr)->otyp == ELVEN_MITHRIL_COAT\ 23. || (optr)->otyp == ELVEN_CLOAK\ 24. || (optr)->otyp == ELVEN_SHIELD\ 25. || (optr)->otyp == ELVEN_BOOTS) 26. 27. boolean known; 28. 29. static NEARDATA const char readable[] = 30. { ALL_CLASSES, SCROLL_CLASS, SPBOOK_CLASS, 0 }; 31. static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 }; 32. 33. static void FDECL(read_grave, (int)); 34. static void FDECL(wand_explode, (struct obj *)); 35. static void NDECL(do_class_genocide); 36. static void FDECL(stripspe,(struct obj *)); 37. static void FDECL(p_glow1,(struct obj *)); 38. static void FDECL(p_glow2,(struct obj *,const char *)); 39. static void FDECL(randomize,(int *, int)); 40. static void FDECL(forget_single_object, (int)); 41. static void FDECL(forget, (int)); 42. 43. STATIC_PTR void FDECL(set_lit, (int,int,genericptr_t)); 44. 45. int 46. doread() 47. { 48. register struct obj *scroll; 49. register boolean confused; 50. 51. 52. if (IS_GRAVE(levl[u.ux][u.uy].typ) && !Levitation) { 53. if(yn("Read the headstone?") == 'y') { 54. /* KMH, conduct */ 55. u.uconduct.literate++; 56. read_grave(u.ux + u.uy + urole.name.m[0]); 57. return 1; 58. } 59. } 60. 61. known = FALSE; 62. if(check_capacity((char *)0)) return (0); 63. scroll = getobj(readable, "read"); 64. if(!scroll) return(0); 65. 66. /* outrumor has its own blindness check */ 67. if(scroll->otyp == FORTUNE_COOKIE) { 68. if(flags.verbose) 69. You("break up the cookie and throw away the pieces."); 70. outrumor(bcsign(scroll), BY_COOKIE); 71. if (!Blind) u.uconduct.literate++; 72. useup(scroll); 73. return(1); 74. #ifdef TOURIST 75. } else if (scroll->otyp == T_SHIRT) { 76. char buf[BUFSZ]; 77. int erosion; 78. 79. if (Blind) { 80. You_cant("feel any Braille writing."); 81. return 0; 82. } 83. u.uconduct.literate++; 84. if(flags.verbose) 85. pline("It reads:"); 86. Sprintf(buf, "I explored the Dungeons of Doom, %s.", 87. Hallucination ? 88. (scroll == uarmu ? 89. /* (force these two to have identical length) */ 90. "and never did any laundry..." : 91. "and couldn't find my way out") : 92. "but all I got was this lousy T-shirt"); 93. erosion = greatest_erosion(scroll); 94. if (erosion) 95. wipeout_text(buf, 96. (int)(strlen(buf) * erosion / (2*MAX_ERODE)), 97. scroll->o_id ^ (unsigned)u.ubirthday); 98. pline("\"%s\"", buf); 99. return 1; 100. #endif /* TOURIST */ 101. } else if (scroll->oclass != SCROLL_CLASS 102. && scroll->oclass != SPBOOK_CLASS) { 103. pline(silly_thing_to, "read"); 104. return(0); 105. } else if (Blind) { 106. const char *what = 0; 107. if (scroll->oclass == SPBOOK_CLASS) 108. what = "mystic runes"; 109. else if (!scroll->dknown) 110. what = "formula on the scroll"; 111. if (what) { 112. pline("Being blind, you cannot read the %s.", what); 113. return(0); 114. } 115. } 116. 117. /* KMH, conduct */ 118. if (scroll->otyp != SPE_BOOK_OF_THE_DEAD) 119. u.uconduct.literate++; 120. 121. confused = (Confusion != 0); 122. #ifdef MAIL 123. if (scroll->otyp == SCR_MAIL) confused = FALSE; 124. #endif 125. if(scroll->oclass == SPBOOK_CLASS) { 126. if(confused) { 127. You("cannot grasp the meaning of this tome."); 128. return(0); 129. } else 130. return(study_book(scroll)); 131. } 132. scroll->in_use = TRUE; /* scroll, not spellbook, now being read */ 133. if(scroll->otyp != SCR_BLANK_PAPER) { 134. if(Blind) 135. pline("As you pronounce the formula on it, the scroll disappears."); 136. else 137. pline("As you read the scroll, it disappears."); 138. if(confused) { 139. if (Hallucination) 140. pline("Being so trippy, you screw up..."); 141. else 142. pline("Being confused, you mispronounce the magic words..."); 143. } 144. } 145. if(!seffects(scroll)) { 146. if(!objects[scroll->otyp].oc_name_known) { 147. if(known) { 148. makeknown(scroll->otyp); 149. more_experienced(0,10); 150. } else if(!objects[scroll->otyp].oc_uname) 151. docall(scroll); 152. } 153. if(scroll->otyp != SCR_BLANK_PAPER) 154. useup(scroll); 155. else scroll->in_use = FALSE; 156. } 157. return(1); 158. } 159. 160. static void 161. read_grave (inscription) 162. int inscription; 163. { 164. const char *epitaph; 165. 166. 167. #define EPITAPHS 25 168. switch (inscription % EPITAPHS) { 169. case 0: epitaph = "Note -- there are NO valuable items in this grave."; 170. break; 171. case 1: epitaph = "1994-1995. The Longest-Lived Hacker Ever."; 172. break; 173. case 2: epitaph = "The Grave of the Unknown Hacker."; 174. break; 175. case 3: 176. case 4: 177. case 5: epitaph = "R.I.P."; 178. break; 179. case 6: epitaph = "Rest In Pieces."; 180. break; 181. case 7: epitaph = "We weren't sure who this was, but we buried him here anyway."; 182. break; 183. case 8: epitaph = "Sparky -- he was a very good dog."; 184. break; 185. case 9: epitaph = "Beware of Electric Third Rail."; 186. break; 187. case 10: epitaph = "Made in Taiwan."; 188. break; 189. case 11: epitaph = "Og friend. Og good dude. Og died. Og now food."; 190. break; 191. case 12: epitaph = "Beetlejuice Beetlejuice Beetlejuice"; 192. break; 193. case 13: epitaph = "Look out below!"; 194. break; 195. case 14: epitaph = "Please don't dig me up. I'm perfectly happy down here. -- Resident"; 196. break; 197. case 15: epitaph = "Postman, please note forwarding address: Gehennom, Asmodeus's Fortress, fifth lemure on the left."; 198. break; 199. case 16: epitaph = "This old man, he played one, he played knick-knack on my thumb."; 200. break; 201. case 17: epitaph = "Mary had a little lamb, its fleece was white as snow. When Mary was in trouble here, the lamb was first to go."; 202. break; 203. case 18: epitaph = "Be careful, or this could happen to you! -- occupant"; 204. break; 205. case 19: epitaph = "Soon you'll join this fellow in hell! -- the Wizard of Yendor"; 206. break; 207. case 20: epitaph = "Caution! This grave contains toxic waste."; 208. break; 209. case 21: epitaph = "Go away!"; 210. break; 211. case 22: epitaph = "Saved by the bell."; 212. break; 213. case 23: 214. case 24: 215. default: 216. pline("It is blank..."); 217. return; 218. } 219. /* Headstones are engraved, so you can read them while blind */ 220. pline("It reads:"); 221. pline(epitaph); 222. } 223. 224. 225. static void 226. stripspe(obj) 227. register struct obj *obj; 228. { 229. if (obj->blessed) pline(nothing_happens); 230. else { 231. if (obj->spe > 0) { 232. obj->spe = 0; 233. if (obj->otyp == OIL_LAMP || obj->otyp == BRASS_LANTERN) 234. obj->age = 0; 235. Your("%s vibrates briefly.",xname(obj)); 236. } else pline(nothing_happens); 237. } 238. } 239. 240. static void 241. p_glow1(otmp) 242. register struct obj *otmp; 243. { 244. Your("%s %s briefly.", xname(otmp), 245. Blind ? "vibrates" : "glows"); 246. } 247. 248. static void 249. p_glow2(otmp,color) 250. register struct obj *otmp; 251. register const char *color; 252. { 253. Your("%s %s%s for a moment.", 254. xname(otmp), 255. Blind ? "vibrates" : "glows ", 256. Blind ? (const char *)"" : hcolor(color)); 257. } 258. 259. /* Is the object chargeable? For purposes of inventory display; it is */ 260. /* possible to be able to charge things for which this returns FALSE. */ 261. boolean 262. is_chargeable(obj) 263. struct obj *obj; 264. { 265. if (obj->oclass == WAND_CLASS) return TRUE; 266. /* known && !uname is possible after amnesia/mind flayer */ 267. if (obj->oclass == RING_CLASS) 268. return (boolean)(objects[obj->otyp].oc_charged && 269. (obj->known || objects[obj->otyp].oc_uname)); 270. if (is_weptool(obj)) /* specific check before general tools */ 271. return FALSE; 272. if (obj->oclass == TOOL_CLASS) 273. return (boolean)(objects[obj->otyp].oc_charged); 274. return FALSE; /* why are weapons/armor considered charged anyway? */ 275. } 276. 277. /* 278. * recharge an object; curse_bless is -1 if the recharging implement 279. * was cursed, +1 if blessed, 0 otherwise. 280. */ 281. void 282. recharge(obj, curse_bless) 283. struct obj *obj; 284. int curse_bless; 285. { 286. register int n; 287. boolean is_cursed, is_blessed; 288. 289. is_cursed = curse_bless < 0; 290. is_blessed = curse_bless > 0; 291. 292. if (obj->oclass == WAND_CLASS) { 293. /* undo any prior cancellation, even when is_cursed */ 294. if (obj->spe == -1) obj->spe = 0; 295. 296. /* 297. * Recharging might cause wands to explode. 298. * v = number of previous recharges 299. * v = percentage chance to explode on this attempt 300. * v = cumulative odds for exploding 301. * 0 : 0 0 302. * 1 : 0.29 0.29 303. * 2 : 2.33 2.62 304. * 3 : 7.87 10.28 305. * 4 : 18.66 27.02 306. * 5 : 36.44 53.62 307. * 6 : 62.97 82.83 308. * 7 : 100 100 309. */ 310. n = (int)obj->recharged; 311. if (n > 0 && (obj->otyp == WAN_WISHING || 312. (n * n * n > rn2(7*7*7)))) { /* recharge_limit */ 313. wand_explode(obj); 314. return; 315. } 316. /* didn't explode, so increment the recharge count */ 317. obj->recharged = (unsigned)(n + 1); 318. 319. /* now handle the actual recharging */ 320. if (is_cursed) { 321. stripspe(obj); 322. } else { 323. int lim = (obj->otyp == WAN_WISHING) ? 3 : 324. (objects[obj->otyp].oc_dir != NODIR) ? 8 : 15; 325. 326. n = (lim == 3) ? 3 : rn1(5, lim + 1 - 5); 327. if (!is_blessed) n = rnd(n); 328. 329. if (obj->spe < n) obj->spe = n; 330. else obj->spe++; 331. if (obj->otyp == WAN_WISHING && obj->spe > 3) { 332. wand_explode(obj); 333. return; 334. } 335. if (obj->spe >= lim) p_glow2(obj,blue); 336. else p_glow1(obj); 337. } 338. 339. } else if (obj->oclass == RING_CLASS && 340. objects[obj->otyp].oc_charged) { 341. /* charging does not affect ring's curse/bless status */ 342. int s = is_blessed ? rnd(3) : is_cursed ? -rnd(2) : 1; 343. boolean is_on = (obj == uleft || obj == uright); 344. 345. /* destruction depends on current state, not adjustment */ 346. if (obj->spe > rn2(7) || obj->spe <= -5) { 347. Your("%s pulsates momentarily, then explodes!", 348. xname(obj)); 349. if (is_on) Ring_gone(obj); 350. s = rnd(3 * abs(obj->spe)); /* amount of damage */ 351. useup(obj); 352. losehp(s, "exploding ring", KILLED_BY_AN); 353. } else { 354. long mask = is_on ? (obj == uleft ? LEFT_RING : 355. RIGHT_RING) : 0L; 356. Your("%s spins %sclockwise for a moment.", 357. xname(obj), s < 0 ? "counter" : ""); 358. /* cause attributes and/or properties to be updated */ 359. if (is_on) Ring_off(obj); 360. obj->spe += s; /* update the ring while it's off */ 361. if (is_on) setworn(obj, mask), Ring_on(obj); 362. /* oartifact: if a touch-sensitive artifact ring is 363. ever created the above will need to be revised */ 364. } 365. 366. } else if (obj->oclass == TOOL_CLASS) { 367. int rechrg = (int)obj->recharged; 368. 369. if (objects[obj->otyp].oc_charged) { 370. /* tools don't have a limit, but the counter used does */ 371. if (rechrg < 7) /* recharge_limit */ 372. obj->recharged++; 373. } 374. switch(obj->otyp) { 375. case BELL_OF_OPENING: 376. if (is_cursed) stripspe(obj); 377. else if (is_blessed) obj->spe += rnd(3); 378. else obj->spe += 1; 379. if (obj->spe > 5) obj->spe = 5; 380. break; 381. case MAGIC_MARKER: 382. case TINNING_KIT: 383. #ifdef TOURIST 384. case EXPENSIVE_CAMERA: 385. #endif 386. if (is_cursed) stripspe(obj); 387. else if (rechrg && obj->otyp == MAGIC_MARKER) { /* previously recharged */ 388. obj->recharged = 1; /* override increment done above */ 389. if (obj->spe < 3) 390. Your("marker seems permanently dried out."); 391. else 392. pline(nothing_happens); 393. } else if (is_blessed) { 394. n = rn1(10,16); /* 10..25 */ 395. if (obj->spe + n <= 50) 396. obj->spe = 50; 397. else if (obj->spe + n <= 75) 398. obj->spe = 75; 399. else { 400. int chrg = (int)obj->spe; 401. if ((chrg + n) > 127) 402. obj->spe = 127; 403. else 404. obj->spe += n; 405. } 406. p_glow2(obj,blue); 407. } else { 408. n = rn1(5,10); /* 5..15 */ 409. if (obj->spe + n <= 50) 410. obj->spe = 50; 411. else { 412. int chrg = (int)obj->spe; 413. if ((chrg + n) > 127) 414. obj->spe = 127; 415. else 416. obj->spe += n; 417. } 418. p_glow2(obj,White); 419. } 420. break; 421. case OIL_LAMP: 422. case BRASS_LANTERN: 423. if (is_cursed) { 424. stripspe(obj); 425. if (obj->lamplit) { 426. if (!Blind) 427. pline("%s goes out!", The(xname(obj))); 428. end_burn(obj, TRUE); 429. } 430. } else if (is_blessed) { 431. obj->spe = 1; 432. obj->age = 1500; 433. p_glow2(obj,blue); 434. } else { 435. obj->spe = 1; 436. obj->age += 750; 437. if (obj->age > 1500) obj->age = 1500; 438. p_glow1(obj); 439. } 440. break; 441. case CRYSTAL_BALL: 442. if (is_cursed) stripspe(obj); 443. else if (is_blessed) { 444. obj->spe = 6; 445. p_glow2(obj,blue); 446. } else { 447. if (obj->spe < 5) { 448. obj->spe++; 449. p_glow1(obj); 450. } else pline(nothing_happens); 451. } 452. break; 453. case HORN_OF_PLENTY: 454. case BAG_OF_TRICKS: 455. case CAN_OF_GREASE: 456. if (is_cursed) stripspe(obj); 457. else if (is_blessed) { 458. if (obj->spe <= 10) 459. obj->spe += rn1(10, 6); 460. else obj->spe += rn1(5, 6); 461. p_glow2(obj,blue); 462. } else { 463. obj->spe += rnd(5); 464. p_glow1(obj); 465. } 466. break; 467. case MAGIC_FLUTE: 468. case MAGIC_HARP: 469. case FROST_HORN: 470. case FIRE_HORN: 471. case DRUM_OF_EARTHQUAKE: 472. if (is_cursed) { 473. stripspe(obj); 474. } else if (is_blessed) { 475. obj->spe += d(2,4); 476. p_glow2(obj,blue); 477. } else { 478. obj->spe += rnd(4); 479. p_glow1(obj); 480. } 481. break; 482. default: 483. goto not_chargable; 484. /*NOTREACHED*/ 485. break; 486. } /* switch */ 487. 488. } else { 489. not_chargable: 490. You("have a feeling of loss."); 491. } 492. } 493. 494. 495. /* Forget known information about this object class. */ 496. static void 497. forget_single_object(obj_id) 498. int obj_id; 499. { 500. objects[obj_id].oc_name_known = 0; 501. objects[obj_id].oc_pre_discovered = 0; /* a discovery when relearned */ 502. if (objects[obj_id].oc_uname) { 503. /* this only works if oc_name_known is false */ 504. undiscover_object(obj_id); 505. 506. free((genericptr_t)objects[obj_id].oc_uname); 507. objects[obj_id].oc_uname = 0; 508. } 509. /* clear & free object names from matching inventory items too? */ 510. } 511. 512. 513. #if 0 /* here if anyone wants it.... */ 514. /* Forget everything known about a particular object class. */ 515. static void 516. forget_objclass(oclass) 517. int oclass; 518. { 519. int i; 520. 521. for (i=bases[oclass]; 522. i < NUM_OBJECTS && objects[i].oc_class==oclass; i++) 523. forget_single_object(i); 524. } 525. #endif 526. 527. 528. /* randomize the given list of numbers 0 <= i < count */ 529. static void 530. randomize(indices, count) 531. int *indices; 532. int count; 533. { 534. int i, iswap, temp; 535. 536. for (i = count - 1; i > 0; i--) { 537. if ((iswap = rn2(i + 1)) == i) continue; 538. temp = indices[i]; 539. indices[i] = indices[iswap]; 540. indices[iswap] = temp; 541. } 542. } 543. 544. 545. /* Forget % of known objects. */ 546. void 547. forget_objects(percent) 548. int percent; 549. { 550. int i, count; 551. int indices[NUM_OBJECTS]; 552. 553. if (percent == 0) return; 554. if (percent <= 0 || percent > 100) { 555. impossible("forget_objects: bad percent %d", percent); 556. return; 557. } 558. 559. for (count = 0, i = 1; i < NUM_OBJECTS; i++) 560. if (OBJ_DESCR(objects[i]) && 561. (objects[i].oc_name_known || objects[i].oc_uname)) 562. indices[count++] = i; 563. 564. randomize(indices, count); 565. 566. /* forget first % of randomized indices */ 567. count = ((count * percent) + 50) / 100; 568. for (i = 0; i < count; i++) 569. forget_single_object(indices[i]); 570. } 571. 572. 573. /* Forget some or all of map (depends on parameters). */ 574. void 575. forget_map(howmuch) 576. int howmuch; 577. { 578. register int zx, zy; 579. 580. known = TRUE; 581. for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++) 582. if (howmuch & ALL_MAP || rn2(7)) { 583. /* Zonk all memory of this location. */ 584. levl[zx][zy].seenv = 0; 585. levl[zx][zy].waslit = 0; 586. levl[zx][zy].glyph = cmap_to_glyph(S_stone); 587. } 588. } 589. 590. /* Forget all traps on the level. */ 591. void 592. forget_traps() 593. { 594. register struct trap *trap; 595. 596. /* forget all traps (except the one the hero is in :-) */ 597. for (trap = ftrap; trap; trap = trap->ntrap) 598. if ((trap->tx != u.ux || trap->ty != u.uy) && (trap->ttyp != HOLE)) 599. trap->tseen = 0; 600. } 601. 602. /* 603. * Forget given % of all levels that the hero has visited and not forgotten, 604. * except this one. 605. */ 606. void 607. forget_levels(percent) 608. int percent; 609. { 610. int i, count; 611. xchar maxl, this_lev; 612. int indices[MAXLINFO]; 613. 614. if (percent == 0) return; 615. 616. if (percent <= 0 || percent > 100) { 617. impossible("forget_levels: bad percent %d", percent); 618. return; 619. } 620. 621. this_lev = ledger_no(&u.uz); 622. maxl = maxledgerno(); 623. 624. /* count & save indices of non-forgotten visited levels */ 625. for (count = 0, i = 0; i <= maxl; i++) 626. if ((level_info[i].flags & VISITED) && 627. !(level_info[i].flags & FORGOTTEN) && i != this_lev) 628. indices[count++] = i; 629. 630. randomize(indices, count); 631. 632. /* forget first % of randomized indices */ 633. count = ((count * percent) + 50) / 100; 634. for (i = 0; i < count; i++) { 635. level_info[indices[i]].flags |= FORGOTTEN; 636. } 637. } 638. 639. /* 640. * Forget some things (e.g. after reading a scroll of amnesia). When called, 641. * the following are always forgotten: 642. * 643. * - felt ball & chain 644. * - traps 645. * - part (6 out of 7) of the map 646. * 647. * Other things are subject to flags: 648. * 649. * howmuch & ALL_MAP = forget whole map 650. * howmuch & ALL_SPELLS = forget all spells 651. */ 652. static void 653. forget(howmuch) 654. int howmuch; 655. { 656. 657. if (Punished) u.bc_felt = 0; /* forget felt ball&chain */ 658. 659. forget_map(howmuch); 660. forget_traps(); 661. 662. /* 1 in 3 chance of forgetting some levels */ 663. if (!rn2(3)) forget_levels(rn2(25)); 664. 665. /* 1 in 3 chance of forgeting some objects */ 666. if (!rn2(3)) forget_objects(rn2(25)); 667. 668. if (howmuch & ALL_SPELLS) losespells(); 669. /* 670. * Make sure that what was seen is restored correctly. To do this, 671. * we need to go blind for an instant --- turn off the display, 672. * then restart it. All this work is needed to correctly handle 673. * walls which are stone on one side and wall on the other. Turning 674. * off the seen bits above will make the wall revert to stone, but 675. * there are cases where we don't want this to happen. The easiest 676. * thing to do is to run it through the vision system again, which 677. * is always correct. 678. */ 679. docrt(); /* this correctly will reset vision */ 680. } 681. 682. int 683. seffects(sobj) 684. register struct obj *sobj; 685. { 686. register int cval; 687. register boolean confused = (Confusion != 0); 688. register struct obj *otmp; 689. 690. if (objects[sobj->otyp].oc_magic) 691. exercise(A_WIS, TRUE); /* just for trying */ 692. switch(sobj->otyp) { 693. #ifdef MAIL 694. case SCR_MAIL: 695. known = TRUE; 696. if (sobj->spe) 697. pline("This seems to be junk mail addressed to the finder of the Eye of Larn."); 698. /* note to the puzzled: the game Larn actually sends you junk 699. * mail if you win! 700. */ 701. else readmail(sobj); 702. break; 703. #endif 704. case SCR_ENCHANT_ARMOR: 705. { 706. register schar s; 707. boolean special_armor; 708. 709. otmp = some_armor(&youmonst); 710. if(!otmp) { 711. strange_feeling(sobj, 712. !Blind ? "Your skin glows then fades." : 713. "Your skin feels warm for a moment."); 714. exercise(A_CON, !sobj->cursed); 715. exercise(A_STR, !sobj->cursed); 716. return(1); 717. } 718. if(confused) { 719. otmp->oerodeproof = !(sobj->cursed); 720. if(Blind) { 721. otmp->rknown = FALSE; 722. Your("%s feels warm for a moment.", 723. xname(otmp)); 724. } else { 725. otmp->rknown = TRUE; 726. Your("%s is covered by a %s %s %s!", 727. xname(otmp), 728. sobj->cursed ? "mottled" : "shimmering", 729. hcolor(sobj->cursed ? Black : golden), 730. sobj->cursed ? "glow" : 731. (is_shield(otmp) ? "layer" : "shield")); 732. } 733. if (otmp->oerodeproof && (otmp->oeroded || otmp->oeroded2)) { 734. otmp->oeroded = otmp->oeroded2 = 0; 735. Your("%s %ss good as new!", 736. xname(otmp), Blind ? "feel" : "look"); 737. } 738. break; 739. } 740. special_armor = is_elven_armor(otmp) || 741. (Role_if(PM_WIZARD) && otmp->otyp == CORNUTHAUM); 742. /* KMH -- catch underflow */ 743. s = sobj->cursed ? -otmp->spe : otmp->spe; 744. if (s > (special_armor ? 5 : 3) && rn2(s)) { 745. Your("%s violently %s%s for a while, then evaporates.", 746. xname(otmp), 747. Blind ? "vibrates" : "glows ", 748. Blind ? nul : hcolor(sobj->cursed ? Black : silver)); 749. if(is_cloak(otmp)) (void) Cloak_off(); 750. if(is_boots(otmp)) (void) Boots_off(); 751. if(is_helmet(otmp)) (void) Helmet_off(); 752. if(is_gloves(otmp)) (void) Gloves_off(); 753. if(is_shield(otmp)) (void) Shield_off(); 754. if(otmp == uarm) (void) Armor_gone(); 755. useup(otmp); 756. break; 757. } 758. s = sobj->cursed ? -1 : 759. otmp->spe >= 9 ? (rn2(otmp->spe) == 0) : 760. sobj->blessed ? rnd(3-otmp->spe/3) : 1; 761. if (s >= 0 && otmp->otyp >= GRAY_DRAGON_SCALES && 762. otmp->otyp <= YELLOW_DRAGON_SCALES) { 763. /* dragon scales get turned into dragon scale mail */ 764. Your("%s merges and hardens!", xname(otmp)); 765. setworn((struct obj *)0, W_ARM); 766. /* assumes same order */ 767. otmp->otyp = GRAY_DRAGON_SCALE_MAIL + 768. otmp->otyp - GRAY_DRAGON_SCALES; 769. otmp->cursed = 0; 770. if (sobj->blessed) { 771. otmp->spe++; 772. otmp->blessed = 1; 773. } 774. otmp->known = 1; 775. setworn(otmp, W_ARM); 776. break; 777. } 778. Your("%s %s%s%s for a %s.", 779. xname(otmp), 780. s == 0 ? "violently " : nul, 781. Blind ? "vibrates" : "glows ", 782. Blind ? nul : hcolor(sobj->cursed ? Black : silver), 783. (s*s>1) ? "while" : "moment"); 784. otmp->cursed = sobj->cursed; 785. if (!otmp->blessed || sobj->cursed) 786. otmp->blessed = sobj->blessed; 787. if (s) { 788. otmp->spe += s; 789. adj_abon(otmp, s); 790. known = otmp->known; 791. } 792. 793. if ((otmp->spe > (special_armor ? 5 : 3)) && 794. (special_armor || !rn2(7))) 795. Your("%s suddenly vibrates %s.", 796. xname(otmp), 797. Blind ? "again" : "unexpectedly"); 798. break; 799. } 800. case SCR_DESTROY_ARMOR: 801. { 802. otmp = some_armor(&youmonst); 803. if(confused) { 804. if(!otmp) { 805. strange_feeling(sobj,"Your bones itch."); 806. exercise(A_STR, FALSE); 807. exercise(A_CON, FALSE); 808. return(1); 809. } 810. otmp->oerodeproof = sobj->cursed; 811. p_glow2(otmp,purple); 812. break; 813. } 814. if(!sobj->cursed || !otmp || !otmp->cursed) { 815. if(!destroy_arm(otmp)) { 816. strange_feeling(sobj,"Your skin itches."); 817. exercise(A_STR, FALSE); 818. exercise(A_CON, FALSE); 819. return(1); 820. } else 821. known = TRUE; 822. } else { /* armor and scroll both cursed */ 823. Your("%s vibrates.", xname(otmp)); 824. if (otmp->spe >= -6) otmp->spe--; 825. make_stunned(HStun + rn1(10, 10), TRUE); 826. } 827. } 828. break; 829. case SCR_CONFUSE_MONSTER: 830. case SPE_CONFUSE_MONSTER: 831. if(youmonst.data->mlet != S_HUMAN || sobj->cursed) { 832. if(!HConfusion) You_feel("confused."); 833. make_confused(HConfusion + rnd(100),FALSE); 834. } else if(confused) { 835. if(!sobj->blessed) { 836. Your("%s begin to %s%s.", 837. makeplural(body_part(HAND)), 838. Blind ? "tingle" : "glow ", 839. Blind ? nul : hcolor(purple)); 840. make_confused(HConfusion + rnd(100),FALSE); 841. } else { 842. pline("A %s%s surrounds your %s.", 843. Blind ? nul : hcolor(red), 844. Blind ? "faint buzz" : " glow", 845. body_part(HEAD)); 846. make_confused(0L,TRUE); 847. } 848. } else { 849. if (!sobj->blessed) { 850. Your("%s%s %s%s.", 851. makeplural(body_part(HAND)), 852. Blind ? "" : " begin to glow", 853. Blind ? (const char *)"tingle" : hcolor(red), 854. u.umconf ? " even more" : ""); 855. u.umconf++; 856. } else { 857. if (Blind) 858. Your("%s tingle %s sharply.", 859. makeplural(body_part(HAND)), 860. u.umconf ? "even more" : "very"); 861. else 862. Your("%s glow a%s brilliant %s.", 863. makeplural(body_part(HAND)), 864. u.umconf ? "n even more" : "", 865. hcolor(red)); 866. u.umconf += rn1(8, 2); 867. } 868. } 869. break; 870. case SCR_SCARE_MONSTER: 871. case SPE_CAUSE_FEAR: 872. { register int ct = 0; 873. register struct monst *mtmp; 874. 875. for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 876. if(cansee(mtmp->mx,mtmp->my)) { 877. if(confused || sobj->cursed) { 878. mtmp->mflee = mtmp->mfrozen = mtmp->msleeping = 0; 879. mtmp->mcanmove = 1; 880. } else 881. if (! resist(mtmp, sobj->oclass, 0, NOTELL)) 882. mtmp->mflee = 1; 883. if(!mtmp->mtame) ct++; /* pets don't laugh at you */ 884. } 885. if(!ct) 886. You_hear("%s in the distance.", 887. (confused || sobj->cursed) ? "sad wailing" : 888. "maniacal laughter"); 889. else if(sobj->otyp == SCR_SCARE_MONSTER) 890. You_hear("%s close by.", 891. (confused || sobj->cursed) ? "sad wailing" : 892. "maniacal laughter"); 893. break; 894. } 895. case SCR_BLANK_PAPER: 896. if (Blind) 897. You("don't remember there being any magic words on this scroll."); 898. else 899. pline("This scroll seems to be blank."); 900. known = TRUE; 901. break; 902. case SCR_REMOVE_CURSE: 903. case SPE_REMOVE_CURSE: 904. { register struct obj *obj; 905. if(confused) 906. if (Hallucination) 907. You_feel("the power of the Force against you!"); 908. else 909. You_feel("like you need some help."); 910. else 911. if (Hallucination) 912. You_feel("in touch with the Universal Oneness."); 913. else 914. You_feel("like someone is helping you."); 915. 916. if(sobj->cursed) pline_The("scroll disintegrates."); 917. else { 918. for(obj = invent; obj ; obj = obj->nobj) 919. if(sobj->blessed || obj->owornmask || 920. (obj->otyp == LOADSTONE)) { 921. if(confused) blessorcurse(obj, 2); 922. else uncurse(obj); 923. } 924. } 925. if(Punished && !confused) unpunish(); 926. break; 927. } 928. case SCR_CREATE_MONSTER: 929. case SPE_CREATE_MONSTER: 930. if (create_critters(1 + ((confused || sobj->cursed) ? 12 : 0) + 931. ((sobj->blessed || rn2(73)) ? 0 : rnd(4)), 932. confused ? &mons[PM_ACID_BLOB] : (struct permonst *)0)) 933. known = TRUE; 934. /* no need to flush monsters; we ask for identification only if the 935. * monsters are not visible 936. */ 937. break; 938. case SCR_ENCHANT_WEAPON: 939. if(uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep)) 940. && confused) { 941. /* oclass check added 10/25/86 GAN */ 942. uwep->oerodeproof = !(sobj->cursed); 943. if (Blind) { 944. uwep->rknown = FALSE; 945. Your("weapon feels warm for a moment."); 946. } else { 947. uwep->rknown = TRUE; 948. Your("%s covered by a %s %s %s!", 949. aobjnam(uwep, "are"), 950. sobj->cursed ? "mottled" : "shimmering", 951. hcolor(sobj->cursed ? purple : golden), 952. sobj->cursed ? "glow" : "shield"); 953. } 954. if (uwep->oerodeproof && (uwep->oeroded || uwep->oeroded2)) { 955. uwep->oeroded = uwep->oeroded2 = 0; 956. Your("%s good as new!", 957. aobjnam(uwep, Blind ? "feel" : "look")); 958. } 959. } else return !chwepon(sobj, 960. sobj->cursed ? -1 : 961. !uwep ? 1 : 962. uwep->spe >= 9 ? (rn2(uwep->spe) == 0) : 963. sobj->blessed ? rnd(3-uwep->spe/3) : 1); 964. break; 965. case SCR_TAMING: 966. case SPE_CHARM_MONSTER: 967. { register int i,j; 968. register int bd = confused ? 5 : 1; 969. register struct monst *mtmp; 970. 971. for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) 972. if(isok(u.ux+i, u.uy+j) && (mtmp = m_at(u.ux+i, u.uy+j))) { 973. if(sobj->cursed) { 974. setmangry(mtmp); 975. } else { 976. if (mtmp->isshk) 977. make_happy_shk(mtmp, FALSE); 978. else if (!resist(mtmp, sobj->oclass, 0, NOTELL)) 979. (void) tamedog(mtmp, (struct obj *) 0); 980. } 981. } 982. break; 983. } 984. case SCR_GENOCIDE: 985. You("have found a scroll of genocide!"); 986. known = TRUE; 987. if (sobj->blessed) do_class_genocide(); 988. else do_genocide(!sobj->cursed | (2 * !!Confusion)); 989. break; 990. case SCR_LIGHT: 991. if(!Blind) known = TRUE; 992. litroom(!confused && !sobj->cursed, sobj); 993. break; 994. case SCR_TELEPORTATION: 995. if(confused || sobj->cursed) level_tele(); 996. else { 997. if (sobj->blessed && !Teleport_control) { 998. known = TRUE; 999. if (yn("Do you wish to teleport?")=='n') 1000. break; 1001. } 1002. tele(); 1003. if(Teleport_control || !couldsee(u.ux0, u.uy0) || 1004. (distu(u.ux0, u.uy0) >= 16)) 1005. known = TRUE; 1006. } 1007. break; 1008. case SCR_GOLD_DETECTION: 1009. if (confused || sobj->cursed) return(trap_detect(sobj)); 1010. else return(gold_detect(sobj)); 1011. case SCR_FOOD_DETECTION: 1012. case SPE_DETECT_FOOD: 1013. if (food_detect(sobj)) 1014. return(1); /* nothing detected */ 1015. break; 1016. case SPE_IDENTIFY: 1017. cval = rn2(5); 1018. goto id; 1019. case SCR_IDENTIFY: 1020. /* known = TRUE; */ 1021. if(confused) 1022. You("identify this as an identify scroll."); 1023. else 1024. pline("This is an identify scroll."); 1025. if (sobj->blessed || (!sobj->cursed && !rn2(5))) { 1026. cval = rn2(5); 1027. /* Note: if rn2(5)==0, identify all items */ 1028. if (cval == 1 && sobj->blessed && Luck > 0) ++cval; 1029. } else cval = 1; 1030. useup(sobj); 1031. makeknown(SCR_IDENTIFY); 1032. id: 1033. if(invent && !confused) { 1034. identify_pack(cval); 1035. } 1036. return(1); 1037. case SCR_CHARGING: 1038. if (confused) { 1039. You_feel("charged up!"); 1040. if (u.uen < u.uenmax) 1041. u.uen = u.uenmax; 1042. else 1043. u.uen = (u.uenmax += d(5,4)); 1044. flags.botl = 1; 1045. break; 1046. } 1047. known = TRUE; 1048. pline("This is a charging scroll."); 1049. otmp = getobj(all_count, "charge"); 1050. if (!otmp) break; 1051. recharge(otmp, sobj->cursed ? -1 : (sobj->blessed ? 1 : 0)); 1052. break; 1053. case SCR_MAGIC_MAPPING: 1054. if (level.flags.nommap) { 1055. Your("mind is filled with crazy lines!"); 1056. if (Hallucination) 1057. pline("Wow! Modern art."); 1058. else 1059. Your("head spins in bewilderment."); 1060. make_confused(HConfusion + rnd(30), FALSE); 1061. break; 1062. } 1063. if (sobj->blessed) { 1064. register int x, y; 1065. 1066. for (x = 1; x < COLNO; x++) 1067. for (y = 0; y < ROWNO; y++) 1068. if (levl[x][y].typ == SDOOR) 1069. cvt_sdoor_to_door(&levl[x][y]); 1070. /* do_mapping() already reveals secret passages */ 1071. } 1072. known = TRUE; 1073. case SPE_MAGIC_MAPPING: 1074. if (level.flags.nommap) { 1075. Your("head spins as something blocks the spell!"); 1076. make_confused(HConfusion + rnd(30), FALSE); 1077. break; 1078. } 1079. pline("A map coalesces in your mind!"); 1080. cval = (sobj->cursed && !confused); 1081. if(cval) HConfusion = 1; /* to screw up map */ 1082. do_mapping(); 1083. if(cval) { 1084. HConfusion = 0; /* restore */ 1085. pline("Unfortunately, you can't grasp the details."); 1086. } 1087. break; 1088. case SCR_AMNESIA: 1089. known = TRUE; 1090. forget( (!sobj->blessed ? ALL_SPELLS : 0) | 1091. (!confused || sobj->cursed ? ALL_MAP : 0) ); 1092. if (Hallucination) /* Ommmmmm! */ 1093. Your("mind releases itself from mundane concerns."); 1094. else if (!strncmpi(plname, "Maud", 4)) 1095. pline("As your mind turns inward on itself, you forget everything else."); 1096. else if (rn2(2)) 1097. pline("Who was that Maud person anyway?"); 1098. else 1099. pline("Thinking of Maud you forget everything else."); 1100. exercise(A_WIS, FALSE); 1101. break; 1102. case SCR_FIRE: 1103. /* 1104. * Note: Modifications have been made as of 3.0 to allow for 1105. * some damage under all potential cases. 1106. */ 1107. cval = bcsign(sobj); 1108. useup(sobj); 1109. makeknown(SCR_FIRE); 1110. if(confused) { 1111. if(Fire_resistance) { 1112. shieldeff(u.ux, u.uy); 1113. if(!Blind) 1114. pline("Oh, look, what a pretty fire in your %s.", 1115. makeplural(body_part(HAND))); 1116. else You_feel("a pleasant warmth in your %s.", 1117. makeplural(body_part(HAND))); 1118. } else { 1119. pline_The("scroll catches fire and you burn your %s.", 1120. makeplural(body_part(HAND))); 1121. losehp(1, "scroll of fire", KILLED_BY_AN); 1122. } 1123. return(1); 1124. } 1125. if (Underwater) 1126. pline_The("water around you vaporizes violently!"); 1127. else { 1128. pline_The("scroll erupts in a tower of flame!"); 1129. burn_away_slime(); 1130. } 1131. explode(u.ux, u.uy, 11, (2*(rn1(3, 3) + 2 * cval) + 1)/3, 1132. SCROLL_CLASS); 1133. return(1); 1134. case SCR_EARTH: 1135. /* TODO: handle steeds */ 1136. if ( 1137. #ifdef REINCARNATION 1138. !Is_rogue_level(&u.uz) && 1139. #endif 1140. (!In_endgame(&u.uz) || Is_earthlevel(&u.uz))) { 1141. register int x, y; 1142. 1143. /* Identify the scroll */ 1144. pline_The("%s rumbles %s you!", ceiling(u.ux,u.uy), 1145. sobj->blessed ? "around" : "above"); 1146. known = 1; 1147. 1148. /* Loop through the surrounding squares */ 1149. if (!sobj->cursed) for (x = u.ux-1; x <= u.ux+1; x++) { 1150. for (y = u.uy-1; y <= u.uy+1; y++) { 1151. 1152. /* Is this a suitable spot? */ 1153. if (isok(x, y) && !closed_door(x, y) && 1154. !IS_ROCK(levl[x][y].typ) && 1155. !IS_AIR(levl[x][y].typ) && 1156. (x != u.ux || y != u.uy)) { 1157. register struct obj *otmp2; 1158. register struct monst *mtmp; 1159. 1160. /* Make the object(s) */ 1161. otmp2 = mksobj(confused ? ROCK : BOULDER, 1162. FALSE, FALSE); 1163. if (!otmp2) continue; /* Shouldn't happen */ 1164. otmp2->quan = confused ? rn1(5,2) : 1; 1165. otmp2->owt = weight(otmp2); 1166. 1167. /* Find the monster here (won't be player) */ 1168. mtmp = m_at(x, y); 1169. if (mtmp && !amorphous(mtmp->data) && 1170. !passes_walls(mtmp->data) && 1171. !noncorporeal(mtmp->data) && 1172. !unsolid(mtmp->data)) { 1173. struct obj *helmet = which_armor(mtmp, W_ARMH); 1174. int mdmg; 1175. 1176. if (cansee(mtmp->mx, mtmp->my)) { 1177. pline("%s is hit by %s!", Monnam(mtmp), 1178. doname(otmp2)); 1179. if (mtmp->minvis && !canspotmon(mtmp)) 1180. map_invisible(mtmp->mx, mtmp->my); 1181. } 1182. mdmg = dmgval(otmp2, mtmp) * otmp2->quan; 1183. if (helmet) { 1184. if(is_metallic(helmet)) { 1185. if (canspotmon(mtmp)) 1186. pline("Fortunately, %s is wearing a hard helmet.", mon_nam(mtmp)); 1187. else if (flags.soundok) 1188. You_hear("a clanging sound."); 1189. if (mdmg > 2) mdmg = 2; 1190. } else { 1191. if (canspotmon(mtmp)) 1192. pline("%s's %s does not protect %s.", 1193. Monnam(mtmp), xname(uarmh), 1194. him[pronoun_gender(mtmp)]); 1195. } 1196. } 1197. mtmp->mhp -= mdmg; 1198. if (mtmp->mhp <= 0) 1199. xkilled(mtmp, 1); 1200. } 1201. /* Drop the rock/boulder to the floor */ 1202. if (!flooreffects(otmp2, x, y, "fall")) { 1203. place_object(otmp2, x, y); 1204. stackobj(otmp2); 1205. newsym(x, y); /* map the rock */ 1206. } 1207. } 1208. } 1209. } 1210. /* Attack the player */ 1211. if (!sobj->blessed) { 1212. int dmg; 1213. struct obj *otmp2; 1214. 1215. /* Okay, _you_ write this without repeating the code */ 1216. otmp2 = mksobj(confused ? ROCK : BOULDER, 1217. FALSE, FALSE); 1218. if (!otmp2) break; 1219. otmp2->quan = confused ? rn1(5,2) : 1; 1220. otmp2->owt = weight(otmp2); 1221. if (!amorphous(youmonst.data) && 1222. !Passes_walls && 1223. !noncorporeal(youmonst.data) && 1224. !unsolid(youmonst.data)) { 1225. You("are hit by %s!", doname(otmp2)); 1226. dmg = dmgval(otmp2, &youmonst) * otmp2->quan; 1227. if (uarmh && !sobj->cursed) { 1228. if(is_metallic(uarmh)) { 1229. pline("Fortunately, you are wearing a hard helmet."); 1230. if (dmg > 2) dmg = 2; 1231. } else if (flags.verbose) { 1232. Your("%s does not protect you.", 1233. xname(uarmh)); 1234. } 1235. } 1236. } else 1237. dmg = 0; 1238. /* Must be before the losehp(), for bones files */ 1239. if (!flooreffects(otmp2, u.ux, u.uy, "fall")) { 1240. place_object(otmp2, u.ux, u.uy); 1241. stackobj(otmp2); 1242. newsym(u.ux, u.uy); 1243. } 1244. if (dmg) losehp(dmg, "scroll of earth", KILLED_BY_AN); 1245. } 1246. } 1247. break; 1248. case SCR_PUNISHMENT: 1249. known = TRUE; 1250. if(confused || sobj->blessed) { 1251. You_feel("guilty."); 1252. break; 1253. } 1254. punish(sobj); 1255. break; 1256. case SCR_STINKING_CLOUD: { 1257. coord cc; 1258. pline("Where ?"); 1259. cc.x = u.ux; 1260. cc.y = u.uy; 1261. if (getpos(&cc, TRUE, "the desired position") < 0) /* force valid */ 1262. return 0; /* abort */ 1263. if (!cansee(cc.x, cc.y) || distu(cc.x, cc.y) >= 32) 1264. return 0; 1265. known = TRUE; 1266. (void) create_gas_cloud(cc.x, cc.y, 3, 10); 1267. break; 1268. } 1269. default: 1270. impossible("What weird effect is this? (%u)", sobj->otyp); 1271. } 1272. return(0); 1273. } 1274. 1275. static void 1276. wand_explode(obj) 1277. register struct obj *obj; 1278. { 1279. obj->in_use = TRUE; /* in case losehp() is fatal */ 1280. Your("%s vibrates violently, and explodes!",xname(obj)); 1281. nhbell(); 1282. losehp(rnd(2*(u.uhpmax+1)/3), "exploding wand", KILLED_BY_AN); 1283. useup(obj); 1284. exercise(A_STR, FALSE); 1285. } 1286. 1287. /* 1288. * Low-level lit-field update routine. 1289. */ 1290. STATIC_PTR void 1291. set_lit(x,y,val) 1292. int x, y; 1293. genericptr_t val; 1294. { 1295. if (val) 1296. levl[x][y].lit = 1; 1297. else { 1298. levl[x][y].lit = 0; 1299. snuff_light_source(x, y); 1300. } 1301. } 1302. 1303. void 1304. litroom(on,obj) 1305. register boolean on; 1306. struct obj *obj; 1307. { 1308. char is_lit; /* value is irrelevant; we use its address 1309. as a `not null' flag for set_lit() */ 1310. 1311. /* first produce the text (provided you're not blind) */ 1312. if(!on) { 1313. register struct obj *otmp; 1314. 1315. if (!Blind) { 1316. if(u.uswallow) { 1317. pline("It seems even darker in here than before."); 1318. return; 1319. } 1320. You("are surrounded by darkness!"); 1321. } 1322. 1323. /* the magic douses lamps, et al, too */ 1324. for(otmp = invent; otmp; otmp = otmp->nobj) 1325. if (otmp->lamplit) 1326. (void) snuff_lit(otmp); 1327. if (Blind) goto do_it; 1328. } else { 1329. if (Blind) goto do_it; 1330. if(u.uswallow){ 1331. if (is_animal(u.ustuck->data)) 1332. pline("%s stomach is lit.", 1333. s_suffix(Monnam(u.ustuck))); 1334. else 1335. if (is_whirly(u.ustuck->data)) 1336. pline("%s shines briefly.", 1337. Monnam(u.ustuck)); 1338. else 1339. pline("%s glistens.", Monnam(u.ustuck)); 1340. return; 1341. } 1342. pline("A lit field surrounds you!"); 1343. } 1344. 1345. do_it: 1346. /* No-op in water - can only see the adjacent squares and that's it! */ 1347. if (Underwater || Is_waterlevel(&u.uz)) return; 1348. /* 1349. * If we are darkening the room and the hero is punished but not 1350. * blind, then we have to pick up and replace the ball and chain so 1351. * that we don't remember them if they are out of sight. 1352. */ 1353. if (Punished && !on && !Blind) 1354. move_bc(1, 0, uball->ox, uball->oy, uchain->ox, uchain->oy); 1355. 1356. #ifdef REINCARNATION 1357. if (Is_rogue_level(&u.uz)) { 1358. /* Can't use do_clear_area because MAX_RADIUS is too small */ 1359. /* rogue lighting must light the entire room */ 1360. int rnum = levl[u.ux][u.uy].roomno - ROOMOFFSET; 1361. int rx, ry; 1362. if(rnum >= 0) { 1363. for(rx = rooms[rnum].lx-1; rx <= rooms[rnum].hx+1; rx++) 1364. for(ry = rooms[rnum].ly-1; ry <= rooms[rnum].hy+1; ry++) 1365. set_lit(rx, ry, 1366. (genericptr_t)(on ? &is_lit : (char *)0)); 1367. rooms[rnum].rlit = on; 1368. } 1369. /* hallways remain dark on the rogue level */ 1370. } else 1371. #endif 1372. do_clear_area(u.ux,u.uy, 1373. (obj && obj->oclass==SCROLL_CLASS && obj->blessed) ? 9 : 5, 1374. set_lit, (genericptr_t)(on ? &is_lit : (char *)0)); 1375. 1376. /* 1377. * If we are not blind, then force a redraw on all positions in sight 1378. * by temporarily blinding the hero. The vision recalculation will 1379. * correctly update all previously seen positions *and* correctly 1380. * set the waslit bit [could be messed up from above]. 1381. */ 1382. if (!Blind) { 1383. vision_recalc(2); 1384. 1385. /* replace ball&chain */ 1386. if (Punished && !on) 1387. move_bc(0, 0, uball->ox, uball->oy, uchain->ox, uchain->oy); 1388. } 1389. 1390. vision_full_recalc = 1; /* delayed vision recalculation */ 1391. } 1392. 1393. static void 1394. do_class_genocide() 1395. { 1396. register int i, j, immunecnt, gonecnt, goodcnt, class; 1397. char buf[BUFSZ]; 1398. boolean gameover = FALSE; /* true iff killed self */ 1399. 1400. for(j=0; ; j++) { 1401. if (j >= 5) { 1402. pline(thats_enough_tries); 1403. return; 1404. } 1405. do { 1406. getlin("What class of monsters do you wish to genocide?", 1407. buf); 1408. (void)mungspaces(buf); 1409. } while (buf[0]=='\033' || !buf[0]); 1410. if (strlen(buf) == 1) { 1411. if (buf[0] == ILLOBJ_SYM) 1412. buf[0] = def_monsyms[S_MIMIC]; 1413. class = def_char_to_monclass(buf[0]); 1414. } else { 1415. char buf2[BUFSZ]; 1416. 1417. class = 0; 1418. Strcpy(buf2, makesingular(buf)); 1419. Strcpy(buf, buf2); 1420. } 1421. immunecnt = gonecnt = goodcnt = 0; 1422. for (i = LOW_PM; i < NUMMONS; i++) { 1423. if (class == 0 && 1424. strstri(monexplain[(int)mons[i].mlet], buf) != 0) 1425. class = mons[i].mlet; 1426. if (mons[i].mlet == class) { 1427. if (!(mons[i].geno & G_GENO)) immunecnt++; 1428. else if(mvitals[i].mvflags & G_GENOD) gonecnt++; 1429. else goodcnt++; 1430. } 1431. } 1432. /* 1433. * TODO[?]: If user's input doesn't match any class 1434. * description, check individual species names. 1435. */ 1436. if (!goodcnt && class != mons[urole.malenum].mlet && 1437. class != mons[urace.malenum].mlet) { 1438. if (gonecnt) 1439. pline("All such monsters are already nonexistent."); 1440. else if (immunecnt || 1441. (buf[0] == DEF_INVISIBLE && buf[1] == '\0')) 1442. You("aren't permitted to genocide such monsters."); 1443. else 1444. #ifdef WIZARD /* to aid in topology testing; remove pesky monsters */ 1445. if (wizard && buf[0] == '*') { 1446. register struct monst *mtmp, *mtmp2; 1447. 1448. gonecnt = 0; 1449. for (mtmp = fmon; mtmp; mtmp = mtmp2) { 1450. mtmp2 = mtmp->nmon; 1451. mongone(mtmp); 1452. gonecnt++; 1453. } 1454. pline("Eliminated %d monster%s.", gonecnt, plur(gonecnt)); 1455. return; 1456. } else 1457. #endif 1458. pline("That symbol does not represent any monster."); 1459. continue; 1460. } 1461. 1462. for (i = LOW_PM; i < NUMMONS; i++) { 1463. if(mons[i].mlet == class) { 1464. char nam[BUFSZ]; 1465. 1466. Strcpy(nam, makeplural(mons[i].mname)); 1467. if (Your_Own_Role(i) || Your_Own_Race(i) || 1468. ((mons[i].geno & G_GENO) 1469. && !(mvitals[i].mvflags & G_GENOD))) { 1470. /* This check must be first since player monsters might 1471. * have G_GENOD or !G_GENO. 1472. */ 1473. mvitals[i].mvflags |= (G_GENOD|G_NOCORPSE); 1474. reset_rndmonst(i); 1475. kill_genocided_monsters(); 1476. update_inventory(); /* eggs & tins */ 1477. pline("Wiped out all %s.", nam); 1478. if (Upolyd && i == u.umonnum && !Unchanging) rehumanize(); 1479. /* Self-genocide if it matches either your race or role */ 1480. /* Assumption: male and female forms share the same letter */ 1481. if (i == urole.malenum || i == urace.malenum) { 1482. u.uhp = -1; 1483. killer_format = KILLED_BY_AN; 1484. killer = "scroll of genocide"; 1485. if (Upolyd) 1486. You_feel("dead inside."); 1487. else 1488. gameover = TRUE; 1489. } 1490. } else if (mvitals[i].mvflags & G_GENOD) { 1491. if (!gameover) 1492. pline("All %s are already nonexistent.", nam); 1493. } else if (!gameover) { 1494. /* suppress feedback about quest beings except 1495. for those applicable to our own role */ 1496. if ((mons[i].msound != MS_LEADER || 1497. quest_info(MS_LEADER) == i) 1498. && (mons[i].msound != MS_NEMESIS || 1499. quest_info(MS_NEMESIS) == i) 1500. && (mons[i].msound != MS_GUARDIAN || 1501. quest_info(MS_GUARDIAN) == i) 1502. /* non-leader/nemesis/guardian role-specific monster */ 1503. && (i != PM_NINJA || /* nuisance */ 1504. Role_if(PM_SAMURAI))) { 1505. boolean named, uniq; 1506. 1507. named = type_is_pname(&mons[i]) ? TRUE : FALSE; 1508. uniq = (mons[i].geno & G_UNIQ) ? TRUE : FALSE; 1509. /* one special case */ 1510. if (i == PM_HIGH_PRIEST) uniq = FALSE; 1511. 1512. You("aren't permitted to genocide %s%s.", 1513. (uniq && !named) ? "the " : "", 1514. (uniq || named) ? mons[i].mname : nam); 1515. } 1516. } 1517. } 1518. } 1519. if (gameover) done(GENOCIDED); 1520. return; 1521. } 1522. } 1523. 1524. #define REALLY 1 1525. #define PLAYER 2 1526. void 1527. do_genocide(how) 1528. int how; 1529. /* 0 = no genocide; create monsters (cursed scroll) */ 1530. /* 1 = normal genocide */ 1531. /* 3 = forced genocide of player */ 1532. { 1533. char buf[BUFSZ]; 1534. register int i, killplayer = 0; 1535. register int mndx; 1536. register struct permonst *ptr; 1537. const char *which; 1538. 1539. if (how & PLAYER) { 1540. mndx = u.umonster; /* non-polymorphed mon num */ 1541. ptr = &mons[mndx]; 1542. Strcpy(buf, ptr->mname); 1543. killplayer++; 1544. } else { 1545. for(i = 0; ; i++) { 1546. if(i >= 5) { 1547. pline(thats_enough_tries); 1548. return; 1549. } 1550. getlin("What monster do you want to genocide? [type the name]", 1551. buf); 1552. 1553. mndx = name_to_mon(buf); 1554. if (mndx == NON_PM || (mvitals[mndx].mvflags & G_GENOD)) { 1555. pline("Such creatures %s exist in this world.", 1556. (mndx == NON_PM) ? "do not" : "no longer"); 1557. continue; 1558. } 1559. ptr = &mons[mndx]; 1560. if (Your_Own_Role(mndx) || Your_Own_Race(mndx)) { 1561. killplayer++; 1562. break; 1563. } 1564. if (is_human(ptr)) adjalign(-sgn(u.ualign.type)); 1565. if (is_demon(ptr)) adjalign(sgn(u.ualign.type)); 1566. 1567. if(!(ptr->geno & G_GENO)) { 1568. if(flags.soundok) { 1569. /* fixme: unconditional "caverns" will be silly in some circumstances */ 1570. if(flags.verbose) 1571. pline("A thunderous voice booms through the caverns:"); 1572. verbalize("No, mortal! That will not be done."); 1573. } 1574. continue; 1575. } 1576. /* KMH -- Unchanging prevents rehumanization */ 1577. if (Unchanging && ptr == youmonst.data) 1578. killplayer++; 1579. break; 1580. } 1581. } 1582. 1583. which = "all "; 1584. if (Hallucination) { 1585. if (Upolyd) 1586. Strcpy(buf,youmonst.data->mname); 1587. else { 1588. Strcpy(buf, (flags.female && urole.name.f) ? 1589. urole.name.f : urole.name.m); 1590. buf[0] = lowc(buf[0]); 1591. } 1592. } else { 1593. Strcpy(buf, ptr->mname); /* make sure we have standard singular */ 1594. if ((ptr->geno & G_UNIQ) && ptr != &mons[PM_HIGH_PRIEST]) 1595. which = !type_is_pname(ptr) ? "the " : ""; 1596. } 1597. if (how & REALLY) { 1598. /* setting no-corpse affects wishing and random tin generation */ 1599. mvitals[mndx].mvflags |= (G_GENOD | G_NOCORPSE); 1600. pline("Wiped out %s%s.", which, 1601. (*which != 'a') ? buf : makeplural(buf)); 1602. 1603. if (killplayer) { 1604. /* might need to wipe out dual role */ 1605. if (urole.femalenum != NON_PM && mndx == urole.malenum) 1606. mvitals[urole.femalenum].mvflags |= (G_GENOD | G_NOCORPSE); 1607. if (urole.femalenum != NON_PM && mndx == urole.femalenum) 1608. mvitals[urole.malenum].mvflags |= (G_GENOD | G_NOCORPSE); 1609. if (urace.femalenum != NON_PM && mndx == urace.malenum) 1610. mvitals[urace.femalenum].mvflags |= (G_GENOD | G_NOCORPSE); 1611. if (urace.femalenum != NON_PM && mndx == urace.femalenum) 1612. mvitals[urace.malenum].mvflags |= (G_GENOD | G_NOCORPSE); 1613. 1614. u.uhp = -1; 1615. killer_format = KILLED_BY_AN; 1616. if (how & PLAYER) 1617. killer = "genocidal confusion"; 1618. else /* selected player deliberately, not confused */ 1619. killer = "scroll of genocide"; 1620. 1621. /* Polymorphed characters will die as soon as they're rehumanized. */ 1622. /* KMH -- Unchanging prevents rehumanization */ 1623. if (Upolyd && ptr != youmonst.data) You_feel("dead inside."); 1624. else 1625. done(GENOCIDED); 1626. } else if (ptr == youmonst.data) { 1627. rehumanize(); 1628. } 1629. reset_rndmonst(mndx); 1630. kill_genocided_monsters(); 1631. update_inventory(); /* in case identified eggs were affected */ 1632. } else { 1633. int cnt = 0; 1634. 1635. if (!(mons[mndx].geno & G_UNIQ) && 1636. !(mvitals[mndx].mvflags & (G_GENOD | G_EXTINCT))) 1637. for (i = rn1(3, 4); i > 0; i--) { 1638. if (!makemon(ptr, u.ux, u.uy, NO_MINVENT)) 1639. break; /* couldn't make one */ 1640. ++cnt; 1641. if (mvitals[mndx].mvflags & G_EXTINCT) 1642. break; /* just made last one */ 1643. } 1644. if (cnt) 1645. pline("Sent in some %s.", makeplural(buf)); 1646. else 1647. pline(nothing_happens); 1648. } 1649. } 1650. 1651. void 1652. punish(sobj) 1653. register struct obj *sobj; 1654. { 1655. /* KMH -- Punishment is still okay when you are riding */ 1656. You("are being punished for your misbehavior!"); 1657. if(Punished){ 1658. Your("iron ball gets heavier."); 1659. uball->owt += 160 * (1 + sobj->cursed); 1660. return; 1661. } 1662. if (amorphous(youmonst.data) || is_whirly(youmonst.data) || unsolid(youmonst.data)) { 1663. pline("A ball and chain appears, then falls away."); 1664. dropy(mkobj(BALL_CLASS, TRUE)); 1665. return; 1666. } 1667. setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN); 1668. setworn(mkobj(BALL_CLASS, TRUE), W_BALL); 1669. uball->spe = 1; /* special ball (see save) */ 1670. 1671. /* 1672. * Place ball & chain if not swallowed. If swallowed, the ball & 1673. * chain variables will be set at the next call to placebc(). 1674. */ 1675. if (!u.uswallow) { 1676. placebc(); 1677. if (Blind) set_bc(1); /* set up ball and chain variables */ 1678. newsym(u.ux,u.uy); /* see ball&chain if can't see self */ 1679. } 1680. } 1681. 1682. void 1683. unpunish() 1684. { /* remove the ball and chain */ 1685. struct obj *savechain = uchain; 1686. 1687. obj_extract_self(uchain); 1688. newsym(uchain->ox,uchain->oy); 1689. setworn((struct obj *)0, W_CHAIN); 1690. dealloc_obj(savechain); 1691. uball->spe = 0; 1692. setworn((struct obj *)0, W_BALL); 1693. } 1694. 1695. /* some creatures have special data structures that only make sense in their 1696. * normal locations -- if the player tries to create one elsewhere, or to revive 1697. * one, the disoriented creature becomes a zombie 1698. */ 1699. boolean 1700. cant_create(mtype, revival) 1701. int *mtype; 1702. boolean revival; 1703. { 1704. 1705. /* SHOPKEEPERS can be revived now */ 1706. if (*mtype==PM_GUARD || (*mtype==PM_SHOPKEEPER && !revival) 1707. || *mtype==PM_ALIGNED_PRIEST || *mtype==PM_ANGEL) { 1708. *mtype = PM_HUMAN_ZOMBIE; 1709. return TRUE; 1710. } else if (*mtype==PM_LONG_WORM_TAIL) { /* for create_particular() */ 1711. *mtype = PM_LONG_WORM; 1712. return TRUE; 1713. } 1714. return FALSE; 1715. } 1716. 1717. #ifdef WIZARD 1718. boolean 1719. create_particular() 1720. { 1721. char buf[BUFSZ]; 1722. int which, tries = 0; 1723. 1724. do { 1725. getlin("Create what kind of monster? [type the name]", buf); 1726. if (buf[0] == '\033') return FALSE; 1727. which = name_to_mon(buf); 1728. if (which < LOW_PM) pline("I've never heard of such monsters."); 1729. else break; 1730. } while (++tries < 5); 1731. if (tries == 5) pline(thats_enough_tries); 1732. else { 1733. (void) cant_create(&which, FALSE); 1734. return((boolean)(makemon(&mons[which], 1735. u.ux, u.uy, NO_MM_FLAGS) != 0)); 1736. } 1737. return FALSE; 1738. } 1739. #endif /* WIZARD */ 1740. 1741. #endif /* OVLB */ 1742. 1743. /*read.c*/