Source:NetHack 3.0.0/read.c

Below is the full text to read.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.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.0	88/04/13 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.   boolean	known; 8.    9.    static const char readable[] = { '#', SCROLL_SYM, 10.  #ifdef SPELLS 11.  	SPBOOK_SYM, 12.  #endif 13.  	0 };  14.    15.   static void explode P((struct obj *)); 16.  static void do_class_genocide; 17.   18.   int 19.  doread { 20.  	register struct obj *scroll; 21.  	register boolean confused = (Confusion != 0); 22.   23.   	known = FALSE; 24.  	scroll = getobj(readable, "read");	/* "#-" added by GAN 10/22/86 */ 25.  	if(!scroll) return(0); 26.   27.   	/* below added to allow reading of fortune cookies */ 28.  	if(scroll->otyp == FORTUNE_COOKIE) { 29.  	    if(flags.verbose) 30.  		You("break up the cookie and throw away the pieces."); 31.  	    outrumor(bcsign(scroll), TRUE); 32.  	    useup(scroll); 33.  	    return(1); 34.  	} else 35.  		if(scroll->olet != SCROLL_SYM  36.   #ifdef SPELLS  37.   		   && scroll->olet != SPBOOK_SYM  38.   #endif  39.   		  ) { 40.  			pline("That is a silly thing to read."); 41.  			return(0); 42.  		}  43.    44.   	if(Blind) 45.  #ifdef SPELLS 46.  	    if (scroll->olet == SPBOOK_SYM) { 47.  		pline("Being blind, you cannot read the mystic runes."); 48.  		return(0); 49.  	    } else 50.  #endif 51.  	    if (!scroll->dknown) { 52.  		pline("Being blind, you cannot read the formula on the scroll."); 53.  		return(0); 54.  	    }  55.   #ifdef SPELLS 56.  	if(scroll->olet == SPBOOK_SYM) { 57.  	    if(confused) { 58.  		You("cannot grasp the meaning of this tome."); 59.  		useup(scroll); 60.  		return(0); 61.  	    } else 62.  		return(study_book(scroll)); 63.  	}  64.   #endif 65.  	if(scroll->otyp != SCR_BLANK_PAPER) { 66.  	  if(Blind) 67.  	    pline("As you pronounce the formula on it, the scroll disappears."); 68.  	  else 69.  	    pline("As you read the scroll, it disappears."); 70.  	  if(confused) { 71.  	    if (Hallucination) 72.  		pline("Being so trippy, you screw up..."); 73.  	    else 74.  		pline("Being confused, you mispronounce the magic words..."); 75.  	  }  76.   	}  77.   	if(!seffects(scroll))  { 78.  		if(!objects[scroll->otyp].oc_name_known) { 79.  		    if(known && !confused) { 80.  			makeknown(scroll->otyp); 81.  			more_experienced(0,10); 82.  		    } else if(!objects[scroll->otyp].oc_uname) 83.  			docall(scroll); 84.  		}  85.   		if(!(scroll->otyp == SCR_BLANK_PAPER) || confused) 86.  			useup(scroll); 87.  	}  88.   	return(1); 89.  }  90.    91.   static void 92.  stripspe(obj) 93.  register struct obj *obj; 94.  {  95.   	if (obj->blessed) pline(nothing_happens); 96.  	else { 97.  		if (obj->spe > 0) { 98.  		    obj->spe = 0; 99.  		    Your("%s vibrates briefly.",xname(obj)); 100. 		} else pline(nothing_happens); 101. 	}  102.  }  103.   104.  static void 105. p_glow1(otmp) 106. register struct obj	*otmp; 107. {  108.  	Your("%s %s briefly.", xname(otmp),  109.  		Blind ? "vibrates" : "glows"); 110. }  111.   112.  static void 113. p_glow2(otmp,color) 114. register struct obj	*otmp; 115. register char *color; 116. {  117.  	Your("%s %s%s for a moment.",  118.  		xname(otmp),  119.  		Blind ? "vibrates" : "glows ",  120.  		Blind ? "" : Hallucination ? hcolor : color); 121. }  122.   123.  int 124. seffects(sobj) 125. register struct obj	*sobj; 126. {  127.  	register int cval = 0; 128. 	register boolean confused = (Confusion != 0); 129.  130.  	switch(sobj->otyp) { 131. #ifdef MAIL 132. 	case SCR_MAIL: 133. 		known = TRUE; 134. 		if (sobj->spe) 135. 		    pline("This seems to be junk mail addressed to the finder of the Eye of Larn."); 136. 		/* note to the puzzled: the game Larn actually sends you junk 137. 		 * mail if you win! 138. 		 */  139.  		else readmail(/* scroll */); 140. 		break; 141. #endif 142. 	case SCR_ENCHANT_ARMOR: 143. 	    {  144.  		register struct obj *otmp = some_armor; 145. 		register schar s = 0; 146. 		if(!otmp) { 147. 			strange_feeling(sobj,  148.  					!Blind ? "Your skin glows then fades." :  149.  					"Your skin feels warm for a moment."); 150. 			return(1); 151. 		}  152.  		if(confused) { 153. 			if(Blind) 154. 			    Your("%s feels warm for a moment.",  155.  				xname(otmp)); 156. 			else 157. 			    Your("%s is covered by a %s %s %s!",  158.  				xname(otmp),  159.  				sobj->cursed ? "mottled" : "shimmering",  160.  				Hallucination ? hcolor :  161.  				  sobj->cursed ? black : "gold",  162.  				sobj->cursed ? "glow" :  163.  				  (is_shield(otmp) ? "layer" : "shield")); 164. 			if(!(otmp->rustfree)) 165. 				otmp->rustfree = !(sobj->cursed); 166. 			break; 167. 		}  168.  #ifdef TOLKIEN 169. 		if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))  170.  #else  171.  		if((otmp->spe > 3) 172. #endif 173. 				&& rn2(otmp->spe) && !sobj->cursed) {  174.  		Your("%s violently %s%s for a while, then evaporates.", 175. 			    xname(otmp), 176. 			    Blind ? "vibrates" : "glows ", 177. 			    Blind ? "" : Hallucination ? hcolor : silver); 178.  			if(is_cloak(otmp)) (void) Cloak_off;  179.  			if(is_boots(otmp)) (void) Boots_off;  180.  			if(is_helmet(otmp)) (void) Helmet_off;  181.  			if(is_gloves(otmp)) (void) Gloves_off;  182.  			if(is_shield(otmp)) (void) Shield_off;  183.  			if(otmp == uarm) (void) Armor_gone;  184.  			useup(otmp);  185.  			break;  186.  		}  187.  		s = sobj->blessed ? rnd(3) : sobj->cursed ? -1 : 1;  188.  		Your("%s %s%s for a %s.", 189. 			xname(otmp), 190. 			Blind ? "vibrates" : "glows ", 191. 			Blind ? "" : Hallucination ? hcolor : 192. 			  sobj->cursed ? black : silver, 193. 			  (s*s>1) ? "while" : "moment"); 194.  		otmp->cursed = sobj->cursed;  195.  		otmp->blessed = sobj->blessed;  196.  		otmp->spe += s;  197.  		adj_abon(otmp, s);  198.  		break;  199.  	    }  200.  	case SCR_DESTROY_ARMOR:  201.  	    {   register struct obj *otmp = some_armor;  202.   203.  		if(confused) {  204.  			if(!otmp) {  205.  				strange_feeling(sobj,"Your bones itch.");  206.  				return(1);  207.  			}  208.  			p_glow2(otmp,purple);  209.  			otmp->rustfree = sobj->cursed;  210.  			break;  211.  		}  212.  		if(!sobj->cursed || (sobj->cursed && (!otmp || !otmp->cursed))) {  213.  		    if(!destroy_arm(otmp)) {  214.  			strange_feeling(sobj,"Your skin itches.");  215.  			return(1);  216.  		    }  217.  		} else {	/* armor and scroll both cursed */  218.  		    Your("%s vibrates", xname(otmp));  219.  		    otmp->spe--;  220.  		    make_stunned(HStun + rn1(10, 10), TRUE);  221. } 222.  	    }  223.  	    break; 224. 	case SCR_CONFUSE_MONSTER: 225. #ifdef SPELLS 226. 	case SPE_CONFUSE_MONSTER: 227. #endif 228. 		if(u.usym != S_HUMAN || sobj->cursed) { 229. 			if(!HConfusion) You("feel confused."); 230. 			make_confused(HConfusion + rnd(100),FALSE); 231. 		} else  if(confused) { 232. 		    if(!sobj->blessed) { 233. 			Your("%s begin to %s%s.",  234.  			    makeplural(body_part(HAND)),  235.  			    Blind ? "tingle" : "glow ",  236.  			    Blind ? "" : Hallucination ? hcolor : purple); 237. 			make_confused(HConfusion + rnd(100),FALSE); 238. 		    } else { 239. 			pline("A %s%s surrounds your %s.",  240.  			    Blind ? "" : Hallucination ? hcolor : red,  241.  			    Blind ? "faint buzz" : " glow",  242.  			    body_part(HEAD)); 243. 			make_confused(0L,TRUE); 244. 		    }  245.  		} else { 246. 			Your("%s%s %s.",  247.  			makeplural(body_part(HAND)),  248.  			Blind ? "" : " begin to glow",  249.  			Blind ? "tingle" : Hallucination ? hcolor : red); 250. 			u.umconf = 1; 251. 		}  252.  		break; 253. 	case SCR_SCARE_MONSTER: 254. #ifdef SPELLS 255. 	case SPE_CAUSE_FEAR: 256. #endif 257. 	    {	register int ct = 0; 258. 		register struct monst *mtmp; 259.  260.  		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) 261. 		    if(cansee(mtmp->mx,mtmp->my)) { 262. 			if(confused || sobj->cursed) 263. 			    mtmp->mflee = mtmp->mfroz = mtmp->msleep = 0; 264. 			else 265. 			    if (! resist(mtmp, sobj->olet, 0, NOTELL)) 266. 				mtmp->mflee = 1; 267. 			if(!mtmp->mtame) ct++;	/* pets don't laugh at you */ 268. 		    }  269.  		if(!ct) 270. 		      You("hear %s in the distance.",  271.  			       (confused || sobj->cursed) ? "sad wailing" :  272.  							"maniacal laughter"); 273. 		else 274. #ifdef SPELLS 275. 		     if(sobj->otyp == SCR_SCARE_MONSTER) 276. #endif 277. 			    You("hear %s close by.",  278.  				  (confused || sobj->cursed) ? "sad wailing" :  279.  						 "maniacal laughter"); 280. 		break; 281. 	    }  282.  	case SCR_BLANK_PAPER: 283. 		if(confused) 284. 		    You("try to read the strange patterns on this scroll, but it disappears."); 285. 		else  { 286. 		    pline("This scroll seems to be blank."); 287. 		    known = TRUE; 288. 		}  289.  		break; 290. 	case SCR_REMOVE_CURSE: 291. #ifdef SPELLS 292. 	case SPE_REMOVE_CURSE: 293. #endif 294. 	    {	register struct obj *obj; 295. 		if(confused) 296. 		    if (Hallucination) 297. 			You("feel the power of the Force against you!"); 298. 		    else 299. 			You("feel like you need some help."); 300. 		else 301. 		    if (Hallucination) 302. 			You("feel in touch with the Universal Oneness."); 303. 		    else 304. 			You("feel like someone is helping you."); 305.  306.  		if(sobj->cursed) pline("The scroll disintegrates."); 307. 		else { 308. 		    for(obj = invent; obj ; obj = obj->nobj) 309. 			if(sobj->blessed || obj->owornmask ||  310.  			   (obj->otyp == LOADSTONE)) { 311. 			    if(confused) blessorcurse(obj, 2); 312. 			    else obj->cursed = 0; 313. 			}  314.  		}  315.  		if(Punished && !confused) unpunish; 316. 		break; 317. 	    }  318.  	case SCR_CREATE_MONSTER: 319. #if defined(WIZARD) || defined(EXPLORE_MODE) 320. 	    if (wizard || discover) 321. 		known = TRUE; 322. #endif /* WIZARD || EXPLORE_MODE */ 323. #ifdef SPELLS 324. 	case SPE_CREATE_MONSTER: 325. #endif 326. 	    {	register int cnt = 1; 327.  328.  		if(!rn2(73)) cnt += rnd(4); 329. 		if(confused || sobj->cursed) cnt += 12; 330. 		while(cnt--) { 331. #if defined(WIZARD) || defined(EXPLORE_MODE) 332. 		    if(wizard || discover) 333. 			if (!create_particular) 334. #endif /* WIZARD || EXPLORE_MODE */ 335. 		    (void) makemon (confused ? &mons[PM_ACID_BLOB] :  336.  					(struct permonst *) 0, u.ux, u.uy); 337. 		}  338.  		break; 339. 	    }  340.  /*	    break;	/*NOTREACHED*/ 341. 	case SCR_ENCHANT_WEAPON: 342. 		if(uwep && (uwep->olet == WEAPON_SYM || uwep->olet == PICK_AXE)  343.  							&& confused) { 344. 		/* olet check added 10/25/86 GAN */ 345. 			if(Blind) 346. 			    Your("weapon feels warm for a moment."); 347. 			else 348. 			    Your("%s covered by a %s %s %s!",  349.  				aobjnam(uwep, "are"),  350.  				sobj->cursed ? "mottled" : "shimmering",  351.  				Hallucination ? hcolor :  352.  				  sobj->cursed ? purple : "gold",  353.  				sobj->cursed ? "glow" : "shield"); 354. 			uwep->rustfree = !(sobj->cursed); 355. 		} else return !chwepon(sobj, bcsign(sobj)*2+1); 356. 		break; 357. 	case SCR_TAMING: 358. #ifdef SPELLS 359. 	case SPE_CHARM_MONSTER: 360. #endif 361. 	    {	register int i,j; 362. 		register int bd = confused ? 5 : 1; 363.  		register struct monst *mtmp; 364.  365.  		for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++) 366. 		if(levl[u.ux+i][u.uy+j].mmask && (mtmp = m_at(u.ux+i, u.uy+j))) { 367. 		    if(sobj->cursed) { 368. 			if(!mtmp->mtame) mtmp->mpeaceful = 0; 369. 		    } else { 370. 			if (mtmp->isshk) { 371. 			    if (!mtmp->mpeaceful) { 372. 				kludge("%s calms down.", Monnam(mtmp)); 373. 				mtmp->mpeaceful = 1; 374. 			    }  375.  			} else if(!resist(mtmp, sobj->olet, 0, NOTELL)) 376. 			    (void) tamedog(mtmp, (struct obj *) 0); 377. 		    }  378.  		}  379.  		break; 380. 	    }  381.  	case SCR_GENOCIDE: 382. 		You("have found a scroll of genocide!"); 383. #ifdef SPELLS 384. 	case SPE_GENOCIDE: 385. #endif 386. 		known = TRUE; 387. 		if (sobj->blessed) do_class_genocide; 388. 		else do_genocide(!sobj->cursed | (2 * !!Confusion)); 389. 		break; 390. 	case SCR_LIGHT: 391. 		if(!Blind) known = TRUE; 392. 		litroom(!confused && !sobj->cursed); 393. 		break; 394. 	case SCR_TELEPORTATION: 395. 		if(confused || sobj->cursed) level_tele; 396. 		else { 397. 			register int uroom = inroom(u.ux, u.uy); 398.  399.  			if (sobj->blessed && !Teleport_control) { 400. 				known = TRUE; 401. 				pline("Do you wish to teleport? "); 402. 				if (yn=='n') break; 403. 			}  404.  			tele; 405. 			if(uroom != inroom(u.ux, u.uy)) known = TRUE; 406. 			if(Teleport_control) known = TRUE; 407. 		}  408.  		break; 409. 	case SCR_GOLD_DETECTION: 410. 		if (confused || sobj->cursed) return(trap_detect(sobj)); 411. 		else return(gold_detect(sobj)); 412. 	case SCR_FOOD_DETECTION: 413. #ifdef SPELLS 414. 	case SPE_DETECT_FOOD: 415. #endif 416. 		if (food_detect(sobj)) 417. 			return(1);	/* nothing detected */ 418. 		break; 419. 	case SCR_IDENTIFY: 420. 		/* known = TRUE; */ 421. 		if(confused) 422. 			You("identify this as an identify scroll."); 423. 		else 424. 			pline("This is an identify scroll."); 425. 		if (sobj->blessed || (!sobj->cursed && !rn2(5))) 426. 			cval = rn2(5); 427. 			/* Note: if rn2(5)==0, identify all items */ 428. 		else	cval = 1; 429. 		useup(sobj); 430. 		makeknown(SCR_IDENTIFY); 431. #ifdef SPELLS 432. 	case SPE_IDENTIFY: 433. #endif 434. 		if(!confused) 435. 		    while(invent && !ggetobj("identify", identify, cval)); 436. 		return(1); 437. 	case SCR_CHARGING: 438. 	    {	register struct obj *obj; 439. 		register int n;  440. if (confused) { 441. 		    You("feel charged up!"); 442. 		    break; 443. 		}  444.  		known = TRUE; 445. 		pline("This is a charging scroll."); 446. 		obj = getobj("0#", "charge"); 447. 		if (!obj) break; 448. 		if (obj->olet != WAND_SYM) { 449. 		    switch(obj->otyp) { 450. 		    case MAGIC_MARKER: 451. 			if (sobj->cursed) stripspe(obj); 452. 			else if (sobj->blessed) { 453. 			    n = obj->spe; 454. 			    if (n < 50) obj->spe = 50; 455. 			    if (n >= 50 && n < 75) obj->spe = 75; 456. 			    if (n >= 75) obj->spe += 10; 457. 			    p_glow2(obj,blue); 458. 			} else { 459. 			    if (obj->spe < 50) obj->spe = 50; 460. 			    else obj->spe++; 461. 			    p_glow2(obj,white); 462. 			}  463.  			break; 464. 		    case LAMP: 465. 			if (sobj->cursed) stripspe(obj); 466. 			else if (sobj->blessed) { 467. 			    n = rn2(11); 468. 			    if (obj->spe < n) obj->spe = n;  469. else obj->spe += rnd(3); 470. 			    p_glow2(obj,blue); 471. 			} else { 472. 			    obj->spe++; 473. 			    p_glow1(obj); 474. 			}  475.  			break; 476. 		    case MAGIC_LAMP: 477. 			if (sobj->cursed) stripspe(obj); 478. 			else if (sobj->blessed) { 479. 			    if (obj->spe == 1) pline(nothing_happens); 480. 			    else { 481. 				obj->spe = 1; 482. 				p_glow1(obj); 483. 			    }  484.  			} else { 485. 			    if (obj->spe == 1) pline(nothing_happens); 486. 			    else { 487. 				n = rn2(2); 488. 				if (!n) { 489. 				    obj->spe = 1; 490. 				    p_glow1(obj); 491. 				} else pline(nothing_happens); 492. 			    }  493.  			}  494.  			break; 495. 		    case CRYSTAL_BALL: 496. 			if (sobj->cursed) stripspe(obj); 497. 			else if (sobj->blessed) { 498. 			    obj->spe = 6; 499. 			    p_glow2(obj,blue); 500. 			} else { 501. 			    if (obj->spe < 5) { 502. 				obj->spe++; 503. 				p_glow1(obj); 504. 			    } else pline(nothing_happens); 505. 			}  506.  			break; 507. 		    case BAG_OF_TRICKS: 508. 			if (sobj->cursed) stripspe(obj); 509. 			else if (sobj->blessed) { 510. 			    if (obj->spe <= 10) 511. 				obj->spe += (5 + rnd(10)); 512. 			    else obj->spe += (5 + rnd(5)); 513. 			    p_glow2(obj,blue); 514. 			} else { 515. 			    obj->spe += rnd(5); 516. 			    p_glow1(obj); 517. 			}  518.  			break; 519. 		    default: 520. 			pline("The scroll %s%s, and disintegrates.",  521.  				Blind ? "vibrates violently" : "glows ",  522.  				Blind ? "" : Hallucination ? hcolor : "dark red"); 523. 		    } /* switch */ 524. 		    break; 525. 		}  526.  		else { 527. 		    if (obj->otyp == WAN_WISHING) { 528. 			if (obj->recharged) { /* recharged once already? */ 529.  			    explode(obj); 530. 			    break; 531. 			}  532.  			if (sobj->cursed) stripspe(obj); 533. 			else if (sobj->blessed) { 534. 			    if (obj->spe != 3) { 535. 				obj->spe = 3; 536. 				p_glow2(obj,blue); 537. 			    } else { 538. 				explode(obj); 539. 				break; 540. 			    }  541.  			} else { 542. 			    if (obj->spe < 3) { 543. 				obj->spe++; 544. 				p_glow2(obj,blue); 545. 			    } else pline(nothing_happens); 546. 			}  547.  			obj->recharged = 1; /* another recharging disallowed */ 548. 		    }  549.  		    else { 550. 			if (sobj->cursed) stripspe(obj); 551. 			else if (sobj->blessed) { 552. 			    if (objects[obj->otyp].bits & NODIR) { 553. 				n = rn1(5,11); 554. 				if (obj->spe < n) obj->spe = n;  555. else obj->spe++; 556. 			    }  557.  			    else { 558. 				n = rn1(5,4); 559. 				if (obj->spe < n) obj->spe = n;  560. else obj->spe++; 561. 			    }  562.  			    p_glow2(obj,blue); 563. 			} else { 564. 			    obj->spe++; 565. 			    p_glow1(obj); 566. 			}  567.  			break; 568. 		    }  569.  		}  570.  	    }  571.  		break; 572. 	case SCR_MAGIC_MAPPING: 573. 		known = TRUE; 574. 		pline("On this scroll %s a map.", confused ? "was" : "is"); 575. #ifdef SPELLS 576. 	case SPE_MAGIC_MAPPING: 577. #endif 578. 		cval = (sobj->cursed && !confused); 579. 		if(cval) HConfusion = 1;	/* to screw up map */ 580. 		do_mapping; 581. 		if(cval) { 582. 		    HConfusion = 0;		/* restore */ 583. 		    pline("Unfortunately, it is of a very poor quality."); 584. 		}  585.  		break; 586. 	case SCR_AMNESIA: 587. 	    {	register int zx, zy; 588.  589.  		known = TRUE; 590. 		for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++) 591. 		    if(!confused || sobj->cursed || rn2(7)) 592. 			if(!cansee(zx,zy)) 593. 			    levl[zx][zy].seen = levl[zx][zy].new = 594. 				levl[zx][zy].scrsym = 0; 595. 		docrt; 596. 		if (Hallucination) /* Ommmmmm! */ 597.  			Your("mind releases itself from mundane concerns."); 598. 		else if (!strncmp(plname, "Maud", 4)) 599. 			pline("As your mind turns inward on itself, you forget everything else."); 600. 		else if (flags.female) 601. 			pline("Who was that Maud person anyway?"); 602. 		else 603. 			pline("Thinking of Maud you forget everything else."); 604. #ifdef SPELLS 605. 		if(!sobj->blessed) losespells; 606. #endif 607. 		break; 608. 	    }  609.  	case SCR_FIRE: 610. 	    {	register int num; 611. 		register struct monst *mtmp; 612. /*  613.   * Note: Modifications have been made as of 3.0 to allow for some damage 614.  *	 under all potential cases. 615.  */  616.  		cval = bcsign(sobj); 617. 		useup(sobj); 618. 		makeknown(SCR_FIRE); 619. 		if(confused) { 620. 		    if(Fire_resistance) { 621.   			shieldeff(u.ux, u.uy); 622. 			if(!Blind) 623. 			    pline("Oh, look, what a pretty fire in your %s.",  624.  				makeplural(body_part(HAND))); 625. 			else You("feal a pleasant warmth in your %s.",  626.  				makeplural(body_part(HAND))); 627. 		    } else { 628. 			pline("The scroll catches fire and you burn your %s.",  629.  				makeplural(body_part(HAND))); 630. 			losehp(1, "scroll of fire"); 631. 		    }  632.  		    return(1); 633. 		}  634.  		pline("The scroll erupts in a tower of flame!"); 635. 		num = rnd(6) - 3 * cval; 636. 		if(num <= 0 || Fire_resistance) { 637. 			shieldeff(u.ux, u.uy); 638. 			You("are uninjured."); 639. 		} else { 640. 			u.uhpmax -= num; 641. 			losehp(num, "scroll of fire"); 642. 		}  643.  		destroy_item(SCROLL_SYM, AD_FIRE); 644. #ifdef SPELLS 645. 		destroy_item(SPBOOK_SYM, AD_FIRE); 646. #endif 647. 		destroy_item(POTION_SYM, AD_FIRE); 648.  649.  		num = (2*(rn1(3, 3) + 2 * cval) + 1)/3; 650. 		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { 651. 		    if(dist(mtmp->mx,mtmp->my) < 3) { 652. 			if (resists_fire(mtmp->data)) continue; 653. 			if (u.uswallow) { 654. 			    if (mtmp != u.ustuck) continue; 655. 			    pline("%s gets heartburn.", Monnam(u.ustuck)); 656. 			    num *= 2; 657. 			}  658.  			mtmp->mhp -= num;		/* No saving throw! */ 659.  			if(resists_cold(mtmp->data)) 660. 			    mtmp->mhp -= 3*num; 661. 			if(mtmp->mhp < 1) { 662. 			    killed(mtmp); 663. 			    break;		/* primitive */ 664. 			}  665.  		    }  666.  		}  667.  		return(1); 668. 	    }  669.  	case SCR_PUNISHMENT: 670. 		known = TRUE; 671. 		if(confused || sobj->blessed) { 672. 			You("feel guilty."); 673. 			break; 674. 		}  675.  		punish(sobj); 676. 		break; 677. 	default: 678. 		impossible("What weird effect is this? (%u)", sobj->otyp); 679. 	}  680.  	return(0); 681. }  682.   683.  static void 684. explode(obj) 685. register struct obj *obj; 686. {  687.      Your("%s vibrates violently, and explodes!",xname(obj)); 688.     bell; 689.     losehp(rn2(2*(u.uhpmax+1)/3),"exploding wand"); 690.     useup(obj); 691. }  692.   693.  int 694. identify(otmp)		/* also called by newmail */ 695. 	register struct obj *otmp; 696. {  697.  	makeknown(otmp->otyp); 698. 	otmp->known = otmp->dknown = otmp->bknown = 1; 699. 	prinv(otmp); 700. 	return(1); 701. }  702.   703.  void 704. litroom(on) 705. register boolean on; 706. {  707.  	register int zx,zy; 708.  709.  	/* first produce the text (provided he is not blind) */ 710. 	if(Blind) goto do_it; 711. 	if(!on) { 712. 		if(u.uswallow || is_maze_lev || levl[u.ux][u.uy].typ == CORR ||  713.  		    !levl[u.ux][u.uy].lit) { 714. 			pline("It seems even darker in here than before."); 715. 			return; 716. 		} else 717. 			pline("It suddenly becomes dark in here."); 718. 	} else { 719. 		if(u.uswallow){ 720. 			pline("%s's stomach is lit.", Monnam(u.ustuck)); 721. 			return; 722. 		}  723.  		if(is_maze_lev){ 724. 			pline(nothing_happens); 725. 			return; 726. 		}  727.  		if(levl[u.ux][u.uy].typ == CORR) { 728. 		    pline("The corridor lights up around you, then fades."); 729. 		    return; 730. 		} else if(levl[u.ux][u.uy].lit) { 731. 		    pline("The light here seems better now."); 732. 		    return; 733. 		} else 734. 		    pline("The room is lit."); 735. 	}  736.   737.  do_it: 738. 	if(levl[u.ux][u.uy].lit == on) 739. 		return; 740. 	if (inroom(u.ux,u.uy) < 0) 741. 		return; 742. 	getcorners(&seelx,&seehx,&seely,&seehy,&seelx2,&seehx2,&seely2,&seehy2); 743.  744.  	for(zy = seely; zy <= seehy; zy++) 745. 		for(zx = seelx; zx <= seehx; zx++) { 746. 			levl[zx][zy].lit = on; 747. 			if(!Blind && dist(zx,zy) > 2) 748. 				if(on) prl(zx,zy); else nosee(zx,zy); 749. 		}  750.  	for(zy = seely2; zy <= seehy2; zy++) 751. 		for(zx = seelx2; zx <= seehx2; zx++) { 752. 			levl[zx][zy].lit = on; 753. 			if(!Blind && dist(zx,zy) > 2) 754. 				if(on) prl(zx,zy); else nosee(zx,zy); 755. 		}  756.  	if(!on) seehx = 0; 757. }  758.   759.  static void 760. do_class_genocide 761. {  762.  	register int i, j, immunecnt, gonecnt, goodcnt; 763. 	char buf[BUFSZ]; 764.  765.  	for(j=0; ; j++) { 766. 		if (j >= 5) { 767. 			pline(thats_enough_tries); 768. 			return; 769. 		}  770.      pline("What class of monsters do you wish to genocide? [type a letter] "); 771. 		do { 772. 			getlin(buf); 773. 		} while (buf[0]=='\033' || strlen(buf) != 1); 774. 		immunecnt = gonecnt = goodcnt = 0; 775. 		for(i=0; mons[i].mlet; i++) { 776. 			if(mons[i].mlet == buf[0]) { 777. 				if (!(mons[i].geno & G_GENO)) immunecnt++; 778. 				else if(mons[i].geno & G_GENOD) gonecnt++; 779. 				else goodcnt++; 780. 			}  781.  		}  782.  		if (!goodcnt && buf[0] != S_HUMAN) { 783. 			if (gonecnt) 784. 	pline("All such monsters are already nonexistent."); 785. 			else if (immunecnt) 786. 	You("aren't permitted to genocide such monsters."); 787. 			else 788. 	pline("That symbol does not represent any monster."); 789. 			continue; 790. 		}  791.  		for(i=0; mons[i].mlet; i++) { 792. 		    if(mons[i].mlet == buf[0]) { 793. 			register struct monst *mtmp, *mtmp2; 794. 			char *n = makeplural(mons[i].mname); 795.  796.  			if (&mons[i]==player_mon || ((mons[i].geno & G_GENO) 797. 				&& !(mons[i].geno & G_GENOD))) { 798. 			/* This check must be first since player monsters might 799. 			 * have G_GENOD or !G_GENO. 800. 			 */  801.  			    pline("Wiped out all %s.", n); 802. 			    if (&mons[i] == player_mon) { 803. 				u.uhp = -1; 804. 				killer = "scroll of genocide"; 805. #ifdef POLYSELF 806. 				if (u.umonnum >= 0) 807. 				    You("feel dead inside."); 808. 				else 809. #endif 810. 				    done("died"); 811. 			    }  812.  			    /* for simplicity (and fairness) let's avoid 813. 			     * alignment changes here...  814. */ 815.  #ifdef POLYSELF 816. 			    if (i==u.umonnum) rehumanize; 817. #endif 818. 			    mons[i].geno |= G_GENOD; 819. 			    for(mtmp = fmon; mtmp; mtmp = mtmp2) { 820. 				mtmp2 = mtmp->nmon; 821. 				if(mtmp->data == &mons[i]) 822. 				    mondead(mtmp); 823. 			    }  824.  			} else if (mons[i].geno & G_GENOD) 825. 			    pline("All %s are already nonexistent.", n); 826. 			else 827. 			    You("aren't permitted to genocide %s%s.",  828.  				i == PM_WIZARD_OF_YENDOR ? "the " : "",  829.  				type_is_pname(&mons[i]) ? mons[i].mname : n); 830. 			}  831.  		}  832.  		return; 833. 	}  834.  }  835.  		  836.  #define REALLY 1 837. #define PLAYER 2 838. void 839. do_genocide(how) 840. int how; 841. /* 0 = no genocide; create monsters (cursed scroll) */ 842. /* 1 = normal genocide */ 843. /* 3 = forced genocide of player */ 844. {  845.  	char buf[BUFSZ]; 846. 	register int	i, j, killplayer = 0; 847. 	register struct permonst *ptr; 848. 	register struct monst *mtmp, *mtmp2; 849.  850.  	if (how & PLAYER) { 851. 		ptr = player_mon; 852. 		Strcpy(buf, ptr->mname); 853. 		killplayer++; 854. 	} else { 855. 	    for(j = 0; ; j++) { 856. 		if(j >= 5) { 857. 		    pline(thats_enough_tries); 858. 		    return; 859. 		}  860.  		pline("What monster do you want to genocide? [type the name] "); 861. 		getlin(buf); 862.  863.  		if(strlen(buf) && (!strncmp(buf, pl_character, PL_CSIZ))) { 864. 	/* Note: pl_character starts with capitals and player_mon does not */ 865. 		    ptr = player_mon; 866. 		    killplayer++; 867. 		    goto deadmeat; 868. 		} else { 869. 		    i = name_to_mon(buf); 870. 		    if(i == -1 || (mons[i].geno & G_GENOD)) { 871. 			pline("Such creatures do not exist in this world."); 872. 			continue; 873. 		    }  874.  		    ptr = &mons[i]; 875. 		    if (ptr == player_mon) { 876. 			killplayer++; 877. 			goto deadmeat; 878. 		    }  879.  		    if (is_human(ptr)) adjalign(-sgn(u.ualigntyp)); 880. 		    if (is_demon(ptr)) adjalign(sgn(u.ualigntyp)); 881.  882.  		    if(!(ptr->geno & G_GENO))  { 883. 			if(flags.soundok) { 884. 			    if(flags.verbose) 885. 			pline("A thunderous voice booms though the caverns:"); 886. 			    pline("\"No, mortal!  That will not be done.\""); 887. 			}  888.  			continue; 889. 		    }  890.  		    break; 891. 		}  892.  	    }  893.  	}  894.  deadmeat: 895. 	if (Hallucination) { 896. #ifdef POLYSELF 897. 	    if (u.umonnum != -1) 898. 		Strcpy(buf,uasmon->mname); 899. 	    else 900. #endif 901. 	    {  902.  		Strcpy(buf, pl_character); 903. 		buf[0] += 'a' - 'A'; 904. 	    }  905.  	} else Strcpy(buf,ptr->mname); /* make sure we have standard singular */ 906. 	if (how & REALLY) { 907. 	    pline("Wiped out all %s.", makeplural(buf)); 908. 	    if(killplayer) { 909. 		u.uhp = -1; 910. 		killer = "genocide spell"; 911. #ifdef POLYSELF 912. 	/* A polymorphed character will die as soon as he is rehumanized. */ 913.  		if(u.umonnum >= 0)	You("feel dead inside."); 914. 		else 915. #endif 916. 			done("died"); 917. 		return; 918. 	    }  919.  #ifdef POLYSELF 920. 	    else if ((how & REALLY) && ptr == &mons[u.umonnum]) rehumanize; 921. #endif 922. 	    ptr->geno |= G_GENOD; 923. 	    for(mtmp = fmon; mtmp; mtmp = mtmp2) { 924. 		mtmp2 = mtmp->nmon; 925. 		if(mtmp->data == ptr) 926. 		    mondead(mtmp); 927. 	    }  928.  	} else { 929. 	    pline("Sent in some %s.", makeplural(buf)); 930. 	    j = rnd(3) + 3; 931. 	    for(i=1; i<=j; i++) 932. 		(void) makemon(ptr, u.ux, u.uy); 933. 	}  934.  }  935.   936.  static void 937. show_map_spot(x, y)  938. register int x, y; 939. { 940.  	register struct rm *lev; 941. 	register int num; 942.  943.  	if((Confusion != 0) && rn2(7)) return; 944. 	lev = &(levl[x][y]); 945. 	if((num = lev->typ) == 0) return; 946.  947.  	if(num == SCORR) { 948. 		lev->typ = CORR; 949. 		lev->scrsym = CORR_SYM; 950. 	/*  951.  	 * magic mapping shouldn't find secret doors, 952. 	 * especially on the stronghold level 953. 	 */  954.  	} else if(lev->seen) return; 955. 	if(num != ROOM) 956. 	{  957.  		lev->seen = lev->new = 1; 958. 		if(lev->scrsym == STONE_SYM || !lev->scrsym) 959. 			newsym(x, y); 960. 		else	on_scr(x, y); 961. 	}  962.  }  963.   964.  void 965. do_mapping { 966. 	register int zx, zy; 967.  968.  	for(zy = 0; zy < ROWNO; zy++) 969. 	    for(zx = 0; zx < COLNO; zx++) 970. 		show_map_spot(zx, zy); 971. }  972.   973.  void 974. do_vicinity_map { 975. 	register int zx, zy; 976. 	  977.  	for(zy = (u.uy-5 < 0 ? 0 : u.uy-5); 978.  			zy < (u.uy+6 > ROWNO ? ROWNO : u.uy+6); zy++) 979. 	    for(zx = (u.ux-9 < 0 ? 0 : u.ux-9); 980.  			zx < (u.ux+10 > COLNO ? COLNO : u.ux+10); zx++) 981. 		show_map_spot(zx, zy); 982. }  983.   984.  int 985. destroy_arm(atmp) 986. register struct obj *atmp; 987. {  988.  	register struct obj *otmp; 989.  990.  	if((otmp = uarmc) && (!atmp || atmp == uarmc)) { 991. 		Your("cloak crumbles and turns to dust!"); 992. 		(void) Cloak_off; 993. 		useup(otmp); 994. 	} else if((otmp = uarm) && (!atmp || atmp == uarm)) { 995. 		Your("armor turns to dust and falls to the floor!"); 996. 		(void) Armor_gone; 997. 		useup(otmp); 998. #ifdef SHIRT 999. 	} else if((otmp = uarmu) && (!atmp || atmp == uarmu)) { 1000. 		Your("shirt crumbles into tiny threads and falls apart!"); 1001. 		useup(otmp); 1002. #endif 1003. 	} else if((otmp = uarmh) && (!atmp || atmp == uarmh)) { 1004. 		Your("helmet turns to dust and is blown away!"); 1005. 		(void) Helmet_off; 1006. 		useup(otmp); 1007. 	} else if((otmp = uarmg) && (!atmp || atmp == uarmg)) { 1008. 		Your("gloves vanish!"); 1009. 		(void) Gloves_off; 1010. 		useup(otmp); 1011. 		selftouch("You"); 1012. 	} else if((otmp = uarmf) && (!atmp || atmp == uarmf)) { 1013. 		Your("boots disintegrate!"); 1014. 		(void) Boots_off; 1015. 		useup(otmp); 1016. 	} else if((otmp =uarms) && (!atmp || atmp == uarms)) { 1017. 		Your("shield crumbles away!"); 1018. 		(void) Shield_off; 1019. 		useup(otmp); 1020. 	} else 	return(0);		/* could not destroy anything */ 1021. 1022. 	return(1); 1023. } 1024.  1025. /* the detections are pulled out so they can	*/ 1026. /* also be used in the crystal ball routine	*/ 1027. /* returns 1 if nothing was detected		*/ 1028. /* returns 0 if something was detected		*/ 1029. int 1030. trap_detect(sobj) 1031. register struct obj	*sobj; 1032. /* sobj is null if crystal ball, *scroll if gold detection scroll */ 1033. { 1034. 	register struct trap *ttmp; 1035. 	register struct obj *obj; 1036. 	register int door; 1037. 	boolean found = FALSE; 1038. 	coord cc; 1039. 1040. 	for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) { 1041. 		if(ttmp->tx != u.ux || ttmp->ty != u.uy) 1042. 			goto outtrapmap; 1043. 		else found = TRUE; 1044. 	} 1045. 	for(obj = fobj; obj; obj = obj->nobj) { 1046. 		if ((obj->otyp==LARGE_BOX || obj->otyp==CHEST) && obj->otrapped) 1047. 			if (obj->ox != u.ux || obj->oy != u.uy) 1048. 				goto outtrapmap; 1049. 			else found = TRUE; 1050. 	} 1051. 	for(door=0; door<=doorindex; door++) { 1052. 		cc = doors[door]; 1053. 		if (levl[cc.x][cc.y].doormask & D_TRAPPED) 1054. 			if (cc.x != u.ux || cc.x != u.uy) 1055. 				goto outtrapmap; 1056. 			else found = TRUE; 1057. 	} 1058. 	if(!found) { 1059. 		char buf[42]; 1060. 		Sprintf(buf, "Your %s stop itching.", 1061. 			makeplural(body_part(TOE))); 1062. 		strange_feeling(sobj,buf); 1063. 		return(1); 1064. 	} 1065. 	/* traps exist, but only under me - no separate display required */ 1066. 	Your("%s itch.", makeplural(body_part(TOE))); 1067. 	return(0); 1068. outtrapmap: 1069. 	cls; 1070. #define SYMBOL (uchar)(Hallucination ? rndobjsym : \ 1071. 		(sobj && sobj->cursed) ? GOLD_SYM : TRAP_SYM) 1072. #define AT Hallucination || (sobj && sobj->cursed) ? AT_OBJ : AT_MAP 1073. 	for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) 1074. 		at(ttmp->tx, ttmp->ty, SYMBOL, AT); 1075. 	for(obj = fobj; obj; obj = obj->nobj) { 1076. 		if ((obj->otyp==LARGE_BOX || obj->otyp==CHEST) && obj->otrapped) 1077. 			at(obj->ox, obj->oy, SYMBOL, AT); 1078. 	} 1079. 	for(door=0; door<=doorindex; door++) { 1080. 		cc = doors[door]; 1081. 		if (levl[cc.x][cc.y].doormask & D_TRAPPED) 1082. 			at(cc.x, cc.y, SYMBOL, AT); 1083. 	} 1084. #undef SYMBOL 1085. #undef AT 1086. prme; 1087. 	if (sobj && sobj->cursed) 1088. 		You("feel very greedy."); 1089. 	else 1090. 		You("feel entrapped."); 1091. 	more; 1092. 	docrt; 1093. 	return(0); 1094. } 1095.  1096. int 1097. gold_detect(sobj) 1098. register struct obj	*sobj; 1099. { 1100. 	register struct gold *gtmp; 1101. 1102. 	if(!fgold) { 1103. 		if(sobj) 1104. 		   strange_feeling(sobj, "You feel materially poor."); 1105. 		return(1); 1106. 	} else { 1107. 		known = TRUE; 1108. 		for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) 1109. 			if(gtmp->gx != u.ux || gtmp->gy != u.uy) 1110. 				goto outgoldmap; 1111. 		/* only under me - no separate display required */ 1112. 		You("notice some gold between your %s.", 1113. 			makeplural(body_part(FOOT))); 1114. 		return(0); 1115. 	outgoldmap: 1116. 		cls; 1117. 		for(gtmp = fgold; gtmp; gtmp = gtmp->ngold) 1118. 		   at( gtmp->gx, gtmp->gy,  1119. 			(uchar)(Hallucination ? rndobjsym : GOLD_SYM), 1120. 			AT_OBJ); 1121. 		prme; 1122. 		You("feel very greedy, and sense gold!"); 1123. 		more; 1124. 		docrt; 1125. 	} 1126. 	return(0); 1127. } 1128.  1129. /* food_detection is pulled out so that it 	*/ 1130. /* can also be used in the crystal ball routine	*/ 1131. /* returns 1 if nothing was detected		*/ 1132. /* returns 0 if something was detected		*/ 1133. int 1134. food_detect(sobj) 1135. register struct obj	*sobj; 1136. { 1137. 	register boolean confused = (Confusion || (sobj && sobj->cursed)); 1138. 	register int ct = 0, ctu = 0; 1139. 	register struct obj *obj; 1140. 	register char foodsym = confused ? POTION_SYM : FOOD_SYM; 1141. 1142. 	for(obj = fobj; obj; obj = obj->nobj) 1143. 		if(obj->olet == foodsym) { 1144. 			if(obj->ox == u.ux && obj->oy == u.uy) ctu++; 1145. 			else ct++; 1146. 		} 1147. 	if(!ct && !ctu) { 1148. 		if (sobj) strange_feeling(sobj,"Your nose twitches."); 1149. 		return(1); 1150. 	} else if(!ct) { 1151. 		known = TRUE; 1152. 		You("%s %s close nearby.", sobj ? "smell" : "sense", 1153. 			confused ? "something" : "food"); 1154. 	} else { 1155. 		known = TRUE; 1156. 		cls; 1157. 		for(obj = fobj; obj; obj = obj->nobj) 1158. 		   if(obj->olet == foodsym) 1159. 			at(obj->ox, obj->oy, 1160. 			   (uchar)(Hallucination ? rndobjsym : FOOD_SYM), 1161. 			   AT_OBJ); 1162. 		prme; 1163. 		if (sobj) Your("nose tingles and you smell %s.", 1164. 				confused ? "something" : "food"); 1165. 		else You("sense %s.", confused ? "something" : "food"); 1166. 		more; 1167. 		docrt; 1168. 	} 1169. 	return(0); 1170. } 1171.  1172. void 1173. punish(sobj) 1174. register struct obj	*sobj; 1175. { 1176. 	You("are being punished for your misbehavior!"); 1177. 	if(Punished){ 1178. 		Your("iron ball gets heavier."); 1179. 		uball->owt += 15 * (1 + sobj->cursed); 1180. 		return; 1181. 	} 1182. 	setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN); 1183. 	setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL); 1184. 	uball->spe = 1;		/* special ball (see save) */ 1185. } 1186.  1187. void 1188. unpunish 1189. {	   /* remove the ball and chain */ 1190. 	freeobj(uchain); 1191. 	unpobj(uchain); 1192. 	free((genericptr_t) uchain); 1193. 	setworn((struct obj *)0, W_CHAIN); 1194. 	uball->spe = 0; 1195. 	setworn((struct obj *)0, W_BALL); 1196. } 1197.  1198. /* some creatures have special data structures that only make sense in their 1199. * normal locations -- if the player tries to create one elsewhere, or to revive 1200. * one, the disoriented creature becomes a zombie 1201. */  1202. boolean 1203. cant_create(mtype) 1204. int *mtype; 1205. { 1206.  1207. 	if (*mtype==PM_GUARD || *mtype==PM_SHOPKEEPER  1208. #if defined(ALTARS) && defined(THEOLOGY)  1209. 	     || *mtype==PM_TEMPLE_PRIEST || *mtype==PM_TEMPLE_PRIESTESS  1210. #endif  1211. 								) { 1212. 		*mtype = PM_HUMAN_ZOMBIE; 1213. 		return TRUE; 1214. 	} else 1215. 		return FALSE; 1216. } 1217.  1218. #if defined(WIZARD) || defined(EXPLORE_MODE) 1219. boolean 1220. create_particular 1221. { 1222. 	char buf[BUFSZ]; 1223. 	int which; 1224. 1225. 	do { 1226. 	   pline("Create what kind of monster? [type the name] "); 1227. 	   getlin(buf); 1228. 	} while(strlen(buf) < 1); 1229. 	which = name_to_mon(buf); 1230. 	if (which != -1) { 1231. 	   if (!(mons[which].geno & G_GENOD) && cant_create(&which) &&  1232. 								!Blind) { 1233. 		if (mons[which].geno & G_GENOD) 1234. pline("An image of the creature forms, wavers momentarily, then fades."); 1235. 		else 1236. pline("The disoriented creature's eyes slowly glaze over."); 1237. 	   }  1238. 	    (void) makemon(&mons[which], u.ux, u.uy); 1239. 	   return TRUE; 1240. 	} 1241. 	return FALSE; 1242. } 1243. #endif /* WIZARD || EXPLORE_MODE */