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