Source:NetHack 3.0.0/read.c

From NetHackWiki
(Redirected from NetHack 3.0.0/read.c)
Jump to navigation Jump to search

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

The NetHack General Public License applies to screenshots, source code and other content from NetHack.

This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.

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