Source:NetHack 3.1.0/read.c

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

Below is the full text to read.c from the source code of NetHack 3.1.0. To link to a particular line, write [[NetHack 3.1.0/read.c#line123]], for example.

Warning! This is the source code from an old release. For the latest release, see Source code

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.1	92/12/10	*/
2.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
3.    /* NetHack may be freely redistributed.  See license for details. */
4.    
5.    #include "hack.h"
6.    
7.    /* elven armor vibrates warningly when enchanted beyond a limit */
8.    #define is_elven_armor(optr)	((optr)->otyp == ELVEN_LEATHER_HELM\
9.    				|| (optr)->otyp == ELVEN_MITHRIL_COAT\
10.   				|| (optr)->otyp == ELVEN_CLOAK\
11.   				|| (optr)->otyp == ELVEN_SHIELD\
12.   				|| (optr)->otyp == ELVEN_BOOTS)
13.   
14.   #ifdef OVLB
15.   
16.   boolean	known;
17.   
18.   static const char NEARDATA readable[] =
19.   		   { ALL_CLASSES, SCROLL_CLASS, SPBOOK_CLASS, 0 };
20.   static const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 };
21.   
22.   static void FDECL(wand_explode, (struct obj *));
23.   static void NDECL(do_class_genocide);
24.   static void FDECL(stripspe,(struct obj *));
25.   static void FDECL(p_glow1,(struct obj *));
26.   static void FDECL(p_glow2,(struct obj *,const char *));
27.   static void FDECL(forget,(BOOLEAN_P));
28.   
29.   #endif /* OVLB */
30.   
31.   #ifndef OVERLAY
32.   STATIC_DCL void FDECL(set_lit, (int,int,genericptr_t));
33.   #endif
34.   
35.   #ifdef OVLB
36.   
37.   int
38.   doread()
39.   {
40.   	register struct obj *scroll;
41.   	register boolean confused;
42.   
43.   	known = FALSE;
44.   	if(check_capacity(NULL)) return (0);
45.   	scroll = getobj(readable, "read");
46.   	if(!scroll) return(0);
47.   
48.   	/* outrumor has its own blindness check */
49.   	if(scroll->otyp == FORTUNE_COOKIE) {
50.   	    if(flags.verbose)
51.   		You("break up the cookie and throw away the pieces.");
52.   	    outrumor(bcsign(scroll), TRUE);
53.   	    useup(scroll);
54.   	    return(1);
55.   	} else if (scroll->oclass != SCROLL_CLASS
56.   		&& scroll->oclass != SPBOOK_CLASS) {
57.   	    pline(silly_thing_to, "read");
58.   	    return(0);
59.   	} else if (Blind) {
60.   	    const char *what = 0;
61.   	    if (scroll->oclass == SPBOOK_CLASS)
62.   		what = "mystic runes";
63.   	    else if (!scroll->dknown)
64.   		what = "formula on the scroll";
65.   	    if (what) {
66.   		pline("Being blind, you cannot read the %s.", what);
67.   		return(0);
68.   	    }
69.   	}
70.   
71.   	confused = (Confusion != 0);
72.   	if(scroll->oclass == SPBOOK_CLASS) {
73.   	    if(confused) {
74.   		You("cannot grasp the meaning of this tome.");
75.   		return(0);
76.   	    } else
77.   		return(study_book(scroll));
78.   	}
79.   #ifndef NO_SIGNAL
80.   	scroll->in_use = TRUE;	/* scroll, not spellbook, now being read */
81.   #endif
82.   	if(scroll->otyp != SCR_BLANK_PAPER) {
83.   	  if(Blind)
84.   	    pline("As you pronounce the formula on it, the scroll disappears.");
85.   	  else
86.   	    pline("As you read the scroll, it disappears.");
87.   	  if(confused) {
88.   	    if (Hallucination)
89.   		pline("Being so trippy, you screw up....");
90.   	    else
91.   		pline("Being confused, you mispronounce the magic words....");
92.   	  }
93.   	}
94.   	if(!seffects(scroll))  {
95.   		if(!objects[scroll->otyp].oc_name_known) {
96.   		    if(known) {
97.   			makeknown(scroll->otyp);
98.   			more_experienced(0,10);
99.   		    } else if(!objects[scroll->otyp].oc_uname)
100.  			docall(scroll);
101.  		}
102.  		if(scroll->otyp != SCR_BLANK_PAPER)
103.  			useup(scroll);
104.  #ifndef NO_SIGNAL
105.  		else scroll->in_use = FALSE;
106.  #endif
107.  	}
108.  	return(1);
109.  }
110.  
111.  static void
112.  stripspe(obj)
113.  register struct obj *obj;
114.  {
115.  	if (obj->blessed) pline(nothing_happens);
116.  	else {
117.  		if (obj->spe > 0) {
118.  		    obj->spe = 0;
119.  		    if (obj->otyp == OIL_LAMP || obj->otyp == BRASS_LANTERN)
120.  			obj->age = 0;
121.  		    Your("%s vibrates briefly.",xname(obj));
122.  		} else pline(nothing_happens);
123.  	}
124.  }
125.  
126.  static void
127.  p_glow1(otmp)
128.  register struct obj	*otmp;
129.  {
130.  	Your("%s %s briefly.", xname(otmp),
131.  		Blind ? "vibrates" : "glows");
132.  }
133.  
134.  static void
135.  p_glow2(otmp,color)
136.  register struct obj	*otmp;
137.  register const char *color;
138.  {
139.  	Your("%s %s%s for a moment.",
140.  		xname(otmp),
141.  		Blind ? "vibrates" : "glows ",
142.  		Blind ? (const char *)"" : Hallucination ? hcolor() : color);
143.  }
144.  
145.  /*
146.   * recharge an object; curse_bless is -1 if the recharging implement
147.   * was cursed, +1 if blessed, 0 otherwise.
148.   */
149.  void
150.  recharge(obj, curse_bless)
151.  struct obj *obj;
152.  int curse_bless;
153.  {
154.  	register int n;
155.  	boolean is_cursed, is_blessed;
156.  
157.  	is_cursed = curse_bless < 0;
158.  	is_blessed = curse_bless > 0;
159.  
160.  	if (obj->oclass == WAND_CLASS) {
161.  	    if (obj->otyp == WAN_WISHING) {
162.  		if (obj->recharged) {	/* recharged once already? */
163.  		    wand_explode(obj);
164.  		    return;
165.  		}
166.  		if (is_cursed) stripspe(obj);
167.  		else if (is_blessed) {
168.  		    if (obj->spe != 3) {
169.  			obj->spe = 3;
170.  			p_glow2(obj,blue);
171.  		    } else {
172.  			wand_explode(obj);
173.  			return;
174.  		    }
175.  		} else {
176.  		    if (obj->spe < 3) {
177.  			obj->spe++;
178.  			p_glow2(obj,blue);
179.  		    } else pline(nothing_happens);
180.  		}
181.  		obj->recharged = 1; /* another recharging disallowed */
182.  	    } else {
183.  		if (is_cursed) stripspe(obj);
184.  		else if (is_blessed) {
185.  		    if (objects[obj->otyp].oc_dir == NODIR) {
186.  			n = rn1(5,11);
187.  			if (obj->spe < n) obj->spe = n;
188.  			else obj->spe++;
189.  		    } else {
190.  			n = rn1(5,4);
191.  			if (obj->spe < n) obj->spe = n;
192.  			else obj->spe++;
193.  		    }
194.  		    p_glow2(obj,blue);
195.  		} else {
196.  		    obj->spe++;
197.  		    p_glow1(obj);
198.  		}
199.  	    }
200.  	} else if (obj->oclass == RING_CLASS &&
201.  					objects[obj->otyp].oc_charged) {
202.  	    /* charging does not affect ring's curse/bless status */
203.  	    int s = is_blessed ? rnd(3) : is_cursed ? -rnd(2) : 1;
204.  	    boolean is_on = (obj == uleft || obj == uright);
205.  
206.  	    /* destruction depends on current state, not adjustment */
207.  	    if (obj->spe > rn2(7) || obj->spe <= -5) {
208.  		Your("%s pulsates momentarily, then explodes!",
209.  		     xname(obj));
210.  		if (is_on) Ring_gone(obj);
211.  		s = rnd(3 * abs(obj->spe));	/* amount of damage */
212.  		useup(obj);
213.  		losehp(s, "exploding ring", KILLED_BY_AN);
214.  	    } else {
215.  		long mask = is_on ? (obj == uleft ? LEFT_RING :
216.  				     RIGHT_RING) : 0L;
217.  		Your("%s spins %sclockwise for a moment.",
218.  		     xname(obj), s < 0 ? "counter" : "");
219.  		/* cause attributes and/or properties to be updated */
220.  		if (is_on) Ring_off(obj);
221.  		obj->spe += s;	/* update the ring while it's off */
222.  		if (is_on) setworn(obj, mask), Ring_on(obj);
223.  		/* oartifact: if a touch-sensitive artifact ring is
224.  		   ever created the above will need to be revised  */
225.  	    }
226.  	} else {
227.  	    switch(obj->otyp) {
228.  	    case MAGIC_MARKER:
229.  		if (is_cursed) stripspe(obj);
230.  		else if (obj->recharged) {
231.  		    if (obj->spe < 3)
232.  			Your("marker seems permanently dried out.");
233.  		    else
234.  			pline(nothing_happens);
235.  		} else if (is_blessed) {
236.  		    n = obj->spe;
237.  		    if (n < 50) obj->spe = 50;
238.  		    if (n >= 50 && n < 75) obj->spe = 75;
239.  		    if (n >= 75) obj->spe += 10;
240.  		    p_glow2(obj,blue);
241.  		    obj->recharged = 1;
242.  		} else {
243.  		    if (obj->spe < 50) obj->spe = 50;
244.  		    else obj->spe++;
245.  		    p_glow2(obj,White);
246.  		    obj->recharged = 1;
247.  		}
248.  		break;
249.  	    case OIL_LAMP:
250.  	    case BRASS_LANTERN:
251.  		if (is_cursed) {
252.  		    stripspe(obj);
253.  		    if (obj->lamplit) {
254.  			if (!Blind)
255.  			    pline("%s goes out!", The(xname(obj)));
256.  			obj->lamplit = 0;
257.  			check_lamps();
258.  		    }
259.  		} else if (is_blessed) {
260.  		    obj->spe = 1;
261.  		    obj->age = 1500;
262.  		    p_glow2(obj,blue);
263.  		} else {
264.  		    obj->spe = 1;
265.  		    obj->age += 750;
266.  		    if (obj->age > 1500) obj->age = 1500;
267.  		    p_glow1(obj);
268.  		}
269.  		break;
270.  	    case CRYSTAL_BALL:
271.  		if (is_cursed) stripspe(obj);
272.  		else if (is_blessed) {
273.  		    obj->spe = 6;
274.  		    p_glow2(obj,blue);
275.  		} else {
276.  		    if (obj->spe < 5) {
277.  			obj->spe++;
278.  			p_glow1(obj);
279.  		    } else pline(nothing_happens);
280.  		}
281.  		break;
282.  	    case HORN_OF_PLENTY:
283.  	    case BAG_OF_TRICKS:
284.  		if (is_cursed) stripspe(obj);
285.  		else if (is_blessed) {
286.  		    if (obj->spe <= 10)
287.  			obj->spe += rn1(10, 6);
288.  		    else obj->spe += rn1(5, 6);
289.  		    p_glow2(obj,blue);
290.  		} else {
291.  		    obj->spe += rnd(5);
292.  		    p_glow1(obj);
293.  		}
294.  		break;
295.  	    default:
296.  		You("have a feeling of loss.");
297.  		break;
298.  	    } /* switch */
299.  	}
300.  }
301.  
302.  /*
303.   * forget some things (e.g. after reading a scroll of amnesia). abs(howmuch)
304.   * controls the level of forgetfulness; 0 == part of the map, 1 == all of
305.   * of map,  2 == part of map + spells, 3 == all of map + spells.
306.   */
307.  
308.  static void
309.  forget(howmuch)
310.  boolean howmuch;
311.  {
312.  	register int zx, zy;
313.  	register struct trap *trap;
314.  
315.  	if (Punished) u.bc_felt = 0;	/* forget felt ball&chain */
316.  
317.  	known = TRUE;
318.  	for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
319.  	    if (howmuch & 1 || rn2(7)) {
320.  		/* Zonk all memory of this location. */
321.  		levl[zx][zy].seen = levl[zx][zy].waslit = 0;
322.  		levl[zx][zy].glyph = cmap_to_glyph(S_stone);
323.  	    }
324.  
325.  	/* forget all traps (except the one the hero is in :-) */
326.  	for (trap = ftrap; trap; trap = trap->ntrap)
327.  	    if (trap->tx != u.ux || trap->ty != u.uy) trap->tseen = 0;
328.  
329.  	/*
330.  	 * Make sure that what was seen is restored correctly.  To do this,
331.  	 * we need to go blind for an instant --- turn off the display,
332.  	 * then restart it.  All this work is needed to correctly handle
333.  	 * walls which are stone on one side and wall on the other.  Turning
334.  	 * off the seen bit above will make the wall revert to stone,  but
335.  	 * there are cases where we don't want this to happen.  The easiest
336.  	 * thing to do is to run it through the vision system again, which
337.  	 * is always correct.
338.  	 */
339.  	docrt();		/* this correctly will reset vision */
340.  
341.  	if(howmuch & 2) losespells();
342.  }
343.  
344.  int
345.  seffects(sobj)
346.  register struct obj	*sobj;
347.  {
348.  	register int cval;
349.  	register boolean confused = (Confusion != 0);
350.  	register struct obj *otmp;
351.  
352.  	exercise(A_WIS, TRUE);		/* just for trying */
353.  	switch(sobj->otyp) {
354.  #ifdef MAIL
355.  	case SCR_MAIL:
356.  		known = TRUE;
357.  		if (sobj->spe)
358.  		    pline("This seems to be junk mail addressed to the finder of the Eye of Larn.");
359.  		/* note to the puzzled: the game Larn actually sends you junk
360.  		 * mail if you win!
361.  		 */
362.  		else readmail(sobj);
363.  		break;
364.  #endif
365.  	case SCR_ENCHANT_ARMOR:
366.  	    {
367.  		register schar s;
368.  		otmp = some_armor();
369.  		if(!otmp) {
370.  			strange_feeling(sobj,
371.  					!Blind ? "Your skin glows then fades." :
372.  					"Your skin feels warm for a moment.");
373.  			exercise(A_CON, !sobj->cursed);
374.  			exercise(A_STR, !sobj->cursed);
375.  			return(1);
376.  		}
377.  		if(confused) {
378.  			otmp->oerodeproof = !(sobj->cursed);
379.  			if(Blind) {
380.  			    otmp->rknown = FALSE;
381.  			    Your("%s feels warm for a moment.",
382.  				xname(otmp));
383.  			} else {
384.  			    otmp->rknown = TRUE;
385.  			    Your("%s is covered by a %s %s %s!",
386.  				xname(otmp),
387.  				sobj->cursed ? "mottled" : "shimmering",
388.  				Hallucination ? hcolor() :
389.  				  sobj->cursed ? Black : golden,
390.  				sobj->cursed ? "glow" :
391.  				  (is_shield(otmp) ? "layer" : "shield"));
392.  			}
393.  			if (otmp->oerodeproof && otmp->oeroded) {
394.  			    otmp->oeroded = 0;
395.  			    Your("%s %ss good as new!",
396.  				 xname(otmp), Blind ? "feel" : "look");
397.  			}
398.  			break;
399.  		}
400.  		if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
401.  				&& rn2(otmp->spe) && !sobj->cursed) {
402.  		Your("%s violently %s%s for a while, then evaporates.",
403.  			    xname(otmp),
404.  			    Blind ? "vibrates" : "glows ",
405.  			    Blind ? nul : Hallucination ? hcolor() : silver);
406.  			if(is_cloak(otmp)) (void) Cloak_off();
407.  			if(is_boots(otmp)) (void) Boots_off();
408.  			if(is_helmet(otmp)) (void) Helmet_off();
409.  			if(is_gloves(otmp)) (void) Gloves_off();
410.  			if(is_shield(otmp)) (void) Shield_off();
411.  			if(otmp == uarm) (void) Armor_gone();
412.  			useup(otmp);
413.  			break;
414.  		}
415.  		s = sobj->cursed ? -1 :
416.  		    otmp->spe >= 9 ? (rn2(otmp->spe) == 0) :
417.  		    sobj->blessed ? rnd(3-otmp->spe/3) : 1;
418.  		if (s >= 0 && otmp->otyp >= GRAY_DRAGON_SCALES &&
419.  					otmp->otyp <= YELLOW_DRAGON_SCALES) {
420.  			/* dragon scales get turned into dragon scale mail */
421.  			Your("%s merges and hardens!", xname(otmp));
422.  			setworn((struct obj *)0, W_ARM);
423.  			/* assumes same order */
424.  			otmp->otyp = GRAY_DRAGON_SCALE_MAIL +
425.  						otmp->otyp - GRAY_DRAGON_SCALES;
426.  			otmp->cursed = 0;
427.  			if (sobj->blessed) {
428.  				otmp->spe++;
429.  				otmp->blessed = 1;
430.  			}
431.  			otmp->known = 1;
432.  			setworn(otmp, W_ARM);
433.  			break;
434.  		}
435.  		Your("%s %s%s%s for a %s.",
436.  			xname(otmp),
437.  		        s == 0 ? "violently " : nul,
438.  			Blind ? "vibrates" : "glows ",
439.  			Blind ? nul : Hallucination ? hcolor() :
440.  			  sobj->cursed ? Black : silver,
441.  			  (s*s>1) ? "while" : "moment");
442.  		otmp->cursed = sobj->cursed;
443.  		if (!otmp->blessed || sobj->cursed)
444.  			otmp->blessed = sobj->blessed;
445.  		if (s) {
446.  			otmp->spe += s;
447.  			adj_abon(otmp, s);
448.  		}
449.  
450.  		/* an elven magic clue, cookie@keebler */
451.  		if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
452.  				&& (is_elven_armor(otmp) || !rn2(7)))
453.  			Your("%s suddenly vibrates %s.",
454.  				xname(otmp),
455.  				Blind ? "again" : "unexpectedly");
456.  		break;
457.  	    }
458.  	case SCR_DESTROY_ARMOR:
459.  	    {
460.  		otmp = some_armor();
461.  		if(confused) {
462.  			if(!otmp) {
463.  				strange_feeling(sobj,"Your bones itch.");
464.  				exercise(A_STR, FALSE);
465.  				exercise(A_CON, FALSE);
466.  				return(1);
467.  			}
468.  			otmp->oerodeproof = sobj->cursed;
469.  			p_glow2(otmp,purple);
470.  			break;
471.  		}
472.  		if(!sobj->cursed || !otmp || !otmp->cursed) {
473.  		    if(!destroy_arm(otmp)) {
474.  			strange_feeling(sobj,"Your skin itches.");
475.  			exercise(A_STR, FALSE);
476.  			exercise(A_CON, FALSE);
477.  			return(1);
478.  		    }
479.  		} else {	/* armor and scroll both cursed */
480.  		    Your("%s vibrates.", xname(otmp));
481.  		    if (otmp->spe >= -6) otmp->spe--;
482.  		    make_stunned(HStun + rn1(10, 10), TRUE);
483.  		}
484.  	    }
485.  	    break;
486.  	case SCR_CONFUSE_MONSTER:
487.  	case SPE_CONFUSE_MONSTER:
488.  		if(u.usym != S_HUMAN || sobj->cursed) {
489.  			if(!HConfusion) You("feel confused.");
490.  			make_confused(HConfusion + rnd(100),FALSE);
491.  		} else  if(confused) {
492.  		    if(!sobj->blessed) {
493.  			Your("%s begin to %s%s.",
494.  			    makeplural(body_part(HAND)),
495.  			    Blind ? "tingle" : "glow ",
496.  			    Blind ? nul : Hallucination ? hcolor() : purple);
497.  			make_confused(HConfusion + rnd(100),FALSE);
498.  		    } else {
499.  			pline("A %s%s surrounds your %s.",
500.  			    Blind ? nul : Hallucination ? hcolor() : red,
501.  			    Blind ? "faint buzz" : " glow",
502.  			    body_part(HEAD));
503.  			make_confused(0L,TRUE);
504.  		    }
505.  		} else {
506.  		    if (!sobj->blessed) {
507.  			Your("%s%s %s%s.",
508.  			makeplural(body_part(HAND)),
509.  			Blind ? "" : " begin to glow",
510.  			Blind ? (const char *)"tingle" : Hallucination ? hcolor() : red,
511.  			u.umconf ? " even more" : "");
512.  			u.umconf++;
513.  		    } else {
514.  			if (Blind)
515.  			    Your("%s tingle %s sharply.",
516.  				makeplural(body_part(HAND)),
517.  				u.umconf ? "even more" : "very");
518.  			else
519.  			    Your("%s glow a%s brilliant %s.",
520.  				makeplural(body_part(HAND)),
521.  				u.umconf ? "n even more" : "",
522.  				Hallucination ? hcolor() : red);
523.  			u.umconf += rn1(8, 2);
524.  		    }
525.  		}
526.  		break;
527.  	case SCR_SCARE_MONSTER:
528.  	case SPE_CAUSE_FEAR:
529.  	    {	register int ct = 0;
530.  		register struct monst *mtmp;
531.  
532.  		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
533.  		    if(cansee(mtmp->mx,mtmp->my)) {
534.  			if(confused || sobj->cursed) {
535.  			    mtmp->mflee = mtmp->mfrozen = mtmp->msleep = 0;
536.  			    mtmp->mcanmove = 1;
537.  			} else
538.  			    if (! resist(mtmp, sobj->oclass, 0, NOTELL))
539.  				mtmp->mflee = 1;
540.  			if(!mtmp->mtame) ct++;	/* pets don't laugh at you */
541.  		    }
542.  		if(!ct)
543.  		      You("hear %s in the distance.",
544.  			       (confused || sobj->cursed) ? "sad wailing" :
545.  							"maniacal laughter");
546.  		else if(sobj->otyp == SCR_SCARE_MONSTER)
547.  			You("hear %s close by.",
548.  				  (confused || sobj->cursed) ? "sad wailing" :
549.  						 "maniacal laughter");
550.  		break;
551.  	    }
552.  	case SCR_BLANK_PAPER:
553.  	    if (Blind)
554.  		You("don't remember there being any magic words on this scroll.");
555.  	    else
556.  		pline("This scroll seems to be blank.");
557.  	    known = TRUE;
558.  	    break;
559.  	case SCR_REMOVE_CURSE:
560.  	case SPE_REMOVE_CURSE:
561.  	    {	register struct obj *obj;
562.  		if(confused)
563.  		    if (Hallucination)
564.  			You("feel the power of the Force against you!");
565.  		    else
566.  			You("feel like you need some help.");
567.  		else
568.  		    if (Hallucination)
569.  			You("feel in touch with the Universal Oneness.");
570.  		    else
571.  			You("feel like someone is helping you.");
572.  
573.  		if(sobj->cursed) pline("The scroll disintegrates.");
574.  		else {
575.  		    for(obj = invent; obj ; obj = obj->nobj)
576.  			if(sobj->blessed || obj->owornmask ||
577.  			   (obj->otyp == LOADSTONE)) {
578.  			    if(confused) blessorcurse(obj, 2);
579.  			    else uncurse(obj);
580.  			}
581.  		}
582.  		if(Punished && !confused) unpunish();
583.  		break;
584.  	    }
585.  	case SCR_CREATE_MONSTER:
586.  #if defined(WIZARD) || defined(EXPLORE_MODE)
587.  	    if (wizard || discover)
588.  		known = TRUE;
589.  #endif /* WIZARD || EXPLORE_MODE */
590.  	case SPE_CREATE_MONSTER:
591.  	    {	register int cnt = 1;
592.  
593.  		if(!rn2(73) && !sobj->blessed) cnt += rnd(4);
594.  		if(confused || sobj->cursed) cnt += 12;
595.  		while(cnt--) {
596.  #if defined(WIZARD) || defined(EXPLORE_MODE)
597.  		    if((!wizard && !discover) || !create_particular())
598.  #endif /* WIZARD || EXPLORE_MODE */
599.  		    (void) makemon (confused ? &mons[PM_ACID_BLOB] :
600.  					(struct permonst *) 0, u.ux, u.uy);
601.  		}
602.  		break;
603.  	    }
604.  /*	    break;	/*NOTREACHED*/
605.  	case SCR_ENCHANT_WEAPON:
606.  		if(uwep && (uwep->oclass == WEAPON_CLASS ||
607.  			    uwep->otyp == PICK_AXE ||
608.  			    uwep->otyp == UNICORN_HORN) && confused) {
609.  		/* oclass check added 10/25/86 GAN */
610.  			uwep->oerodeproof = !(sobj->cursed);
611.  			if(Blind) {
612.  			    uwep->rknown = FALSE;
613.  			    Your("weapon feels warm for a moment.");
614.  			} else {
615.  			    uwep->rknown = TRUE;
616.  			    Your("%s covered by a %s %s %s!",
617.  				aobjnam(uwep, "are"),
618.  				sobj->cursed ? "mottled" : "shimmering",
619.  				Hallucination ? hcolor() :
620.  				  sobj->cursed ? purple : golden,
621.  				sobj->cursed ? "glow" : "shield");
622.  			}
623.  			if (uwep->oerodeproof && uwep->oeroded) {
624.  			    uwep->oeroded = 0;
625.  			    Your("%s good as new!",
626.  				 aobjnam(uwep, Blind ? "feel" : "look"));
627.  			}
628.  		} else return !chwepon(sobj,
629.  				       sobj->cursed ? -1 :
630.  				       !uwep ? 1 :
631.  				       uwep->spe >= 9 ? (rn2(uwep->spe) == 0) :
632.  				       sobj->blessed ? rnd(3-uwep->spe/3) : 1);
633.  		break;
634.  	case SCR_TAMING:
635.  	case SPE_CHARM_MONSTER:
636.  	    {	register int i,j;
637.  		register int bd = confused ? 5 : 1;
638.  		register struct monst *mtmp;
639.  
640.  		for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
641.  		if(isok(u.ux+i, u.uy+j) && (mtmp = m_at(u.ux+i, u.uy+j))) {
642.  		    if(sobj->cursed) {
643.  			if(!mtmp->mtame) mtmp->mpeaceful = 0;
644.  		    } else {
645.  			if (mtmp->isshk) {
646.  			    if (!mtmp->mpeaceful) {
647.  				pline("%s calms down.", Monnam(mtmp));
648.  				mtmp->mpeaceful = 1;
649.  			    }
650.  			} else if(!resist(mtmp, sobj->oclass, 0, NOTELL))
651.  			    (void) tamedog(mtmp, (struct obj *) 0);
652.  		    }
653.  		}
654.  		break;
655.  	    }
656.  	case SCR_GENOCIDE:
657.  		You("have found a scroll of genocide!");
658.  		known = TRUE;
659.  		if (sobj->blessed) do_class_genocide();
660.  		else do_genocide(!sobj->cursed | (2 * !!Confusion));
661.  		break;
662.  	case SCR_LIGHT:
663.  		if(!Blind) known = TRUE;
664.  		litroom(!confused && !sobj->cursed, sobj);
665.  		break;
666.  	case SCR_TELEPORTATION:
667.  		if(confused || sobj->cursed) level_tele();
668.  		else {
669.  			if (sobj->blessed && !Teleport_control) {
670.  				known = TRUE;
671.  				if (yn("Do you wish to teleport?")=='n')
672.  					break;
673.  			}
674.  			tele();
675.  			if(Teleport_control || !couldsee(u.ux0, u.uy0) ||
676.  			   (distu(u.ux0, u.uy0) >= 16))
677.  				known = TRUE;
678.  		}
679.  		break;
680.  	case SCR_GOLD_DETECTION:
681.  		if (confused || sobj->cursed) return(trap_detect(sobj));
682.  		else return(gold_detect(sobj));
683.  	case SCR_FOOD_DETECTION:
684.  	case SPE_DETECT_FOOD:
685.  		if (food_detect(sobj))
686.  			return(1);	/* nothing detected */
687.  		break;
688.  	case SPE_IDENTIFY:
689.  		cval = rn2(5);
690.  		goto id;
691.  	case SCR_IDENTIFY:
692.  		/* known = TRUE; */
693.  		if(confused)
694.  			You("identify this as an identify scroll.");
695.  		else
696.  			pline("This is an identify scroll.");
697.  		if (sobj->blessed || (!sobj->cursed && !rn2(5)))
698.  			cval = rn2(5);
699.  			/* Note: if rn2(5)==0, identify all items */
700.  		else	cval = 1;
701.  		useup(sobj);
702.  		makeknown(SCR_IDENTIFY);
703.  	id:
704.  		if(invent && !confused) {
705.  		    int ret;
706.  		    do {
707.  			ret = ggetobj("identify", identify, cval);
708.  		    } while(cval && (cval -= ret));
709.  		}
710.  		return(1);
711.  	case SCR_CHARGING:
712.  		if (confused) {
713.  		    You("feel charged up!");
714.  		    if (u.uen < u.uenmax)
715.  			u.uen = u.uenmax;
716.  		    else
717.  			u.uen = (u.uenmax += d(5,4));
718.  		    flags.botl = 1;
719.  		    break;
720.  		}
721.  		known = TRUE;
722.  		pline("This is a charging scroll.");
723.  		otmp = getobj(all_count, "charge");
724.  		if (!otmp) break;
725.  		recharge(otmp, sobj->cursed ? -1 : (sobj->blessed ? 1 : 0));
726.  		break;
727.  	case SCR_MAGIC_MAPPING:
728.  		if (level.flags.nommap) {
729.  		    Your("mind is filled with crazy lines!");
730.  		    if (Hallucination)
731.  			pline("Wow!  Modern art.");
732.  		    else
733.  			Your("head spins in bewilderment.");
734.  		    make_confused(HConfusion + rnd(30), FALSE);
735.  		    break;
736.  		}
737.  		known = TRUE;
738.  	case SPE_MAGIC_MAPPING:
739.  		if (level.flags.nommap) {
740.  		    Your("head spins as something blocks the spell!");
741.  		    make_confused(HConfusion + rnd(30), FALSE);
742.  		    break;
743.  		}
744.  		pline("A map coalesces in your mind!");
745.  		cval = (sobj->cursed && !confused);
746.  		if(cval) HConfusion = 1;	/* to screw up map */
747.  		do_mapping();
748.  		if(cval) {
749.  		    HConfusion = 0;		/* restore */
750.  		    pline("Unfortunately, you can't grasp the details.");
751.  		}
752.  		break;
753.  	case SCR_AMNESIA:
754.  		known = TRUE;
755.  		forget( ((!sobj->blessed) << 1) | (!confused || sobj->cursed) );
756.  		if (Hallucination) /* Ommmmmm! */
757.  			Your("mind releases itself from mundane concerns.");
758.  		else if (!strncmpi(plname, "Maud", 4))
759.  			pline("As your mind turns inward on itself, you forget everything else.");
760.  		else if (rn2(2))
761.  			pline("Who was that Maud person anyway?");
762.  		else
763.  			pline("Thinking of Maud you forget everything else.");
764.  		exercise(A_WIS, FALSE);
765.  		break;
766.  	case SCR_FIRE:
767.  		/*
768.  		 * Note: Modifications have been made as of 3.0 to allow for
769.  		 * some damage under all potential cases.
770.  		 */
771.  		cval = bcsign(sobj);
772.  		useup(sobj);
773.  		makeknown(SCR_FIRE);
774.  		if(confused) {
775.  		    if(Fire_resistance) {
776.    			shieldeff(u.ux, u.uy);
777.  			if(!Blind)
778.  			    pline("Oh, look, what a pretty fire in your %s.",
779.  				makeplural(body_part(HAND)));
780.  			else You("feel a pleasant warmth in your %s.",
781.  				makeplural(body_part(HAND)));
782.  		    } else {
783.  			pline("The scroll catches fire and you burn your %s.",
784.  				makeplural(body_part(HAND)));
785.  			losehp(1, "scroll of fire", KILLED_BY_AN);
786.  		    }
787.  		    return(1);
788.  		}
789.  		if (Underwater)
790.  			pline("The water around you vaporizes violently!");
791.  		else
792.  			pline("The scroll erupts in a tower of flame!");
793.  		explode(u.ux, u.uy, 11, (2*(rn1(3, 3) + 2 * cval) + 1)/3,
794.  							SCROLL_CLASS);
795.  		return(1);
796.  	case SCR_PUNISHMENT:
797.  		known = TRUE;
798.  		if(confused || sobj->blessed) {
799.  			You("feel guilty.");
800.  			break;
801.  		}
802.  		punish(sobj);
803.  		break;
804.  	default:
805.  		impossible("What weird effect is this? (%u)", sobj->otyp);
806.  	}
807.  	return(0);
808.  }
809.  
810.  static void
811.  wand_explode(obj)
812.  register struct obj *obj;
813.  {
814.      Your("%s vibrates violently, and explodes!",xname(obj));
815.      nhbell();
816.      losehp(rn2(2*(u.uhpmax+1)/3),"exploding wand", KILLED_BY_AN);
817.      useup(obj);
818.      exercise(A_STR, FALSE);
819.  }
820.  
821.  /*
822.   * Low-level lit-field update routine.
823.   */
824.  STATIC_PTR void
825.  set_lit(x,y,val)
826.  int x, y;
827.  genericptr_t val;
828.  {
829.  	levl[x][y].lit = (val == (genericptr_t)-1) ? 0 : 1;
830.  	return;
831.  }
832.  
833.  void
834.  litroom(on,obj)
835.  register boolean on;
836.  struct obj *obj;
837.  {
838.  	/* first produce the text (provided you're not blind) */
839.  	if(Blind) goto do_it;
840.  	if(!on) {
841.  		if(u.uswallow) {
842.  			pline("It seems even darker in here than before.");
843.  			return;
844.  		}
845.  		You("are surrounded by darkness!");
846.  	} else {
847.  		if(u.uswallow){
848.  			if (is_animal(u.ustuck->data))
849.  				pline("%s stomach is lit.",
850.  				         s_suffix(Monnam(u.ustuck)));
851.  			else
852.  				if (is_whirly(u.ustuck->data))
853.  					pline("%s shines briefly.",
854.  					      Monnam(u.ustuck));
855.  				else
856.  					pline("%s glistens.", Monnam(u.ustuck));
857.  			return;
858.  		}
859.  		pline("A lit field surrounds you!");
860.  	}
861.  
862.  do_it:
863.  	/* No-op in water - can only see the adjacent squares and that's it! */
864.  	if (Underwater || Is_waterlevel(&u.uz)) return;
865.  	/*
866.  	 *  If we are darkening the room and the hero is punished but not
867.  	 *  blind, then we have to pick up and replace the ball and chain so
868.  	 *  that we don't remember them if they are out of sight.
869.  	 */
870.  	if (Punished && !on && !Blind)
871.  	    move_bc(1, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
872.  
873.  #ifdef REINCARNATION
874.  	if (Is_rogue_level(&u.uz)) {
875.  	    /* Can't use do_clear_area because MAX_RADIUS is too small */
876.  	    /* rogue lighting must light the entire room */
877.  	    int rnum = levl[u.ux][u.uy].roomno - ROOMOFFSET;
878.  	    int rx, ry;
879.  	    if(rnum >= 0) {
880.  		for(rx = rooms[rnum].lx-1; rx <= rooms[rnum].hx+1; rx++)
881.  		    for(ry = rooms[rnum].ly-1; ry <= rooms[rnum].hy+1; ry++)
882.  			set_lit(rx, ry, (genericptr_t)((on)? 1 : -1));
883.  		rooms[rnum].rlit = on;
884.  	    }
885.  	    /* hallways remain dark on the rogue level */
886.  	} else
887.  #endif
888.  	    do_clear_area(u.ux,u.uy,
889.  		(obj && obj->oclass==SCROLL_CLASS && obj->blessed) ? 9 : 5,
890.  		set_lit, (genericptr_t)((on)? 1 : -1));
891.  
892.  	/*
893.  	 *  If we are not blind, then force a redraw on all positions in sight
894.  	 *  by temporarily blinding the hero.  The vision recalculation will
895.  	 *  correctly update all previously seen positions *and* correctly
896.  	 *  set the waslit bit [could be messed up from above].
897.  	 */
898.  	if (!Blind) {
899.  	    vision_recalc(2);
900.  
901.  	    /* replace ball&chain */
902.  	    if (Punished && !on)
903.  		move_bc(0, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
904.  	}
905.  
906.  	vision_full_recalc = 1;	/* delayed vision recalculation */
907.  }
908.  
909.  static void
910.  do_class_genocide()
911.  {
912.  	register int i, j, immunecnt, gonecnt, goodcnt, class;
913.  	char buf[BUFSZ];
914.  
915.  	for(j=0; ; j++) {
916.  		if (j >= 5) {
917.  			pline(thats_enough_tries);
918.  			return;
919.  		}
920.  		do {
921.      getlin("What class of monsters do you wish to genocide? [type a letter]",
922.  	   buf);
923.  		} while (buf[0]=='\033' || strlen(buf) != 1);
924.  		immunecnt = gonecnt = goodcnt = 0;
925.  		class = def_char_to_monclass(buf[0]);
926.  		for(i = 0; i < NUMMONS; i++) {
927.  			if(mons[i].mlet == class) {
928.  				if (!(mons[i].geno & G_GENO)) immunecnt++;
929.  				else if(mons[i].geno & G_GENOD) gonecnt++;
930.  				else goodcnt++;
931.  			}
932.  		}
933.  		if (!goodcnt && class != S_HUMAN) {
934.  			if (gonecnt)
935.  	pline("All such monsters are already nonexistent.");
936.  			else if (immunecnt)
937.  	You("aren't permitted to genocide such monsters.");
938.  			else
939.  	pline("That symbol does not represent any monster.");
940.  			continue;
941.  		}
942.  		for(i = 0; i < NUMMONS; i++) {
943.  		    if(mons[i].mlet == class) {
944.  			register struct monst *mtmp, *mtmp2;
945.  			char *n = makeplural(mons[i].mname);
946.  
947.  			if (&mons[i]==player_mon() || ((mons[i].geno & G_GENO)
948.  				&& !(mons[i].geno & G_GENOD))) {
949.  			/* This check must be first since player monsters might
950.  			 * have G_GENOD or !G_GENO.
951.  			 */
952.  			    pline("Wiped out all %s.", n);
953.  			    if (&mons[i] == player_mon()) {
954.  				u.uhp = -1;
955.  				killer_format = KILLED_BY_AN;
956.  				killer = "scroll of genocide";
957.  #ifdef POLYSELF
958.  				if (u.umonnum >= 0)
959.  				    You("feel dead inside.");
960.  				else
961.  #endif
962.  				    done(GENOCIDED);
963.  			    }
964.  			    /* for simplicity (and fairness) let's avoid
965.  			     * alignment changes here...
966.  			     */
967.  #ifdef POLYSELF
968.  			    if (i==u.umonnum) rehumanize();
969.  #endif
970.  			    mons[i].geno |= G_GENOD;
971.  			    for(mtmp = fmon; mtmp; mtmp = mtmp2) {
972.  				mtmp2 = mtmp->nmon;
973.  				if(mtmp->data == &mons[i])
974.  				    mondead(mtmp);
975.  			    }
976.  			} else if (mons[i].geno & G_GENOD)
977.  			    pline("All %s are already nonexistent.", n);
978.  			else
979.  			    You("aren't permitted to genocide %s%s.",
980.  				i == PM_WIZARD_OF_YENDOR ? "the " : "",
981.  				type_is_pname(&mons[i]) ? mons[i].mname : (const char *)n);
982.  			}
983.  		}
984.  		return;
985.  	}
986.  }
987.  
988.  #define REALLY 1
989.  #define PLAYER 2
990.  void
991.  do_genocide(how)
992.  int how;
993.  /* 0 = no genocide; create monsters (cursed scroll) */
994.  /* 1 = normal genocide */
995.  /* 3 = forced genocide of player */
996.  {
997.  	char buf[BUFSZ];
998.  	register int	i, j, killplayer = 0;
999.  	register struct permonst *ptr;
1000. 	register struct monst *mtmp, *mtmp2;
1001. 
1002. 	if (how & PLAYER) {
1003. 		ptr = player_mon();
1004. 		Strcpy(buf, ptr->mname);
1005. 		killplayer++;
1006. 	} else {
1007. 	    for(j = 0; ; j++) {
1008. 		if(j >= 5) {
1009. 		    pline(thats_enough_tries);
1010. 		    return;
1011. 		}
1012. 		getlin("What monster do you want to genocide? [type the name]",
1013. 			buf);
1014. 
1015. 		i = name_to_mon(buf);
1016. 		if(i == -1 || (mons[i].geno & G_GENOD)) {
1017. 			pline("Such creatures do not exist in this world.");
1018. 			continue;
1019. 		}
1020. 		ptr = &mons[i];
1021. 		if (ptr == player_mon()) {
1022. 			killplayer++;
1023. 			goto deadmeat;
1024. 		}
1025. 		if (is_human(ptr)) adjalign(-sgn(u.ualign.type));
1026. 		if (is_demon(ptr)) adjalign(sgn(u.ualign.type));
1027. 
1028. 		if(!(ptr->geno & G_GENO))  {
1029. 			if(flags.soundok) {
1030. 			    if(flags.verbose)
1031. 			pline("A thunderous voice booms though the caverns:");
1032. 			    pline("\"No, mortal!  That will not be done.\"");
1033. 			}
1034. 			continue;
1035. 		}
1036. 		break;
1037. 	    }
1038. 	}
1039. deadmeat:
1040. 	if (Hallucination) {
1041. #ifdef POLYSELF
1042. 	    if (u.umonnum != -1)
1043. 		Strcpy(buf,uasmon->mname);
1044. 	    else
1045. #endif
1046. 	    {
1047. 		Strcpy(buf, pl_character);
1048. 		buf[0] += 'a' - 'A';
1049. 	    }
1050. 	} else Strcpy(buf,ptr->mname); /* make sure we have standard singular */
1051. 	if (how & REALLY) {
1052. 	    pline("Wiped out all %s.", makeplural(buf));
1053. 	    if(killplayer) {
1054. 		u.uhp = -1;
1055. 		killer_format = KILLED_BY_AN;
1056. 		killer = "genocide spell";
1057. #ifdef POLYSELF
1058. 	/* Polymorphed characters will die as soon as they're rehumanized. */
1059. 		if(u.umonnum >= 0)	You("feel dead inside.");
1060. 		else
1061. #endif
1062. 			done(GENOCIDED);
1063. 		return;
1064. 	    }
1065. #ifdef POLYSELF
1066. 	    else if (ptr == uasmon) rehumanize();
1067. #endif
1068. 	    ptr->geno |= G_GENOD;
1069. 	    for(mtmp = fmon; mtmp; mtmp = mtmp2) {
1070. 		mtmp2 = mtmp->nmon;
1071. 		if(mtmp->data == ptr)
1072. 		    mondead(mtmp);
1073. 	    }
1074. 	} else if (!(ptr->geno & G_EXTINCT)) {
1075. 	    pline("Sent in some %s.", makeplural(buf));
1076. 	    j = rn1(3, 4);
1077. 	    for(i=1; i<=j; i++) {
1078. 		struct monst *mmon = makemon(ptr, u.ux, u.uy);
1079. 		struct obj *otmp;
1080. 
1081. 		while ((otmp = mmon->minvent) != 0) {
1082. 			mmon->minvent = otmp->nobj;
1083. 			dealloc_obj(otmp);
1084. 		}
1085. 	    }
1086. 	}
1087. }
1088. 
1089. #endif /* OVLB */
1090. #ifdef OVLB
1091. 
1092. void
1093. punish(sobj)
1094. register struct obj	*sobj;
1095. {
1096. 	You("are being punished for your misbehavior!");
1097. 	if(Punished){
1098. 		Your("iron ball gets heavier.");
1099. 		uball->owt += 160 * (1 + sobj->cursed);
1100. 		return;
1101. 	}
1102. 	setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN);
1103. 	setworn(mkobj(BALL_CLASS, TRUE), W_BALL);
1104. 	uball->spe = 1;		/* special ball (see save) */
1105. 
1106. 	/*
1107. 	 *  Place ball & chain if not swallowed.  If swallowed, the ball &
1108. 	 *  chain variables will be set at the next call to placebc().
1109. 	 */
1110. 	if (!u.uswallow) {
1111. 	    placebc();
1112. 	    if (Blind) set_bc(1);	/* set up ball and chain variables */
1113. 	    newsym(u.ux,u.uy);		/* see ball&chain if can't see self */
1114. 	}
1115. }
1116. 
1117. void
1118. unpunish()
1119. {	    /* remove the ball and chain */
1120. 	freeobj(uchain);
1121. 	newsym(uchain->ox,uchain->oy);
1122. 	dealloc_obj(uchain);
1123. 	setworn((struct obj *)0, W_CHAIN);
1124. 	uball->spe = 0;
1125. 	setworn((struct obj *)0, W_BALL);
1126. }
1127. 
1128. /* some creatures have special data structures that only make sense in their
1129.  * normal locations -- if the player tries to create one elsewhere, or to revive
1130.  * one, the disoriented creature becomes a zombie
1131.  */
1132. boolean
1133. cant_create(mtype)
1134. int *mtype;
1135. {
1136. 
1137. 	if (*mtype==PM_GUARD || *mtype==PM_SHOPKEEPER
1138. 	     || *mtype==PM_ALIGNED_PRIEST || *mtype==PM_ANGEL) {
1139. 		*mtype = PM_HUMAN_ZOMBIE;
1140. 		return TRUE;
1141. 	}
1142. 	return FALSE;
1143. }
1144. 
1145. #if defined(WIZARD) || defined(EXPLORE_MODE)
1146. boolean
1147. create_particular()
1148. {
1149. 	char buf[BUFSZ];
1150. 	int which, tries = 0;
1151. 
1152. 	do {
1153. 	    getlin("Create what kind of monster? [type the name]", buf);
1154. 	    which = name_to_mon(buf);
1155. 	    if (which < 0) pline("I've never heard of such monsters.");
1156. 	    else break;
1157. 	} while (++tries < 5);
1158. 	if (tries == 5) pline(thats_enough_tries);
1159. 	else {
1160. 	    if (!(mons[which].geno & G_GENOD) && cant_create(&which) &&
1161. 								!Blind) {
1162. 		if (mons[which].geno & G_GENOD)
1163. pline("An image of the creature forms, wavers momentarily, then fades.");
1164. 		else
1165. pline("The disoriented creature's eyes slowly glaze over.");
1166. 	    }
1167. 	    (void) makemon(&mons[which], u.ux, u.uy);
1168. 	    return TRUE;
1169. 	}
1170. 	return FALSE;
1171. }
1172. #endif /* WIZARD || EXPLORE_MODE */
1173. 
1174. #endif /* OVLB */
1175. 
1176. /*read.c*/