Source:NetHack 3.1.0/read.c

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*/