1 /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
2 /* hack.read.c - version 1.0.3 */
3 /* $FreeBSD: src/games/hack/hack.read.c,v 1.6 1999/11/16 10:26:37 marcel Exp $ */
4 /* $DragonFly: src/games/hack/hack.read.c,v 1.2 2003/06/17 04:25:24 dillon Exp $ */
8 extern struct monst *makemon();
9 extern struct obj *mkobj_at();
14 boolean confused = (Confusion != 0);
15 boolean known = FALSE;
16 extern struct obj *some_armor();
18 scroll = getobj("?", "read");
19 if(!scroll) return(0);
20 if(!scroll->dknown && Blind) {
21 pline("Being blind, you cannot read the formula on the scroll.");
25 pline("As you pronounce the formula on it, the scroll disappears.");
27 pline("As you read the scroll, it disappears.");
29 pline("Being confused, you mispronounce the magic words ... ");
31 switch(scroll->otyp) {
34 readmail(/* scroll */);
37 case SCR_ENCHANT_ARMOR:
38 { struct obj *otmp = some_armor();
40 strange_feeling(scroll,"Your skin glows then fades.");
44 pline("Your %s glows silver for a moment.",
45 objects[otmp->otyp].oc_name);
49 if(otmp->spe > 3 && rn2(otmp->spe)) {
50 pline("Your %s glows violently green for a while, then evaporates.",
51 objects[otmp->otyp].oc_name);
55 pline("Your %s glows green for a moment.",
56 objects[otmp->otyp].oc_name);
61 case SCR_DESTROY_ARMOR:
63 struct obj *otmp = some_armor();
65 strange_feeling(scroll,"Your bones itch.");
68 pline("Your %s glows purple for a moment.",
69 objects[otmp->otyp].oc_name);
74 pline("Your armor turns to dust and falls to the floor!");
77 pline("Your helmet turns to dust and is blown away!");
80 pline("Your gloves vanish!");
84 strange_feeling(scroll,"Your skin itches.");
88 case SCR_CONFUSE_MONSTER:
90 pline("Your hands begin to glow purple.");
91 Confusion += rnd(100);
93 pline("Your hands begin to glow blue.");
97 case SCR_SCARE_MONSTER:
101 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
102 if(cansee(mtmp->mx,mtmp->my)) {
104 mtmp->mflee = mtmp->mfroz =
112 pline("You hear sad wailing in the distance.");
114 pline("You hear maniacal laughter in the distance.");
118 case SCR_BLANK_PAPER:
120 pline("You see strange patterns on this scroll.");
122 pline("This scroll seems to be blank.");
124 case SCR_REMOVE_CURSE:
127 pline("You feel like you need some help.");
129 pline("You feel like someone is helping you.");
130 for(obj = invent; obj ; obj = obj->nobj)
132 obj->cursed = confused;
133 if(Punished && !confused) {
137 free((char *) uchain);
139 uball->owornmask &= ~W_BALL;
140 uchain = uball = (struct obj *) 0;
144 case SCR_CREATE_MONSTER:
147 if(!rn2(73)) cnt += rnd(4);
148 if(confused) cnt += 12;
150 (void) makemon(confused ? PM_ACID_BLOB :
151 (struct permonst *) 0, u.ux, u.uy);
154 case SCR_ENCHANT_WEAPON:
155 if(uwep && confused) {
156 pline("Your %s glows silver for a moment.",
157 objects[uwep->otyp].oc_name);
160 if(!chwepon(scroll, 1)) /* tests for !uwep */
163 case SCR_DAMAGE_WEAPON:
164 if(uwep && confused) {
165 pline("Your %s glows purple for a moment.",
166 objects[uwep->otyp].oc_name);
169 if(!chwepon(scroll, -1)) /* tests for !uwep */
174 int bd = confused ? 5 : 1;
177 for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
178 if(mtmp = m_at(u.ux+i, u.uy+j))
179 (void) tamedog(mtmp, (struct obj *) 0);
183 { extern char genocided[], fut_geno[];
185 struct monst *mtmp, *mtmp2;
187 pline("You have found a scroll of genocide!");
192 pline("What monster do you want to genocide (Type the letter)? ");
194 } while(strlen(buf) != 1 || !monstersym(*buf));
195 if(!index(fut_geno, *buf))
196 charcat(fut_geno, *buf);
197 if(!index(genocided, *buf))
198 charcat(genocided, *buf);
200 pline("Such monsters do not exist in this world.");
203 for(mtmp = fmon; mtmp; mtmp = mtmp2){
205 if(mtmp->data->mlet == *buf)
208 pline("Wiped out all %c's.", *buf);
210 killer = "scroll of genocide";
216 if(!Blind) known = TRUE;
219 case SCR_TELEPORTATION:
224 int oux = u.ux, ouy = u.uy;
226 if(dist(oux, ouy) > 100) known = TRUE;
228 int uroom = inroom(u.ux, u.uy);
230 if(uroom != inroom(u.ux, u.uy)) known = TRUE;
234 case SCR_GOLD_DETECTION:
235 /* Unfortunately this code has become slightly less elegant,
236 now that gold and traps no longer are of the same type. */
241 strange_feeling(scroll, "Your toes stop itching.");
244 for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
245 if(ttmp->tx != u.ux || ttmp->ty != u.uy)
247 /* only under me - no separate display required */
248 pline("Your toes itch!");
252 for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
253 at(ttmp->tx, ttmp->ty, '$');
255 pline("You feel very greedy!");
261 strange_feeling(scroll, "You feel materially poor.");
265 for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
266 if(gtmp->gx != u.ux || gtmp->gy != u.uy)
268 /* only under me - no separate display required */
269 pline("You notice some gold between your feet.");
273 for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
274 at(gtmp->gx, gtmp->gy, '$');
276 pline("You feel very greedy, and sense gold!");
283 case SCR_FOOD_DETECTION:
284 { int ct = 0, ctu = 0;
286 char foodsym = confused ? POTION_SYM : FOOD_SYM;
288 for(obj = fobj; obj; obj = obj->nobj)
289 if(obj->olet == FOOD_SYM) {
290 if(obj->ox == u.ux && obj->oy == u.uy) ctu++;
294 strange_feeling(scroll,"Your nose twitches.");
298 pline("You smell %s close nearby.",
299 confused ? "something" : "food");
304 for(obj = fobj; obj; obj = obj->nobj)
305 if(obj->olet == foodsym)
306 at(obj->ox, obj->oy, FOOD_SYM);
308 pline("Your nose tingles and you smell %s!",
309 confused ? "something" : "food");
318 pline("You identify this as an identify scroll.");
320 pline("This is an identify scroll.");
322 objects[SCR_IDENTIFY].oc_name_known = 1;
325 !ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
329 case SCR_MAGIC_MAPPING:
334 pline("On this scroll %s a map!",
335 confused ? "was" : "is");
336 for(zy = 0; zy < ROWNO; zy++)
337 for(zx = 0; zx < COLNO; zx++) {
338 if(confused && rn2(7)) continue;
339 lev = &(levl[zx][zy]);
340 if((num = lev->typ) == 0)
344 lev->scrsym = CORR_SYM;
349 /* do sth in doors ? */
350 } else if(lev->seen) continue;
355 lev->seen = lev->new = 1;
356 if(lev->scrsym == ' ' || !lev->scrsym)
368 for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
369 if(!confused || rn2(7))
371 levl[zx][zy].seen = 0;
373 pline("Thinking of Maud you forget everything else.");
382 pline("The scroll catches fire and you burn your hands.");
383 losehp(1, "scroll of fire");
385 pline("The scroll erupts in a tower of flame!");
387 pline("You are uninjured.");
391 losehp(num, "scroll of fire");
395 for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
396 if(dist(mtmp->mx,mtmp->my) < 3) {
398 if(index("FY", mtmp->data->mlet))
399 mtmp->mhp -= 3*num; /* this might well kill 'F's */
402 break; /* primitive */
411 pline("You feel guilty.");
414 pline("You are being punished for your misbehaviour!");
416 pline("Your iron ball gets heavier.");
420 Punished = INTRINSIC;
421 setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
422 setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
423 uball->spe = 1; /* special ball (see save) */
426 impossible("What weird language is this written in? (%u)",
429 if(!objects[scroll->otyp].oc_name_known) {
430 if(known && !confused) {
431 objects[scroll->otyp].oc_name_known = 1;
432 more_experienced(0,10);
433 } else if(!objects[scroll->otyp].oc_uname)
440 identify(otmp) /* also called by newmail() */
443 objects[otmp->otyp].oc_name_known = 1;
444 otmp->known = otmp->dknown = 1;
454 /* first produce the text (provided he is not blind) */
455 if(Blind) goto do_it;
457 if(u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||
458 !levl[u.ux][u.uy].lit) {
459 pline("It seems even darker in here than before.");
462 pline("It suddenly becomes dark in here.");
465 pline("%s's stomach is lit.", Monnam(u.ustuck));
469 pline("Nothing Happens.");
473 pline("The cave lights up around you, then fades.");
476 if(levl[u.ux][u.uy].typ == CORR) {
477 pline("The corridor lights up around you, then fades.");
479 } else if(levl[u.ux][u.uy].lit) {
480 pline("The light here seems better now.");
483 pline("The room is lit.");
491 if(levl[u.ux][u.uy].lit == on)
493 if(levl[u.ux][u.uy].typ == DOOR) {
494 if(IS_ROOM(levl[u.ux][u.uy+1].typ)) zy = u.uy+1;
495 else if(IS_ROOM(levl[u.ux][u.uy-1].typ)) zy = u.uy-1;
497 if(IS_ROOM(levl[u.ux+1][u.uy].typ)) zx = u.ux+1;
498 else if(IS_ROOM(levl[u.ux-1][u.uy].typ)) zx = u.ux-1;
504 for(seelx = u.ux; (num = levl[seelx-1][zy].typ) != CORR && num != 0;
506 for(seehx = u.ux; (num = levl[seehx+1][zy].typ) != CORR && num != 0;
508 for(seely = u.uy; (num = levl[zx][seely-1].typ) != CORR && num != 0;
510 for(seehy = u.uy; (num = levl[zx][seehy+1].typ) != CORR && num != 0;
512 for(zy = seely; zy <= seehy; zy++)
513 for(zx = seelx; zx <= seehx; zx++) {
514 levl[zx][zy].lit = on;
515 if(!Blind && dist(zx,zy) > 2) {
516 if(on) prl(zx,zy); else nosee(zx,zy);
523 /* Test whether we may genocide all monsters with symbol ch */
524 monstersym(ch) /* arnold@ucsfcgl */
528 extern struct permonst pm_eel;
531 * can't genocide certain monsters
533 if (index("12 &:", ch))
536 if (ch == pm_eel.mlet)
538 for (mp = mons; mp < &mons[CMNUM+2]; mp++)