Source:NetHack 3.2.0/read.c

Below is the full text to read.c from the source code of NetHack 3.2.0. To link to a particular line, write [[NetHack 3.2.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.2	96/03/16	*/ 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.   #define Your_Own_Role(mndx) (\  8.    	Role_is('C') ? (mndx == PM_CAVEMAN || mndx == PM_CAVEWOMAN) :	\  9.    	Role_is('P') ? (mndx == PM_PRIEST  || mndx == PM_PRIESTESS) :	\  10.   	(mndx == u.umonster)) 11.   12.   #ifdef OVLB 13.   14.   /* elven armor vibrates warningly when enchanted beyond a limit */ 15.  #define is_elven_armor(optr)	((optr)->otyp == ELVEN_LEATHER_HELM\  16.   				|| (optr)->otyp == ELVEN_MITHRIL_COAT\  17.   				|| (optr)->otyp == ELVEN_CLOAK\  18.   				|| (optr)->otyp == ELVEN_SHIELD\  19.   				|| (optr)->otyp == ELVEN_BOOTS) 20.   21.   boolean	known; 22.   23.   static NEARDATA const char readable[] = 24.  		   { ALL_CLASSES, SCROLL_CLASS, SPBOOK_CLASS, 0 }; 25.  static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 }; 26.   27.   static void FDECL(wand_explode, (struct obj *)); 28.  static void NDECL(do_class_genocide); 29.  static void FDECL(stripspe,(struct obj *)); 30.  static void FDECL(p_glow1,(struct obj *)); 31.  static void FDECL(p_glow2,(struct obj *,const char *)); 32.  static void FDECL(randomize,(int *, int)); 33.  static void FDECL(forget_single_object, (int)); 34.  static void FDECL(forget, (int)); 35.   36.   STATIC_PTR void FDECL(set_lit, (int,int,genericptr_t)); 37.   38.   int 39.  doread 40.  {  41.   	register struct obj *scroll; 42.  	register boolean confused; 43.   44.   	known = FALSE; 45.  	if(check_capacity((char *)0)) return (0); 46.  	scroll = getobj(readable, "read"); 47.  	if(!scroll) return(0); 48.   49.   	/* outrumor has its own blindness check */ 50.  	if(scroll->otyp == FORTUNE_COOKIE) { 51.  	    if(flags.verbose) 52.  		You("break up the cookie and throw away the pieces."); 53.  	    outrumor(bcsign(scroll), TRUE); 54.  	    useup(scroll); 55.  	    return(1); 56.  #ifdef TOURIST 57.  	} else if (scroll->otyp == T_SHIRT) { 58.  	    char buf[BUFSZ]; 59.   60.   	    if (Blind) { 61.  		You_cant("feel any Braille writing."); 62.  		return 0; 63.  	    }  64.   	    if(flags.verbose) 65.  		pline("It reads:"); 66.  	    Sprintf(buf,  "I explored the Dungeons of Doom, %s.",  67.   		    Hallucination ?  68.   			(scroll == uarmu ? 69.  			    /* (force these two to have identical length) */ 70.  			    "and never did any laundry..." : 71.   			    "and couldn't find my way out") :  72.   			"but all I got was this lousy T-shirt"); 73.  	    if (scroll->oeroded) 74.  		wipeout_text(buf,  75.   			(int)(strlen(buf) * scroll->oeroded / (2*MAX_ERODE)),  76.   			     scroll->o_id ^ (unsigned)u.ubirthday); 77.  	    pline("\"%s\"", buf); 78.  	    return 1; 79.  #endif	/* TOURIST */ 80.  	} else if (scroll->oclass != SCROLL_CLASS  81.   		&& scroll->oclass != SPBOOK_CLASS) { 82.  	    pline(silly_thing_to, "read"); 83.  	    return(0); 84.  	} else if (Blind) { 85.  	    const char *what = 0; 86.  	    if (scroll->oclass == SPBOOK_CLASS) 87.  		what = "mystic runes"; 88.  	    else if (!scroll->dknown) 89.  		what = "formula on the scroll"; 90.  	    if (what) { 91.  		pline("Being blind, you cannot read the %s.", what); 92.  		return(0); 93.  	    }  94.   	}  95.    96.   	confused = (Confusion != 0); 97.  #ifdef MAIL 98.  	if (scroll->otyp == SCR_MAIL) confused = FALSE; 99.  #endif 100. 	if(scroll->oclass == SPBOOK_CLASS) { 101. 	    if(confused) { 102. 		You("cannot grasp the meaning of this tome."); 103. 		return(0); 104. 	    } else 105. 		return(study_book(scroll)); 106. 	}  107.  #ifndef NO_SIGNAL 108. 	scroll->in_use = TRUE;	/* scroll, not spellbook, now being read */ 109. #endif 110. 	if(scroll->otyp != SCR_BLANK_PAPER) { 111. 	  if(Blind) 112. 	    pline("As you pronounce the formula on it, the scroll disappears."); 113. 	  else 114. 	    pline("As you read the scroll, it disappears."); 115. 	  if(confused) { 116. 	    if (Hallucination) 117. 		pline("Being so trippy, you screw up..."); 118. 	    else 119. 		pline("Being confused, you mispronounce the magic words..."); 120. 	  }  121.  	}  122.  	if(!seffects(scroll))  { 123. 		if(!objects[scroll->otyp].oc_name_known) { 124. 		    if(known) { 125. 			makeknown(scroll->otyp); 126. 			more_experienced(0,10); 127. 		    } else if(!objects[scroll->otyp].oc_uname) 128. 			docall(scroll); 129. 		}  130.  		if(scroll->otyp != SCR_BLANK_PAPER) 131. 			useup(scroll); 132. #ifndef NO_SIGNAL 133. 		else scroll->in_use = FALSE; 134. #endif 135. 	}  136.  	return(1); 137. }  138.   139.  static void 140. stripspe(obj) 141. register struct obj *obj; 142. {  143.  	if (obj->blessed) pline(nothing_happens); 144. 	else { 145. 		if (obj->spe > 0) { 146. 		    obj->spe = 0; 147. 		    if (obj->otyp == OIL_LAMP || obj->otyp == BRASS_LANTERN) 148. 			obj->age = 0; 149. 		    Your("%s vibrates briefly.",xname(obj)); 150. 		} else pline(nothing_happens); 151. 	}  152.  }  153.   154.  static void 155. p_glow1(otmp) 156. register struct obj	*otmp; 157. {  158.  	Your("%s %s briefly.", xname(otmp),  159.  		Blind ? "vibrates" : "glows"); 160. }  161.   162.  static void 163. p_glow2(otmp,color) 164. register struct obj	*otmp; 165. register const char *color; 166. {  167.  	Your("%s %s%s for a moment.",  168.  		xname(otmp),  169.  		Blind ? "vibrates" : "glows ",  170.  		Blind ? (const char *)"" : hcolor(color)); 171. }  172.   173.  /* Is the object chargeable? For purposes of inventory display; it is */ 174. /* possible to be able to charge things for which this returns FALSE. */ 175.  boolean 176. is_chargeable(obj) 177. struct obj *obj; 178. {  179.  	if (obj->oclass == WAND_CLASS) return TRUE; 180. 	/* known && !uname is possible after amnesia/mind flayer */ 181. 	if (obj->oclass == RING_CLASS) 182. 	    return (boolean)(objects[obj->otyp].oc_charged &&  183.  			(obj->known || objects[obj->otyp].oc_uname)); 184. 	if (obj->oclass == TOOL_CLASS) 185. 	    return (boolean)(objects[obj->otyp].oc_charged); 186. 	return FALSE; /* why are weapons/armor considered charged anyway? */ 187.  }  188.   189.  /*  190.   * recharge an object; curse_bless is -1 if the recharging implement 191.  * was cursed, +1 if blessed, 0 otherwise. 192.  */  193.  void 194. recharge(obj, curse_bless) 195. struct obj *obj; 196. int curse_bless; 197. {  198.  	register int n;  199. boolean is_cursed, is_blessed; 200.  201.  	is_cursed = curse_bless < 0; 202. 	is_blessed = curse_bless > 0; 203.  204.  	if (obj->oclass == WAND_CLASS) { 205. 	    if (obj->otyp == WAN_WISHING) { 206. 		if (obj->recharged) {	/* recharged once already? */ 207.  		    wand_explode(obj); 208. 		    return; 209. 		}  210.  		if (is_cursed) stripspe(obj); 211. 		else if (is_blessed) { 212. 		    if (obj->spe != 3) { 213. 			obj->spe = 3; 214. 			p_glow2(obj,blue); 215. 		    } else { 216. 			wand_explode(obj); 217. 			return; 218. 		    }  219.  		} else { 220. 		    if (obj->spe < 3) { 221. 			obj->spe++; 222. 			p_glow2(obj,blue); 223. 		    } else pline(nothing_happens); 224. 		}  225.  		obj->recharged = 1; /* another recharging disallowed */ 226. 	    } else { 227. 		if (is_cursed) stripspe(obj); 228. 		else if (is_blessed) { 229. 		    if (objects[obj->otyp].oc_dir == NODIR) { 230. 			n = rn1(5,11); 231. 			if (obj->spe < n) obj->spe = n;  232. else obj->spe++; 233. 		    } else { 234. 			n = rn1(5,4); 235. 			if (obj->spe < n) obj->spe = n;  236. else obj->spe++; 237. 		    }  238.  		    p_glow2(obj,blue); 239. 		} else { 240. 		    obj->spe++; 241. 		    p_glow1(obj); 242. 		}  243.  	    }  244.  	} else if (obj->oclass == RING_CLASS &&  245.  					objects[obj->otyp].oc_charged) { 246. 	    /* charging does not affect ring's curse/bless status */ 247. 	    int s = is_blessed ? rnd(3) : is_cursed ? -rnd(2) : 1; 248. 	    boolean is_on = (obj == uleft || obj == uright); 249.  250.  	    /* destruction depends on current state, not adjustment */ 251. 	    if (obj->spe > rn2(7) || obj->spe <= -5) { 252. 		Your("%s pulsates momentarily, then explodes!",  253.  		     xname(obj)); 254. 		if (is_on) Ring_gone(obj); 255. 		s = rnd(3 * abs(obj->spe));	/* amount of damage */ 256. 		useup(obj); 257. 		losehp(s, "exploding ring", KILLED_BY_AN); 258. 	    } else { 259. 		long mask = is_on ? (obj == uleft ? LEFT_RING : 260.  				     RIGHT_RING) : 0L; 261. 		Your("%s spins %sclockwise for a moment.",  262.  		     xname(obj), s < 0 ? "counter" : ""); 263. 		/* cause attributes and/or properties to be updated */ 264. 		if (is_on) Ring_off(obj); 265. 		obj->spe += s;	/* update the ring while it's off */ 266. 		if (is_on) setworn(obj, mask), Ring_on(obj); 267. 		/* oartifact: if a touch-sensitive artifact ring is  268. ever created the above will need to be revised */ 269. 	    }  270.  	} else { 271. 	    switch(obj->otyp) { 272. 	    case BELL_OF_OPENING: 273. 		if (is_cursed) stripspe(obj); 274. 		else if (is_blessed) obj->spe += rnd(3); 275. 		else obj->spe += 1; 276. 		if (obj->spe > 5) obj->spe = 5; 277. 		break; 278. 	    case MAGIC_MARKER: 279. 		if (is_cursed) stripspe(obj); 280. 		else if (obj->recharged) { 281. 		    if (obj->spe < 3) 282. 			Your("marker seems permanently dried out."); 283. 		    else 284. 			pline(nothing_happens); 285. 		} else if (is_blessed) { 286. 		    n = obj->spe; 287. 		    if (n < 50) obj->spe = 50; 288. 		    if (n >= 50 && n < 75) obj->spe = 75; 289. 		    if (n >= 75) obj->spe += 10; 290. 		    p_glow2(obj,blue); 291. 		    obj->recharged = 1; 292. 		} else { 293. 		    if (obj->spe < 50) obj->spe = 50; 294. 		    else obj->spe++; 295. 		    p_glow2(obj,White); 296. 		    obj->recharged = 1; 297. 		}  298.  		break; 299. 	    case OIL_LAMP: 300. 	    case BRASS_LANTERN: 301. 		if (is_cursed) { 302. 		    stripspe(obj); 303. 		    if (obj->lamplit) { 304. 			if (!Blind) 305. 			    pline("%s goes out!", The(xname(obj))); 306. 			end_burn(obj, TRUE); 307. 		    }  308.  		} else if (is_blessed) { 309. 		    obj->spe = 1; 310. 		    obj->age = 1500; 311. 		    p_glow2(obj,blue); 312. 		} else { 313. 		    obj->spe = 1; 314. 		    obj->age += 750; 315. 		    if (obj->age > 1500) obj->age = 1500; 316. 		    p_glow1(obj); 317. 		}  318.  		break; 319. 	    case CRYSTAL_BALL: 320. 		if (is_cursed) stripspe(obj); 321. 		else if (is_blessed) { 322. 		    obj->spe = 6; 323. 		    p_glow2(obj,blue); 324. 		} else { 325. 		    if (obj->spe < 5) { 326. 			obj->spe++; 327. 			p_glow1(obj); 328. 		    } else pline(nothing_happens); 329. 		}  330.  		break; 331. 	    case HORN_OF_PLENTY: 332. 	    case BAG_OF_TRICKS: 333. 	    case CAN_OF_GREASE: 334. 		if (is_cursed) stripspe(obj); 335. 		else if (is_blessed) { 336. 		    if (obj->spe <= 10) 337. 			obj->spe += rn1(10, 6); 338. 		    else obj->spe += rn1(5, 6); 339. 		    p_glow2(obj,blue); 340. 		} else { 341. 		    obj->spe += rnd(5); 342. 		    p_glow1(obj); 343. 		}  344.  		break; 345. 	    case MAGIC_FLUTE: 346. 	    case MAGIC_HARP: 347. 	    case FROST_HORN: 348. 	    case FIRE_HORN: 349. 	    case DRUM_OF_EARTHQUAKE: 350. 		if (is_cursed) { 351. 		    stripspe(obj); 352. 		} else if (is_blessed) { 353. 		    obj->spe += d(2,4); 354. 		    p_glow2(obj,blue); 355. 		} else { 356. 		    obj->spe += rnd(4); 357. 		    p_glow1(obj); 358. 		}  359.  		break; 360. 	    default: 361. 		You("have a feeling of loss."); 362. 		break; 363. 	    } /* switch */ 364. 	}  365.  }  366.   367.   368.  /* Forget known information about this object class. */ 369.  static void 370. forget_single_object(obj_id) 371. 	int obj_id; 372. {  373.  	objects[obj_id].oc_name_known = 0; 374. 	objects[obj_id].oc_pre_discovered = 0;	/* a discovery when relearned */ 375. 	if (objects[obj_id].oc_uname) { 376. 	    /* this only works if oc_name_known is false */ 377. 	    undiscover_object(obj_id); 378.  379.  	    free((genericptr_t)objects[obj_id].oc_uname); 380. 	    objects[obj_id].oc_uname = 0; 381. 	}  382.  	/* clear & free object names from matching inventory items too? */ 383.  }  384.   385.   386.  #if 0	/* here if anyone wants it.... */ 387.  /* Forget everything known about a particular object class. */ 388.  static void 389. forget_objclass(oclass) 390. 	int oclass; 391. {  392.  	int i;  393. 394. 	for (i=bases[oclass];  395.  		i < NUM_OBJECTS && objects[i].oc_class==oclass; i++) 396. 	    forget_single_object(i); 397. }  398.  #endif 399.  400.   401.  /* randomize the given list of numbers  0 <= i < count */ 402. static void 403. randomize(indices, count) 404. 	int *indices; 405. 	int count; 406. {  407.  	int i, iswap, temp; 408.  409.  	for (i = count - 1; i > 0; i--) { 410. 	    if ((iswap = rn2(i + 1)) == i) continue; 411. 	    temp = indices[i]; 412. 	    indices[i] = indices[iswap]; 413. 	    indices[iswap] = temp; 414. 	}  415.  }  416.   417.   418.  /* Forget % of known objects. */ 419.  void 420. forget_objects(percent) 421. 	int percent; 422. {  423.  	int i, count; 424. 	int indices[NUM_OBJECTS]; 425.  426.  	if (percent == 0) return; 427. 	if (percent <= 0 || percent > 100) { 428. 	    impossible("forget_objects: bad percent %d", percent); 429. 	    return; 430. 	}  431.   432.  	for (count = 0, i = 1; i < NUM_OBJECTS; i++) 433. 	    if (objects[i].oc_name_known && OBJ_DESCR(objects[i])) 434. 		indices[count++] = i;  435. 436. 	randomize(indices, count); 437.  438.  	/* forget first % of randomized indices */ 439. 	count = ((count * percent) + 50) / 100; 440. 	for (i = 0; i < count; i++) 441. 	    forget_single_object(indices[i]); 442. }  443.   444.   445.  /* Forget some or all of map (depends on parameters). */ 446.  void 447. forget_map(howmuch) 448. 	int howmuch; 449. {  450.  	register int zx, zy; 451.  452.  	known = TRUE; 453. 	for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++) 454. 	    if (howmuch & ALL_MAP || rn2(7)) { 455. 		/* Zonk all memory of this location. */ 456.  		levl[zx][zy].seenv = 0; 457. 		levl[zx][zy].waslit = 0; 458. 		levl[zx][zy].glyph = cmap_to_glyph(S_stone); 459. 	    }  460.  }  461.   462.  /* Forget all traps on the level. */ 463.  void 464. forget_traps 465. {  466.  	register struct trap *trap; 467.  468.  	/* forget all traps (except the one the hero is in :-) */ 469. 	for (trap = ftrap; trap; trap = trap->ntrap) 470. 	    if ((trap->tx != u.ux || trap->ty != u.uy) && (trap->ttyp != HOLE)) 471. 		trap->tseen = 0; 472. }  473.   474.  /*  475.   * Forget given % of all levels that the hero has visited and not forgotten, 476.  * except this one. 477.  */  478.  void 479. forget_levels(percent) 480. 	int percent; 481. {  482.  	int i, count; 483. 	xchar  maxl, this_lev; 484. 	int indices[MAXLINFO]; 485.  486.  	if (percent == 0) return; 487.  488.  	if (percent <= 0 || percent > 100) { 489. 	    impossible("forget_levels: bad percent %d", percent); 490. 	    return; 491. 	}  492.   493.  	this_lev = ledger_no(&u.uz); 494. 	maxl = maxledgerno; 495.  496.  	/* count & save indices of non-forgotten visited levels */ 497. 	for (count = 0, i = 0; i <= maxl; i++) 498. 	    if ((level_info[i].flags & VISITED) &&  499.  			!(level_info[i].flags & FORGOTTEN) && i != this_lev) 500. 		indices[count++] = i;  501. 502. 	randomize(indices, count); 503.  504.  	/* forget first % of randomized indices */ 505. 	count = ((count * percent) + 50) / 100; 506. 	for (i = 0; i < count; i++) { 507. 	    level_info[indices[i]].flags |= FORGOTTEN; 508. 	}  509.  }  510.   511.  /*  512.   * Forget some things (e.g. after reading a scroll of amnesia). When called, 513.  * the following are always forgotten: 514.  *  515.   *	- felt ball & chain 516.  *	- traps 517.  *	- part (6 out of 7) of the map 518.  *  519.   * Other things are subject to flags: 520.  *  521.   *	howmuch & ALL_MAP	= forget whole map 522.  *	howmuch & ALL_SPELLS	= forget all spells 523.  */  524.  static void 525. forget(howmuch) 526. int howmuch; 527. {  528.   529.  	if (Punished) u.bc_felt = 0;	/* forget felt ball&chain */ 530.  531.  	forget_map(howmuch); 532. 	forget_traps; 533.  534.  	/* 1 in 3 chance of forgetting some levels */ 535. 	if (!rn2(3)) forget_levels(rn2(25)); 536.  537.  	/* 1 in 3 chance of forgeting some objects */ 538. 	if (!rn2(3)) forget_objects(rn2(25)); 539.  540.  	if (howmuch & ALL_SPELLS) losespells; 541. 	/*  542.  	 * Make sure that what was seen is restored correctly. To do this, 543. 	 * we need to go blind for an instant --- turn off the display, 544. 	 * then restart it. All this work is needed to correctly handle 545. 	 * walls which are stone on one side and wall on the other. Turning 546. 	 * off the seen bits above will make the wall revert to stone,  but 547. 	 * there are cases where we don't want this to happen. The easiest 548. 	 * thing to do is to run it through the vision system again, which 549. 	 * is always correct. 550. 	 */  551.  	docrt;		/* this correctly will reset vision */ 552. }  553.   554.  int 555. seffects(sobj) 556. register struct obj	*sobj; 557. {  558.  	register int cval; 559. 	register boolean confused = (Confusion != 0); 560. 	register struct obj *otmp; 561.  562.  	if (objects[sobj->otyp].oc_magic) 563. 		exercise(A_WIS, TRUE);		/* just for trying */ 564. 	switch(sobj->otyp) { 565. #ifdef MAIL 566. 	case SCR_MAIL: 567. 		known = TRUE; 568. 		if (sobj->spe) 569. 		    pline("This seems to be junk mail addressed to the finder of the Eye of Larn."); 570. 		/* note to the puzzled: the game Larn actually sends you junk 571. 		 * mail if you win! 572. 		 */  573.  		else readmail(sobj); 574. 		break; 575. #endif 576. 	case SCR_ENCHANT_ARMOR: 577. 	    {  578.  		register schar s;  579. boolean special_armor; 580.  581.  		otmp = some_armor; 582. 		if(!otmp) { 583. 			strange_feeling(sobj,  584.  					!Blind ? "Your skin glows then fades." :  585.  					"Your skin feels warm for a moment."); 586. 			exercise(A_CON, !sobj->cursed); 587. 			exercise(A_STR, !sobj->cursed); 588. 			return(1); 589. 		}  590.  		if(confused) { 591. 			otmp->oerodeproof = !(sobj->cursed); 592. 			if(Blind) { 593. 			    otmp->rknown = FALSE; 594. 			    Your("%s feels warm for a moment.",  595.  				xname(otmp)); 596. 			} else { 597. 			    otmp->rknown = TRUE; 598. 			    Your("%s is covered by a %s %s %s!",  599.  				xname(otmp),  600.  				sobj->cursed ? "mottled" : "shimmering",  601.  				hcolor(sobj->cursed ? Black : golden), 602.  				sobj->cursed ? "glow" :  603.  				  (is_shield(otmp) ? "layer" : "shield")); 604. 			}  605.  			if (otmp->oerodeproof && otmp->oeroded) { 606. 			    otmp->oeroded = 0; 607. 			    Your("%s %ss good as new!",  608.  				 xname(otmp), Blind ? "feel" : "look"); 609. 			}  610.  			break; 611. 		}  612.  		special_armor = is_elven_armor(otmp) || 613. 				(Role_is('W') && otmp->otyp == CORNUTHAUM); 614. 		if ((otmp->spe > (special_armor ? 5 : 3)) &&  615.  		    rn2(otmp->spe) && !sobj->cursed) { 616. 		Your("%s violently %s%s for a while, then evaporates.",  617.  			    xname(otmp),  618.  			    Blind ? "vibrates" : "glows ",  619.  			    Blind ? nul : hcolor(silver)); 620. 			if(is_cloak(otmp)) (void) Cloak_off; 621. 			if(is_boots(otmp)) (void) Boots_off; 622. 			if(is_helmet(otmp)) (void) Helmet_off; 623. 			if(is_gloves(otmp)) (void) Gloves_off; 624. 			if(is_shield(otmp)) (void) Shield_off; 625. 			if(otmp == uarm) (void) Armor_gone; 626. 			useup(otmp); 627. 			break; 628. 		}  629.  		s = sobj->cursed ? -1 : 630.  		    otmp->spe >= 9 ? (rn2(otmp->spe) == 0) : 631. 		    sobj->blessed ? rnd(3-otmp->spe/3) : 1; 632. 		if (s >= 0 && otmp->otyp >= GRAY_DRAGON_SCALES &&  633.  					otmp->otyp <= YELLOW_DRAGON_SCALES) { 634. 			/* dragon scales get turned into dragon scale mail */ 635. 			Your("%s merges and hardens!", xname(otmp)); 636. 			setworn((struct obj *)0, W_ARM); 637. 			/* assumes same order */ 638. 			otmp->otyp = GRAY_DRAGON_SCALE_MAIL + 639. 						otmp->otyp - GRAY_DRAGON_SCALES; 640. 			otmp->cursed = 0; 641. 			if (sobj->blessed) { 642. 				otmp->spe++; 643. 				otmp->blessed = 1; 644. 			}  645.  			otmp->known = 1; 646. 			setworn(otmp, W_ARM); 647. 			break; 648. 		}  649.  		Your("%s %s%s%s for a %s.",  650.  			xname(otmp),  651.  		        s == 0 ? "violently " : nul,  652.  			Blind ? "vibrates" : "glows ",  653.  			Blind ? nul : hcolor(sobj->cursed ? Black : silver), 654.  			  (s*s>1) ? "while" : "moment"); 655. 		otmp->cursed = sobj->cursed; 656. 		if (!otmp->blessed || sobj->cursed) 657. 			otmp->blessed = sobj->blessed; 658. 		if (s) { 659. 			otmp->spe += s;  660. adj_abon(otmp, s); 661. 			known = otmp->known; 662. 		}  663.   664.  		if ((otmp->spe > (special_armor ? 5 : 3)) &&  665.  		    (special_armor || !rn2(7))) 666. 			Your("%s suddenly vibrates %s.",  667.  				xname(otmp),  668.  				Blind ? "again" : "unexpectedly"); 669. 		break; 670. 	    }  671.  	case SCR_DESTROY_ARMOR: 672. 	    {  673.  		otmp = some_armor; 674. 		if(confused) { 675. 			if(!otmp) { 676. 				strange_feeling(sobj,"Your bones itch."); 677. 				exercise(A_STR, FALSE); 678. 				exercise(A_CON, FALSE); 679. 				return(1); 680. 			}  681.  			otmp->oerodeproof = sobj->cursed; 682. 			p_glow2(otmp,purple); 683. 			break; 684. 		}  685.  		if(!sobj->cursed || !otmp || !otmp->cursed) { 686. 		    if(!destroy_arm(otmp)) { 687. 			strange_feeling(sobj,"Your skin itches."); 688. 			exercise(A_STR, FALSE); 689. 			exercise(A_CON, FALSE); 690. 			return(1); 691. 		    } else 692. 			known = TRUE; 693. 		} else {	/* armor and scroll both cursed */ 694. 		    Your("%s vibrates.", xname(otmp)); 695. 		    if (otmp->spe >= -6) otmp->spe--; 696. 		    make_stunned(HStun + rn1(10, 10), TRUE); 697. 		}  698.  	    }  699.  	    break; 700. 	case SCR_CONFUSE_MONSTER: 701. 	case SPE_CONFUSE_MONSTER: 702. 		if(u.usym != S_HUMAN || sobj->cursed) { 703. 			if(!HConfusion) You_feel("confused."); 704. 			make_confused(HConfusion + rnd(100),FALSE); 705. 		} else  if(confused) { 706. 		    if(!sobj->blessed) { 707. 			Your("%s begin to %s%s.",  708.  			    makeplural(body_part(HAND)),  709.  			    Blind ? "tingle" : "glow ",  710.  			    Blind ? nul : hcolor(purple)); 711. 			make_confused(HConfusion + rnd(100),FALSE); 712. 		    } else { 713. 			pline("A %s%s surrounds your %s.",  714.  			    Blind ? nul : hcolor(red),  715.  			    Blind ? "faint buzz" : " glow",  716.  			    body_part(HEAD)); 717. 			make_confused(0L,TRUE); 718. 		    }  719.  		} else { 720. 		    if (!sobj->blessed) { 721. 			Your("%s%s %s%s.",  722.  			makeplural(body_part(HAND)),  723.  			Blind ? "" : " begin to glow",  724.  			Blind ? (const char *)"tingle" : hcolor(red),  725.  			u.umconf ? " even more" : ""); 726. 			u.umconf++; 727. 		    } else { 728. 			if (Blind) 729. 			    Your("%s tingle %s sharply.",  730.  				makeplural(body_part(HAND)),  731.  				u.umconf ? "even more" : "very"); 732. 			else 733. 			    Your("%s glow a%s brilliant %s.",  734.  				makeplural(body_part(HAND)),  735.  				u.umconf ? "n even more" : "",  736.  				hcolor(red)); 737. 			u.umconf += rn1(8, 2); 738. 		    }  739.  		}  740.  		break; 741. 	case SCR_SCARE_MONSTER: 742. 	case SPE_CAUSE_FEAR: 743. 	    {	register int ct = 0; 744. 		register struct monst *mtmp; 745.  746.  		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 747. 		    if(cansee(mtmp->mx,mtmp->my)) { 748. 			if(confused || sobj->cursed) { 749. 			    mtmp->mflee = mtmp->mfrozen = mtmp->msleep = 0; 750. 			    mtmp->mcanmove = 1; 751. 			} else 752. 			    if (! resist(mtmp, sobj->oclass, 0, NOTELL)) 753. 				mtmp->mflee = 1; 754. 			if(!mtmp->mtame) ct++;	/* pets don't laugh at you */ 755. 		    }  756.  		if(!ct) 757. 		      You_hear("%s in the distance.",  758.  			       (confused || sobj->cursed) ? "sad wailing" :  759.  							"maniacal laughter"); 760. 		else if(sobj->otyp == SCR_SCARE_MONSTER) 761. 			You_hear("%s close by.",  762.  				  (confused || sobj->cursed) ? "sad wailing" :  763.  						 "maniacal laughter"); 764. 		break; 765. 	    }  766.  	case SCR_BLANK_PAPER: 767. 	    if (Blind) 768. 		You("don't remember there being any magic words on this scroll."); 769. 	    else 770. 		pline("This scroll seems to be blank."); 771. 	    known = TRUE; 772. 	    break; 773. 	case SCR_REMOVE_CURSE: 774. 	case SPE_REMOVE_CURSE: 775. 	    {	register struct obj *obj; 776. 		if(confused) 777. 		    if (Hallucination) 778. 			You_feel("the power of the Force against you!"); 779. 		    else 780. 			You_feel("like you need some help."); 781. 		else 782. 		    if (Hallucination) 783. 			You_feel("in touch with the Universal Oneness."); 784. 		    else 785. 			You_feel("like someone is helping you."); 786.  787.  		if(sobj->cursed) pline_The("scroll disintegrates."); 788. 		else { 789. 		    for(obj = invent; obj ; obj = obj->nobj) 790. 			if(sobj->blessed || obj->owornmask ||  791.  			   (obj->otyp == LOADSTONE)) { 792. 			    if(confused) blessorcurse(obj, 2); 793. 			    else uncurse(obj); 794. 			}  795.  		}  796.  		if(Punished && !confused) unpunish; 797. 		break; 798. 	    }  799.  	case SCR_CREATE_MONSTER: 800. 	case SPE_CREATE_MONSTER: 801. 	    if (create_critters(1 + ((confused || sobj->cursed) ? 12 : 0) + 802. 				((sobj->blessed || rn2(73)) ? 0 : rnd(4)), 803. 			confused ? &mons[PM_ACID_BLOB] : (struct permonst *)0)) 804. 		known = TRUE; 805. 	    /* no need to flush monsters; we ask for identification only if the 806. 	     * monsters are not visible 807. 	     */  808.  	    break; 809. 	case SCR_ENCHANT_WEAPON: 810. 		if(uwep && (uwep->oclass == WEAPON_CLASS || is_weptool(uwep))  811.  			&& confused) { 812. 		/* oclass check added 10/25/86 GAN */ 813. 			uwep->oerodeproof = !(sobj->cursed); 814. 			if (Blind) { 815. 			    uwep->rknown = FALSE; 816. 			    Your("weapon feels warm for a moment."); 817. 			} else { 818. 			    uwep->rknown = TRUE; 819. 			    Your("%s covered by a %s %s %s!",  820.  				aobjnam(uwep, "are"),  821.  				sobj->cursed ? "mottled" : "shimmering",  822.  				hcolor(sobj->cursed ? purple : golden), 823.  				sobj->cursed ? "glow" : "shield"); 824. 			}  825.  			if (uwep->oerodeproof && uwep->oeroded) { 826. 			    uwep->oeroded = 0; 827. 			    Your("%s good as new!",  828.  				 aobjnam(uwep, Blind ? "feel" : "look")); 829. 			}  830.  		} else return !chwepon(sobj,  831.  				       sobj->cursed ? -1 :  832.  				       !uwep ? 1 :  833.  				       uwep->spe >= 9 ? (rn2(uwep->spe) == 0) :  834.  				       sobj->blessed ? rnd(3-uwep->spe/3) : 1); 835. 		break; 836. 	case SCR_TAMING: 837. 	case SPE_CHARM_MONSTER: 838. 	    {	register int i,j; 839. 		register int bd = confused ? 5 : 1; 840.  		register struct monst *mtmp; 841.  842.  		for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) 843. 		if(isok(u.ux+i, u.uy+j) && (mtmp = m_at(u.ux+i, u.uy+j))) { 844. 		    if(sobj->cursed) { 845. 			setmangry(mtmp); 846. 		    } else { 847. 			if (mtmp->isshk) 848. 			    make_happy_shk(mtmp, FALSE); 849. 			else if (!resist(mtmp, sobj->oclass, 0, NOTELL)) 850. 			    (void) tamedog(mtmp, (struct obj *) 0); 851. 		    }  852.  		}  853.  		break; 854. 	    }  855.  	case SCR_GENOCIDE: 856. 		You("have found a scroll of genocide!"); 857. 		known = TRUE; 858. 		if (sobj->blessed) do_class_genocide; 859. 		else do_genocide(!sobj->cursed | (2 * !!Confusion)); 860. 		break; 861. 	case SCR_LIGHT: 862. 		if(!Blind) known = TRUE; 863. 		litroom(!confused && !sobj->cursed, sobj); 864. 		break; 865. 	case SCR_TELEPORTATION: 866. 		if(confused || sobj->cursed) level_tele; 867. 		else { 868. 			if (sobj->blessed && !Teleport_control) { 869. 				known = TRUE; 870. 				if (yn("Do you wish to teleport?")=='n') 871. 					break; 872. 			}  873.  			tele; 874. 			if(Teleport_control || !couldsee(u.ux0, u.uy0) ||  875.  			   (distu(u.ux0, u.uy0) >= 16)) 876. 				known = TRUE; 877. 		}  878.  		break; 879. 	case SCR_GOLD_DETECTION: 880. 		if (confused || sobj->cursed) return(trap_detect(sobj)); 881. 		else return(gold_detect(sobj)); 882. 	case SCR_FOOD_DETECTION: 883. 	case SPE_DETECT_FOOD: 884. 		if (food_detect(sobj)) 885. 			return(1);	/* nothing detected */ 886. 		break; 887. 	case SPE_IDENTIFY: 888. 		cval = rn2(5); 889. 		goto id; 890. 	case SCR_IDENTIFY: 891. 		/* known = TRUE; */ 892. 		if(confused) 893. 			You("identify this as an identify scroll."); 894. 		else 895. 			pline("This is an identify scroll."); 896. 		if (sobj->blessed || (!sobj->cursed && !rn2(5))) { 897. 			cval = rn2(5); 898. 			/* Note: if rn2(5)==0, identify all items */ 899. 			if (cval == 1 && sobj->blessed && Luck > 0) ++cval; 900. 		} else	cval = 1; 901. 		useup(sobj); 902. 		makeknown(SCR_IDENTIFY); 903. 	id: 904. 		if(invent && !confused) { 905. 		    identify_pack(cval); 906. 		}  907.  		return(1); 908. 	case SCR_CHARGING: 909. 		if (confused) { 910. 		    You_feel("charged up!"); 911. 		    if (u.uen < u.uenmax) 912. 			u.uen = u.uenmax; 913. 		    else 914. 			u.uen = (u.uenmax += d(5,4)); 915. 		    flags.botl = 1; 916. 		    break; 917. 		}  918.  		known = TRUE; 919. 		pline("This is a charging scroll."); 920. 		otmp = getobj(all_count, "charge"); 921. 		if (!otmp) break; 922. 		recharge(otmp, sobj->cursed ? -1 : (sobj->blessed ? 1 : 0)); 923.  		break; 924. 	case SCR_MAGIC_MAPPING: 925. 		if (level.flags.nommap) { 926. 		    Your("mind is filled with crazy lines!"); 927. 		    if (Hallucination) 928. 			pline("Wow!  Modern art."); 929. 		    else 930. 			Your("head spins in bewilderment."); 931. 		    make_confused(HConfusion + rnd(30), FALSE); 932. 		    break; 933. 		}  934.  		known = TRUE; 935. 	case SPE_MAGIC_MAPPING: 936. 		if (level.flags.nommap) { 937. 		    Your("head spins as something blocks the spell!"); 938. 		    make_confused(HConfusion + rnd(30), FALSE); 939. 		    break; 940. 		}  941.  		pline("A map coalesces in your mind!"); 942. 		cval = (sobj->cursed && !confused); 943. 		if(cval) HConfusion = 1;	/* to screw up map */ 944. 		do_mapping; 945. 		if(cval) { 946. 		    HConfusion = 0;		/* restore */ 947. 		    pline("Unfortunately, you can't grasp the details."); 948. 		}  949.  		break; 950. 	case SCR_AMNESIA: 951. 		known = TRUE; 952. 		forget(	(!sobj->blessed ? ALL_SPELLS : 0) | 953.  			(!confused || sobj->cursed ? ALL_MAP : 0) ); 954. 		if (Hallucination) /* Ommmmmm! */ 955.  			Your("mind releases itself from mundane concerns."); 956. 		else if (!strncmpi(plname, "Maud", 4)) 957. 			pline("As your mind turns inward on itself, you forget everything else."); 958. 		else if (rn2(2)) 959. 			pline("Who was that Maud person anyway?"); 960. 		else 961. 			pline("Thinking of Maud you forget everything else."); 962. 		exercise(A_WIS, FALSE); 963. 		break; 964. 	case SCR_FIRE: 965. 		/*  966.  		 * Note: Modifications have been made as of 3.0 to allow for 967. 		 * some damage under all potential cases. 968. 		 */  969.  		cval = bcsign(sobj); 970. 		useup(sobj); 971. 		makeknown(SCR_FIRE); 972. 		if(confused) { 973. 		    if(Fire_resistance) { 974. 			shieldeff(u.ux, u.uy); 975. 			if(!Blind) 976. 			    pline("Oh, look, what a pretty fire in your %s.",  977.  				makeplural(body_part(HAND))); 978. 			else You_feel("a pleasant warmth in your %s.",  979.  				makeplural(body_part(HAND))); 980. 		    } else { 981. 			pline_The("scroll catches fire and you burn your %s.",  982.  				makeplural(body_part(HAND))); 983. 			losehp(1, "scroll of fire", KILLED_BY_AN); 984. 		    }  985.  		    return(1); 986. 		}  987.  		if (Underwater) 988. 			pline_The("water around you vaporizes violently!"); 989. 		else 990. 			pline_The("scroll erupts in a tower of flame!"); 991. 		explode(u.ux, u.uy, 11, (2*(rn1(3, 3) + 2 * cval) + 1)/3,  992.  							SCROLL_CLASS); 993. 		return(1); 994. 	case SCR_PUNISHMENT: 995. 		known = TRUE; 996. 		if(confused || sobj->blessed) { 997. 			You_feel("guilty."); 998. 			break; 999. 		}  1000. 		punish(sobj); 1001. 		break; 1002. 	default: 1003. 		impossible("What weird effect is this? (%u)", sobj->otyp); 1004. 	} 1005. 	return(0); 1006. } 1007.  1008. static void 1009. wand_explode(obj) 1010. register struct obj *obj; 1011. { 1012.     Your("%s vibrates violently, and explodes!",xname(obj)); 1013.    nhbell; 1014.    losehp(rnd(2*(u.uhpmax+1)/3), "exploding wand", KILLED_BY_AN); 1015.    useup(obj); 1016.    exercise(A_STR, FALSE); 1017. } 1018.  1019. /*  1020.  * Low-level lit-field update routine. 1021. */  1022. STATIC_PTR void 1023. set_lit(x,y,val) 1024. int x, y; 1025. genericptr_t val; 1026. { 1027. 	if (val) 1028. 	   levl[x][y].lit = 1; 1029. 	else { 1030. 	   levl[x][y].lit = 0; 1031. 	   snuff_light_source(x, y); 1032. 	} 1033. }  1034.  1035. void 1036. litroom(on,obj) 1037. register boolean on; 1038. struct obj *obj; 1039. { 1040. 	char is_lit;	/* value is irrelevant; we use its address 1041. 			  as a `not null' flag for set_lit */ 1042. 1043. 	/* first produce the text (provided you're not blind) */ 1044. 	if(!on) { 1045. 		register struct obj *otmp; 1046. 1047. 		if (!Blind) { 1048. 		   if(u.uswallow) { 1049. 			pline("It seems even darker in here than before."); 1050. 			return; 1051. 		   }  1052. 		    You("are surrounded by darkness!"); 1053. 		} 1054.  1055. 		/* the magic douses lamps, et al, too */ 1056. 		for(otmp = invent; otmp; otmp = otmp->nobj) 1057. 		   if (otmp->lamplit) 1058. 			(void) snuff_lit(otmp); 1059. 		if (Blind) goto do_it; 1060. 	} else { 1061. 		if (Blind) goto do_it; 1062. 		if(u.uswallow){ 1063. 			if (is_animal(u.ustuck->data)) 1064. 				pline("%s stomach is lit.", 1065. 				         s_suffix(Monnam(u.ustuck))); 1066. 			else 1067. 				if (is_whirly(u.ustuck->data)) 1068. 					pline("%s shines briefly.", 1069. 					      Monnam(u.ustuck)); 1070. 				else 1071. 					pline("%s glistens.", Monnam(u.ustuck)); 1072. 			return; 1073. 		} 1074. 		pline("A lit field surrounds you!"); 1075. 	} 1076.  1077. do_it: 1078. 	/* No-op in water - can only see the adjacent squares and that's it! */ 1079. 	if (Underwater || Is_waterlevel(&u.uz)) return; 1080. 	/* 1081. 	 *  If we are darkening the room and the hero is punished but not 1082. 	 * blind, then we have to pick up and replace the ball and chain so  1083. * that we don't remember them if they are out of sight. 1084. 	 */ 1085. 	if (Punished && !on && !Blind) 1086. 	   move_bc(1, 0, uball->ox, uball->oy, uchain->ox, uchain->oy); 1087. 1088. #ifdef REINCARNATION 1089. 	if (Is_rogue_level(&u.uz)) { 1090. 	   /* Can't use do_clear_area because MAX_RADIUS is too small */ 1091. 	   /* rogue lighting must light the entire room */ 1092. 	   int rnum = levl[u.ux][u.uy].roomno - ROOMOFFSET; 1093. 	   int rx, ry; 1094. 	   if(rnum >= 0) { 1095. 		for(rx = rooms[rnum].lx-1; rx <= rooms[rnum].hx+1; rx++) 1096. 		   for(ry = rooms[rnum].ly-1; ry <= rooms[rnum].hy+1; ry++) 1097. 			set_lit(rx, ry, 1098. 				(genericptr_t)(on ? &is_lit : (char *)0)); 1099. 		rooms[rnum].rlit = on; 1100. 	   }  1101. 	    /* hallways remain dark on the rogue level */ 1102. 	} else 1103. #endif 1104. 	   do_clear_area(u.ux,u.uy,  1105. 		(obj && obj->oclass==SCROLL_CLASS && obj->blessed) ? 9 : 5,  1106. 		set_lit, (genericptr_t)(on ? &is_lit : (char *)0)); 1107. 1108. 	/*  1109. 	 *  If we are not blind, then force a redraw on all positions in sight 1110. 	 * by temporarily blinding the hero. The vision recalculation will 1111. 	 * correctly update all previously seen positions *and* correctly 1112. 	 * set the waslit bit [could be messed up from above]. 1113. 	 */ 1114. 	if (!Blind) { 1115. 	   vision_recalc(2); 1116. 1117. 	    /* replace ball&chain */ 1118. 	   if (Punished && !on) 1119. 		move_bc(0, 0, uball->ox, uball->oy, uchain->ox, uchain->oy); 1120. 	} 1121.  1122. 	vision_full_recalc = 1;	/* delayed vision recalculation */ 1123. } 1124.  1125. static void 1126. do_class_genocide 1127. { 1128. 	register int i, j, immunecnt, gonecnt, goodcnt, class; 1129. 	char buf[BUFSZ]; 1130. 1131. 	for(j=0; ; j++) { 1132. 		if (j >= 5) { 1133. 			pline(thats_enough_tries); 1134. 			return; 1135. 		} 1136. 		do { 1137. 		   getlin("What class of monsters do you wish to genocide?",  1138. 			buf); 1139. 		} while (buf[0]=='\033' || !buf[0]); 1140. 		if (strlen(buf) == 1) 1141. 		   class = def_char_to_monclass(buf[0]); 1142. 		else 1143. 		   class = 0; 1144. 		immunecnt = gonecnt = goodcnt = 0; 1145. 		for (i = LOW_PM; i < NUMMONS; i++) { 1146. 		   if (class ? mons[i].mlet == class :  1147. 			    strstri(monexplain[(int)mons[i].mlet], 1148. 				   makesingular(buf)) != 0) { 1149. 			class = mons[i].mlet; 1150. 			if (!(mons[i].geno & G_GENO)) immunecnt++; 1151. 			else if(mvitals[i].mvflags & G_GENOD) gonecnt++; 1152. 			else goodcnt++; 1153. 		   }  1154. 		}  1155. 		if (!goodcnt && class != S_HUMAN) { 1156. 			if (gonecnt) 1157. 	pline("All such monsters are already nonexistent."); 1158. 			else if (immunecnt) 1159. 	You("aren't permitted to genocide such monsters."); 1160. 			else 1161. #ifdef WIZARD	/* to aid in topology testing; remove pesky monsters */ 1162. 			 if (wizard && buf[0] == '*') { 1163. 			   register struct monst *mtmp, *mtmp2; 1164. 1165. 			    gonecnt = 0; 1166. 			   for (mtmp = fmon; mtmp; mtmp = mtmp2) { 1167. 				mtmp2 = mtmp->nmon; 1168. 				mongone(mtmp); 1169. 				gonecnt++; 1170. 			   }  1171. 	pline("Eliminated %d monster%s.", gonecnt, plur(gonecnt)); 1172. 			   return; 1173. 			} else 1174. #endif 1175. 	pline("That symbol does not represent any monster."); 1176. 			continue; 1177. 		} 1178. 		for (i = LOW_PM; i < NUMMONS; i++) { 1179. 		   if(mons[i].mlet == class) { 1180. 			const char *n = makeplural(mons[i].mname); 1181. 1182. 			if (Your_Own_Role(i) || ((mons[i].geno & G_GENO) 1183. 				&& !(mvitals[i].mvflags & G_GENOD))) { 1184. 			/* This check must be first since player monsters might 1185. 			 * have G_GENOD or !G_GENO. 1186. 			 */ 1187. 			    pline("Wiped out all %s.", n); 1188. 			   if (&mons[i] == player_mon) { 1189. 				u.uhp = -1; 1190. 				killer_format = KILLED_BY_AN; 1191. 				killer = "scroll of genocide"; 1192. 				if (u.umonnum >= LOW_PM) 1193. 				   You_feel("dead inside."); 1194. 				else 1195. 				   done(GENOCIDED); 1196. 			   }  1197. 			    /* for simplicity (and fairness) let's avoid 1198. 			    * alignment changes here...  1199. */ 1200. 			    if (i==u.umonnum) rehumanize; 1201. 			   mvitals[i].mvflags |= (G_GENOD|G_NOCORPSE); 1202. 			   reset_rndmonst(i); 1203. 			   kill_genocided_monsters; 1204. 			   update_inventory;		/* eggs & tins */ 1205. 			} else if (mvitals[i].mvflags & G_GENOD) { 1206. 			   pline("All %s are already nonexistent.", n); 1207. 			} else { 1208. 			 /* suppress feedback about quest beings except 1209. 			    for those applicable to our own role */ 1210. 			 if ((mons[i].msound != MS_LEADER || 1211. 			      quest_info(MS_LEADER) == i)  1212. 			   && (mons[i].msound != MS_NEMESIS || 1213. 			      quest_info(MS_NEMESIS) == i)  1214. 			   && (mons[i].msound != MS_GUARDIAN || 1215. 			      quest_info(MS_GUARDIAN) == i)  1216. 			/* non-leader/nemesis/guardian role-specific monster */  1217. 			   && (i != PM_NINJA ||		/* nuisance */ 1218. 			      Role_is('S'))) { 1219. 				boolean named, uniq; 1220. 1221. 				named = type_is_pname(&mons[i]) ? TRUE : FALSE; 1222. 				uniq = (mons[i].geno & G_UNIQ) ? TRUE : FALSE; 1223. 				/* one special case */ 1224. 				if (i == PM_HIGH_PRIEST) uniq = FALSE; 1225. 1226. 				You("aren't permitted to genocide %s%s.",  1227. 				    (uniq && !named) ? "the " : "",  1228. 				    (uniq || named) ? mons[i].mname : n); 1229. 			   }  1230. 			}  1231. 		    }  1232. 		}  1233. 		return; 1234. 	} 1235. }  1236.  1237. #define REALLY 1 1238. #define PLAYER 2 1239. void 1240. do_genocide(how) 1241. int how; 1242. /* 0 = no genocide; create monsters (cursed scroll) */ 1243. /* 1 = normal genocide */ 1244. /* 3 = forced genocide of player */ 1245. { 1246. 	char buf[BUFSZ]; 1247. 	register int	i, killplayer = 0; 1248. 	register int mndx; 1249. 	register struct permonst *ptr; 1250. 	const char *which; 1251. 1252. 	if (how & PLAYER) { 1253. 		ptr = player_mon; 1254. 		mndx = monsndx(ptr); 1255. 		Strcpy(buf, ptr->mname); 1256. 		killplayer++; 1257. 	} else { 1258. 	   for(i = 0; ; i++) { 1259. 		if(i >= 5) { 1260. 		   pline(thats_enough_tries); 1261. 		   return; 1262. 		} 1263. 		getlin("What monster do you want to genocide? [type the name]",  1264. 			buf); 1265. 1266. 		mndx = name_to_mon(buf); 1267. 		if (mndx == NON_PM || (mvitals[mndx].mvflags & G_GENOD)) { 1268. 			pline("Such creatures %s exist in this world.", 1269. 			      (mndx == NON_PM) ? "do not" : "no longer"); 1270. 			continue; 1271. 		} 1272. 		ptr = &mons[mndx]; 1273. 		if (Your_Own_Role(mndx)) { 1274. 			killplayer++; 1275. 			break; 1276. 		} 1277. 		if (is_human(ptr)) adjalign(-sgn(u.ualign.type)); 1278. 		if (is_demon(ptr)) adjalign(sgn(u.ualign.type)); 1279. 1280. 		if(!(ptr->geno & G_GENO))  { 1281. 			if(flags.soundok) { 1282. 	/* fixme: unconditional "caverns" will be silly in some circumstances */ 1283. 			   if(flags.verbose) 1284. 			pline("A thunderous voice booms though the caverns:"); 1285. 			   verbalize("No, mortal!  That will not be done."); 1286. 			} 1287. 			continue; 1288. 		} 1289. 		break; 1290. 	   }  1291. 	}  1292.  1293. 	which = "all "; 1294. 	if (Hallucination) { 1295. 	   if (u.umonnum != PM_PLAYERMON) 1296. 		Strcpy(buf,uasmon->mname); 1297. 	   else { 1298. 		Strcpy(buf, pl_character); 1299. 		buf[0] = lowc(buf[0]); 1300. 	   }  1301. 	} else { 1302. 	   Strcpy(buf, ptr->mname); /* make sure we have standard singular */ 1303. 	   if ((ptr->geno & G_UNIQ) && ptr != &mons[PM_HIGH_PRIEST]) 1304. 		which = !type_is_pname(ptr) ? "the " : ""; 1305. 	} 1306. 	if (how & REALLY) { 1307. 	   /* setting no-corpse affects wishing and random tin generation */ 1308. 	   mvitals[mndx].mvflags |= (G_GENOD | G_NOCORPSE); 1309. 	   pline("Wiped out %s%s.", which,  1310. 		  (*which != 'a') ? buf : makeplural(buf)); 1311. 1312. 	    if (killplayer) { 1313. 		/* might need to wipe out dual role */ 1314. 		int altx = Role_is('C') ? (PM_CAVEMAN + PM_CAVEWOMAN - mndx) : 1315. 			  Role_is('P') ? (PM_PRIEST + PM_PRIESTESS - mndx) : 1316. 			  0;  1317. 		if (altx) mvitals[altx].mvflags |= (G_GENOD | G_NOCORPSE); 1318. 1319. 		u.uhp = -1; 1320. 		killer_format = KILLED_BY_AN; 1321. 		killer = "genocidal confusion"; 1322. 1323. 	/* Polymorphed characters will die as soon as they're rehumanized. */ 1324. 		if (u.umonnum >= LOW_PM) You_feel("dead inside."); 1325. 		else 1326. 			done(GENOCIDED); 1327. 	   } else if (ptr == uasmon) { 1328. 		rehumanize; 1329. 	   }  1330. 	    reset_rndmonst(mndx); 1331. 	   kill_genocided_monsters; 1332. 	   update_inventory;	/* in case identified eggs were affected */ 1333. 	} else if (!(mons[mndx].geno & G_UNIQ) && 1334. 		   !(mvitals[mndx].mvflags & (G_GENOD | G_EXTINCT))) { 1335. 	   pline("Sent in some %s.", makeplural(buf)); 1336. 	   for (i = rn1(3, 4); i > 0; i--) { 1337. 		struct monst *mmon = makemon(ptr, u.ux, u.uy); 1338. 1339. 		if (mmon) discard_minvent(mmon); 1340. 		if (mvitals[mndx].mvflags & G_EXTINCT) 1341. 			break;	/* just made last one */ 1342. 	   }  1343. 	}  1344. }  1345.  1346. void 1347. punish(sobj) 1348. register struct obj	*sobj; 1349. { 1350. 	You("are being punished for your misbehavior!"); 1351. 	if(Punished){ 1352. 		Your("iron ball gets heavier."); 1353. 		uball->owt += 160 * (1 + sobj->cursed); 1354. 		return; 1355. 	} 1356. 	if (amorphous(uasmon) || is_whirly(uasmon) || unsolid(uasmon)) { 1357. 		pline("A ball and chain appears, then falls away."); 1358. 		dropy(mkobj(BALL_CLASS, TRUE)); 1359. 		return; 1360. 	} 1361. 	setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN); 1362. 	setworn(mkobj(BALL_CLASS, TRUE), W_BALL); 1363. 	uball->spe = 1;		/* special ball (see save) */ 1364. 1365. 	/*  1366. 	 *  Place ball & chain if not swallowed. If swallowed, the ball & 1367. 	 * chain variables will be set at the next call to placebc. 1368. 	 */ 1369. 	if (!u.uswallow) { 1370. 	   placebc; 1371. 	   if (Blind) set_bc(1);	/* set up ball and chain variables */ 1372. 	   newsym(u.ux,u.uy);		/* see ball&chain if can't see self */ 1373. 	} 1374. }  1375.  1376. void 1377. unpunish 1378. {	   /* remove the ball and chain */ 1379. 	struct obj *savechain = uchain; 1380. 1381. 	obj_extract_self(uchain); 1382. 	newsym(uchain->ox,uchain->oy); 1383. 	setworn((struct obj *)0, W_CHAIN); 1384. 	dealloc_obj(savechain); 1385. 	uball->spe = 0; 1386. 	setworn((struct obj *)0, W_BALL); 1387. } 1388.  1389. /* some creatures have special data structures that only make sense in their 1390. * normal locations -- if the player tries to create one elsewhere, or to revive 1391. * one, the disoriented creature becomes a zombie 1392. */  1393. boolean 1394. cant_create(mtype) 1395. int *mtype; 1396. { 1397.  1398. 	if (*mtype==PM_GUARD || *mtype==PM_SHOPKEEPER  1399. 	     || *mtype==PM_ALIGNED_PRIEST || *mtype==PM_ANGEL) { 1400. 		*mtype = PM_HUMAN_ZOMBIE; 1401. 		return TRUE; 1402. 	} else if (*mtype==PM_LONG_WORM_TAIL) {	/* for create_particular */ 1403. 		*mtype = PM_LONG_WORM; 1404. 		return TRUE; 1405. 	} 1406. 	return FALSE; 1407. } 1408.  1409. #ifdef WIZARD 1410. boolean 1411. create_particular 1412. { 1413. 	char buf[BUFSZ]; 1414. 	int which, tries = 0; 1415. 1416. 	do { 1417. 	   getlin("Create what kind of monster? [type the name]", buf); 1418. 	   if (buf[0] == '\033') return FALSE; 1419. 	   which = name_to_mon(buf); 1420. 	   if (which < LOW_PM) pline("I've never heard of such monsters."); 1421. 	   else break; 1422. 	} while (++tries < 5); 1423. 	if (tries == 5) pline(thats_enough_tries); 1424. 	else { 1425. 	   (void) cant_create(&which); 1426. 	   return((boolean)(makemon(&mons[which], u.ux, u.uy) != 0)); 1427. 	} 1428. 	return FALSE; 1429. } 1430. #endif /* WIZARD */ 1431. 1432. #endif /* OVLB */ 1433. 1434. /*read.c*/