Source:Hack 1.0/hack.read.c

From NetHackWiki
(Redirected from Hack 1.0/hack.read.c)
Jump to navigation Jump to search

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

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

Screenshots and source code from Hack are used under the CWI license.

1.    /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1984. */
2.    
3.    #include "hack.h"
4.    
5.    extern struct monst *makemon();
6.    int identify();
7.    
8.    doread() {
9.    	register struct obj *scroll;
10.   	register boolean confused = (Confusion != 0);
11.   	register boolean known = FALSE;
12.   
13.   	scroll = getobj("?", "read");
14.   	if(!scroll) return(0);
15.   	if(!scroll->dknown && Blind) {
16.   	    pline("Being blind, you cannot read the formula on the scroll.");
17.   	    return(0);
18.   	}
19.   	if(Blind)
20.   	  pline("As you pronounce the formula on it, the scroll disappears.");
21.   	else
22.   	  pline("As you read the scroll, it disappears.");
23.   	if(confused)
24.   	  pline("Being confused, you mispronounce the magic words ... ");
25.   
26.   	switch(scroll->otyp) {
27.   
28.   	case SCR_ENCHANT_ARMOR:
29.   	    {	extern struct obj *some_armor();
30.   		register struct obj *otmp = some_armor();
31.   		if(!otmp) {
32.   			strange_feeling(scroll);
33.   			return(1);
34.   		}
35.   		if(confused) {
36.   			pline("Your %s glows silver for a moment.",
37.   				objects[otmp->otyp].oc_name);
38.   			otmp->rustfree = 1;
39.   			break;
40.   		}
41.   		if(otmp->spe*2 + objects[otmp->otyp].a_ac > 23 &&
42.   			!rn2(3)) {
43.   	pline("Your %s glows violently green for a while, then evaporates.",
44.   			objects[otmp->otyp].oc_name);
45.   			useup(otmp);
46.   			break;
47.   		}
48.   		pline("Your %s glows green for a moment.",
49.   			objects[otmp->otyp].oc_name);
50.   		otmp->cursed = 0;
51.   		otmp->spe++;
52.   		break;
53.   	    }
54.   	case SCR_DESTROY_ARMOR:
55.   		if(confused) {
56.   			register struct obj *otmp = some_armor();
57.   			if(!otmp) {
58.   				strange_feeling(scroll);
59.   				return(1);
60.   			}
61.   			pline("Your %s glows purple for a moment.",
62.   				objects[otmp->otyp].oc_name);
63.   			otmp->rustfree = 0;
64.   			break;
65.   		}
66.   		if(uarm) {
67.   		    pline("Your armor turns to dust and falls to the floor!");
68.   		    useup(uarm);
69.   		} else if(uarmh) {
70.   		    pline("Your helmet turns to dust and is blown away!");
71.   		    useup(uarmh);
72.   		} else if(uarmg) {
73.   			pline("Your gloves vanish!");
74.   			useup(uarmg);
75.   			selftouch("You");
76.   		} else {
77.   			strange_feeling(scroll);
78.   			return(1);
79.   		}
80.   		break;
81.   	case SCR_CONFUSE_MONSTER:
82.   		if(confused) {
83.   			pline("Your hands begin to glow purple.");
84.   			Confusion += rnd(100);
85.   		} else {
86.   			pline("Your hands begin to glow blue.");
87.   			u.umconf = 1;
88.   		}
89.   		break;
90.   	case SCR_SCARE_MONSTER:
91.   	    {	register int ct = 0;
92.   		register struct monst *mtmp;
93.   
94.   		for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
95.   			if(cansee(mtmp->mx,mtmp->my)) {
96.   				if(confused)
97.   					mtmp->mflee = mtmp->mfroz =
98.   					mtmp->msleep = 0;
99.   				else
100.  					mtmp->mflee = 1;
101.  				ct++;
102.  			}
103.  		if(!ct) {
104.  		    if(confused)
105.  			pline("You hear sad wailing in the distance.");
106.  		    else
107.  			pline("You hear maniacal laughter in the distance.");
108.  		}
109.  		break;
110.  	    }
111.  	case SCR_BLANK_PAPER:
112.  		if(confused)
113.  		    pline("You see strange patterns on this scroll.");
114.  		else
115.  		    pline("This scroll seems to be blank.");
116.  		break;
117.  	case SCR_REMOVE_CURSE:
118.  	    {	register struct obj *obj;
119.  		if(confused)
120.  		  pline("You feel like you need some help.");
121.  		else
122.  		  pline("You feel like someone is helping you.");
123.  		for(obj = invent; obj ; obj = obj->nobj)
124.  			if(obj->owornmask)
125.  				obj->cursed = confused;
126.  		if(Punished && !confused) {
127.  			Punished = 0;
128.  			freeobj(uchain);
129.  			unpobj(uchain);
130.  			free((char *) uchain);
131.  			uball->spe = 0;
132.  			uball->owornmask &= ~W_BALL;
133.  			uchain = uball = (struct obj *) 0;
134.  		}
135.  		break;
136.  	    }
137.  	case SCR_CREATE_MONSTER:
138.  	    {	register int cnt = 1;
139.  
140.  		if(!rn2(73)) cnt += rn2(4) + 1;
141.  		if(confused) cnt += 12;
142.  		while(cnt--)
143.  		    (void) makemon(confused ? PM_ACIDBLOB :
144.  			(struct permonst *) 0, u.ux, u.uy);
145.  		break;
146.  	    }
147.  	case SCR_ENCHANT_WEAPON:
148.  		if(!uwep) {
149.  			strange_feeling(scroll);
150.  			return(1);
151.  		}
152.  		if(confused) {
153.  			pline("Your %s glows silver for a moment.",
154.  				objects[uwep->otyp].oc_name);
155.  			uwep->rustfree = 1;
156.  		} else
157.  			if(!chwepon(scroll, 1)) return(1);
158.  		break;
159.  	case SCR_DAMAGE_WEAPON:
160.  		if(confused) {
161.  			pline("Your %s glows purple for a moment.",
162.  				objects[uwep->otyp].oc_name);
163.  			uwep->rustfree = 0;
164.  		} else
165.  			if(!chwepon(scroll, -1)) return(1);
166.  		break;
167.  	case SCR_TAMING:
168.  	    {	register int i,j;
169.  		register int bd = confused ? 5 : 1;
170.  		register struct monst *mtmp;
171.  
172.  		for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
173.  		if(mtmp = m_at(u.ux+i, u.uy+j))
174.  			(void) tamedog(mtmp, (struct obj *) 0);
175.  		break;
176.  	    }
177.  	case SCR_GENOCIDE:
178.  	    {	extern char genocided[], fut_geno[];
179.  		char buf[BUFSZ];
180.  		register struct monst *mtmp, *mtmp2;
181.  
182.  		pline("You have found a scroll of genocide!");
183.  		known = TRUE;
184.  		if(confused)
185.  			*buf = u.usym;
186.  		else do {
187.  	    pline("What monster do you want to genocide (Type the letter)? ");
188.  			getlin(buf);
189.  		} while(strlen(buf) != 1 || !letter(*buf));
190.  		if(!index(fut_geno, *buf))
191.  			charcat(fut_geno, *buf);
192.  		if(!index(genocided, *buf))
193.  			charcat(genocided, *buf);
194.  		else {
195.  			pline("Such monsters do not exist in this world.");
196.  			break;
197.  		}
198.  		for(mtmp = fmon; mtmp; mtmp = mtmp2){
199.  			mtmp2 = mtmp->nmon;
200.  			if(mtmp->data->mlet == *buf)
201.  				mondead(mtmp);
202.  		}
203.  		pline("Wiped out all %c's.", *buf);
204.  		if(*buf == u.usym) {
205.  			killer = "scroll of genocide";
206.  			u.uhp = -1;
207.  		}
208.   break;
209.  		}
210.  	case SCR_LIGHT:
211.  		if(!Blind) known = TRUE;
212.  		litroom(!confused);
213.  		break;
214.  	case SCR_TELEPORTATION:
215.  		if(confused)
216.  			level_tele();
217.  		else {
218.  #ifdef QUEST
219.  			register int oux = u.ux, ouy = u.uy;
220.  			tele();
221.  			if(dist(oux, ouy) > 100) known = TRUE;
222.  #else QUEST
223.  			register int uroom = inroom(u.ux, u.uy);
224.  			tele();
225.  			if(uroom != inroom(u.ux, u.uy)) known = TRUE;
226.  #endif QUEST
227.  		}
228.  		break;
229.  	case SCR_GOLD_DETECTION:
230.  	    {	register struct gen *head = confused ? ftrap : fgold;
231.  		register struct gen *gtmp;
232.  
233.  		if(!head) {
234.  			strange_feeling(scroll);
235.  			return(1);
236.  		} else {
237.  			known = TRUE;
238.  			for(gtmp = head; gtmp; gtmp = gtmp->ngen)
239.  				if(gtmp->gx != u.ux || gtmp->gy != u.uy)
240.  					goto outgoldmap;
241.  			/* only under me - no separate display required */
242.  			if(confused)
243.  			    pline("You feel very giddy!");
244.  			else
245.  			    pline("You notice some gold between your feet.");
246.  			break;
247.  		outgoldmap:
248.  			cls();
249.  			for(gtmp = head; gtmp; gtmp = gtmp->ngen)
250.  				at(gtmp->gx, gtmp->gy, '$');
251.  			prme();
252.  			if(confused)
253.  			    pline("You feel very greedy!");
254.  			else
255.  			    pline("You feel very greedy, and sense gold!");
256.  			more();
257.  			docrt();
258.  		}
259.  		break;
260.  	    }
261.  	case SCR_FOOD_DETECTION:
262.  	    {	register ct = 0, ctu = 0;
263.  		register struct obj *obj;
264.  		register char foodsym = confused ? POTION_SYM : FOOD_SYM;
265.  
266.  		for(obj = fobj; obj; obj = obj->nobj)
267.  			if(obj->olet == FOOD_SYM) {
268.  				if(obj->ox == u.ux && obj->oy == u.uy) ctu++;
269.  				else ct++;
270.  			}
271.  		if(!ct && !ctu) {
272.  			strange_feeling(scroll);
273.  			return(1);
274.  		} else if(!ct) {
275.  			known = TRUE;
276.  			pline("You smell %s close nearby.",
277.  				confused ? "something" : "food");
278.  			
279.  		} else {
280.  			known = TRUE;
281.  			cls();
282.  			for(obj = fobj; obj; obj = obj->nobj)
283.  			    if(obj->olet == foodsym)
284.  				at(obj->ox, obj->oy, FOOD_SYM);
285.  			prme();
286.  			pline("Your nose tingles and you smell %s!",
287.  				confused ? "something" : "food");
288.  			more();
289.  			docrt();
290.  		}
291.  		break;
292.  	    }
293.  	case SCR_IDENTIFY:
294.  		/* known = TRUE; */
295.  		if(confused)
296.  			pline("You identify this as an identify scroll.");
297.  		else
298.  			pline("This is an identify scroll.");
299.  		useup(scroll);
300.  		objects[SCR_IDENTIFY].oc_name_known = 1;
301.  		if(!confused)
302.  		    while(
303.  			!ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
304.  			&& invent
305.  		    );
306.  		return(1);
307.  	case SCR_MAGIC_MAPPING:
308.  	    {	register struct rm *lev;
309.  		register int num, zx, zy;
310.  
311.  		known = TRUE;
312.  		pline("On this scroll %s a map!",
313.  			confused ? "was" : "is");
314.  		for(zy = 0; zy < ROWNO; zy++)
315.  			for(zx = 0; zx < COLNO; zx++) {
316.  				if(confused && rn2(7)) continue;
317.  				lev = &(levl[zx][zy]);
318.  				if((num = lev->typ) == 0)
319.  					continue;
320.  				if(num == SCORR) {
321.  					lev->typ = CORR;
322.  					lev->scrsym = CORR_SYM;
323.  				} else
324.  				if(num == SDOOR) {
325.  					lev->typ = DOOR;
326.  					lev->scrsym = '+';
327.  					/* do sth in doors ? */
328.  				} else if(lev->seen) continue;
329.  #ifndef QUEST
330.  				if(num != ROOM)
331.  #endif QUEST
332.  				{
333.  				  lev->seen = lev->new = 1;
334.  				  on_scr(zx,zy);
335.  				}
336.  			}
337.  		break;
338.  	    }
339.  	case SCR_AMNESIA:
340.  	    {	register int zx, zy;
341.  
342.  		known = TRUE;
343.  		for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
344.  		    if(!confused || rn2(7))
345.  			if(!cansee(zx,zy))
346.  			    levl[zx][zy].seen = 0;
347.  		docrt();
348.  		pline("Thinking of Maud you forget everything else.");
349.  		break;
350.  	    }
351.  	case SCR_FIRE:
352.  	    {	register int num;
353.  
354.  		known = TRUE;
355.  		if(confused) {
356.  		    pline("The scroll catches fire and you burn your hands.");
357.  		    losehp(1, "scroll of fire");
358.  		} else {
359.  		    pline("The scroll erupts in a tower of flame!");
360.  		    if(Fire_resistance)
361.  			pline("You are uninjured.");
362.  		    else {
363.  			num = rnd(6);
364.  			u.uhpmax -= num;
365.  			losehp(num, "scroll of fire");
366.  		    }
367.  		}
368.  		break;
369.  	    }
370.  	case SCR_PUNISHMENT:
371.  		known = TRUE;
372.  		if(confused) {
373.  			pline("You feel guilty.");
374.  			break;
375.  		}
376.  		pline("You are being punished for your misbehaviour!");
377.  		if(Punished){
378.  			pline("Your iron ball gets heavier.");
379.  			uball->owt += 15;
380.  			break;
381.  		}
382.  		Punished = INTRINSIC;
383.  		mkobj_at(CHAIN_SYM, u.ux, u.uy);
384.  		setworn(fobj, W_CHAIN);
385.  		mkobj_at(BALL_SYM, u.ux, u.uy);
386.  		setworn(fobj, W_BALL);
387.  		uball->spe = 1;		/* special ball (see save) */
388.  		break;
389.  	default:
390.  		pline("What weird language is this written in? (%d)",
391.  			scroll->otyp);
392.  		impossible();
393.  	}
394.  	if(!objects[scroll->otyp].oc_name_known) {
395.  		if(known && !confused) {
396.  			objects[scroll->otyp].oc_name_known = 1;
397.  			u.urexp += 10;
398.  		} else if(!objects[scroll->otyp].oc_uname)
399.   docall(scroll);
400.  	}
401.  	useup(scroll);
402.  	return(1);
403.  }
404.  
405.  identify(otmp)
406.  register struct obj *otmp;
407.  {
408.  	objects[otmp->otyp].oc_name_known = 1;
409.  	otmp->known = otmp->dknown = 1;
410.  	prinv(otmp);
411.  	return(1);
412.  }
413.  
414.  litroom(on)
415.  register boolean on;
416.  {
417.  	register num,zx,zy;
418.  
419.  	/* first produce the text (provided he is not blind) */
420.  	if(Blind) goto do_it;
421.  	if(!on) {
422.  		if(u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||
423.  		    !levl[u.ux][u.uy].lit) {
424.  			pline("It seems even darker in here than before.");
425.  			return;
426.  		} else
427.   pline("It suddenly becomes dark in here.");
428.  	} else {
429.  		if(u.uswallow){
430.  			pline("%s's stomach is lit.", Monnam(u.ustuck));
431.  			return;
432.  		}
433.  		if(!xdnstair){
434.  			pline("Nothing Happens");
435.  			return;
436.  		}
437.  #ifdef QUEST
438.  		pline("The cave lights up around you, then fades.");
439.  		return;
440.  #else QUEST
441.  		if(levl[u.ux][u.uy].typ == CORR) {
442.  		    pline("The corridor lights up around you, then fades.");
443.  		    return;
444.  		} else if(levl[u.ux][u.uy].lit) {
445.  		    pline("The light here seems better now.");
446.  		    return;
447.  		} else
448.  		    pline("The room is lit.");
449.  #endif QUEST
450.  	}
451.  
452.  do_it:
453.  #ifdef QUEST
454.  	return;
455.  #else QUEST
456.  	if(levl[u.ux][u.uy].lit == on)
457.  		return;
458.  	if(levl[u.ux][u.uy].typ == DOOR) {
459.  		if(levl[u.ux][u.uy+1].typ >= ROOM) zy = u.uy+1;
460.  		else if(levl[u.ux][u.uy-1].typ >= ROOM) zy = u.uy-1;
461.  		else zy = u.uy;
462.  		if(levl[u.ux+1][u.uy].typ >= ROOM) zx = u.ux+1;
463.  		else if(levl[u.ux-1][u.uy].typ >= ROOM) zx = u.ux-1;
464.  		else zx = u.ux;
465.  	} else {
466.  		zx = u.ux;
467.  		zy = u.uy;
468.  	}
469.  	for(seelx = u.ux; (num = levl[seelx-1][zy].typ) != CORR && num != 0;
470.  		seelx--);
471.  	for(seehx = u.ux; (num = levl[seehx+1][zy].typ) != CORR && num != 0;
472.  		seehx++);
473.  	for(seely = u.uy; (num = levl[zx][seely-1].typ) != CORR && num != 0;
474.  		seely--);
475.  	for(seehy = u.uy; (num = levl[zx][seehy+1].typ) != CORR && num != 0;
476.  		seehy++);
477.  	for(zy = seely; zy <= seehy; zy++)
478.  		for(zx = seelx; zx <= seehx; zx++) {
479.  			levl[zx][zy].lit = on;
480.  			if(!Blind && dist(zx,zy) > 2)
481.  				if(on) prl(zx,zy); else nosee(zx,zy);
482.  		}
483.  	if(!on) seehx = 0;
484.  #endif	QUEST
485.  }