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.4 2006/08/21 19:45:32 pavalos Exp $ */
8 static bool monstersym(char);
14 boolean confused = (Confusion != 0);
15 boolean known = FALSE;
17 scroll = getobj("?", "read");
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:
39 struct obj *otmp = some_armor();
41 strange_feeling(scroll, "Your skin glows then fades.");
45 pline("Your %s glows silver for a moment.",
46 objects[otmp->otyp].oc_name);
50 if (otmp->spe > 3 && rn2(otmp->spe)) {
51 pline("Your %s glows violently green for a while, then evaporates.",
52 objects[otmp->otyp].oc_name);
56 pline("Your %s glows green for a moment.",
57 objects[otmp->otyp].oc_name);
62 case SCR_DESTROY_ARMOR:
64 struct obj *otmp = some_armor();
66 strange_feeling(scroll, "Your bones itch.");
69 pline("Your %s glows purple for a moment.",
70 objects[otmp->otyp].oc_name);
75 pline("Your armor turns to dust and falls to the floor!");
78 pline("Your helmet turns to dust and is blown away!");
81 pline("Your gloves vanish!");
85 strange_feeling(scroll, "Your skin itches.");
89 case SCR_CONFUSE_MONSTER:
91 pline("Your hands begin to glow purple.");
92 Confusion += rnd(100);
94 pline("Your hands begin to glow blue.");
98 case SCR_SCARE_MONSTER:
103 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
104 if (cansee(mtmp->mx, mtmp->my)) {
106 mtmp->mflee = mtmp->mfroz =
114 pline("You hear sad wailing in the distance.");
116 pline("You hear maniacal laughter in the distance.");
120 case SCR_BLANK_PAPER:
122 pline("You see strange patterns on this scroll.");
124 pline("This scroll seems to be blank.");
126 case SCR_REMOVE_CURSE:
130 pline("You feel like you need some help.");
132 pline("You feel like someone is helping you.");
133 for (obj = invent; obj; obj = obj->nobj)
135 obj->cursed = confused;
136 if (Punished && !confused) {
142 uball->owornmask &= ~W_BALL;
143 uchain = uball = NULL;
147 case SCR_CREATE_MONSTER:
156 makemon(confused ? PM_ACID_BLOB :
160 case SCR_ENCHANT_WEAPON:
161 if (uwep && confused) {
162 pline("Your %s glows silver for a moment.",
163 objects[uwep->otyp].oc_name);
165 } else if (!chwepon(scroll, 1)) /* tests for !uwep */
168 case SCR_DAMAGE_WEAPON:
169 if (uwep && confused) {
170 pline("Your %s glows purple for a moment.",
171 objects[uwep->otyp].oc_name);
173 } else if (!chwepon(scroll, -1)) /* tests for !uwep */
179 int bd = confused ? 5 : 1;
182 for (i = -bd; i <= bd; i++)
183 for (j = -bd; j <= bd; j++)
184 if ((mtmp = m_at(u.ux + i, u.uy + j)))
191 struct monst *mtmp, *mtmp2;
193 pline("You have found a scroll of genocide!");
199 pline("What monster do you want to genocide (Type the letter)? ");
201 } while (strlen(buf) != 1 || !monstersym(*buf));
202 if (!strchr(fut_geno, *buf))
203 charcat(fut_geno, *buf);
204 if (!strchr(genocided, *buf))
205 charcat(genocided, *buf);
207 pline("Such monsters do not exist in this world.");
210 for (mtmp = fmon; mtmp; mtmp = mtmp2) {
212 if (mtmp->data->mlet == *buf)
215 pline("Wiped out all %c's.", *buf);
216 if (*buf == u.usym) {
217 killer = "scroll of genocide";
227 case SCR_TELEPORTATION:
232 int oux = u.ux, ouy = u.uy;
234 if (dist(oux, ouy) > 100)
237 int uroom = inroom(u.ux, u.uy);
239 if (uroom != inroom(u.ux, u.uy))
244 case SCR_GOLD_DETECTION:
246 * Unfortunately this code has become slightly less elegant,
247 * now that gold and traps no longer are of the same type.
253 strange_feeling(scroll, "Your toes stop itching.");
256 for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
257 if (ttmp->tx != u.ux || ttmp->ty != u.uy)
259 /* only under me - no separate display required */
260 pline("Your toes itch!");
264 for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
265 at(ttmp->tx, ttmp->ty, '$');
267 pline("You feel very greedy!");
273 strange_feeling(scroll, "You feel materially poor.");
277 for (gtmp = fgold; gtmp; gtmp = gtmp->ngold)
278 if (gtmp->gx != u.ux || gtmp->gy != u.uy)
280 /* only under me - no separate display required */
281 pline("You notice some gold between your feet.");
285 for (gtmp = fgold; gtmp; gtmp = gtmp->ngold)
286 at(gtmp->gx, gtmp->gy, '$');
288 pline("You feel very greedy, and sense gold!");
295 case SCR_FOOD_DETECTION:
299 char foodsym = confused ? POTION_SYM : FOOD_SYM;
301 for (obj = fobj; obj; obj = obj->nobj)
302 if (obj->olet == FOOD_SYM) {
303 if (obj->ox == u.ux && obj->oy == u.uy)
309 strange_feeling(scroll, "Your nose twitches.");
313 pline("You smell %s close nearby.",
314 confused ? "something" : "food");
318 for (obj = fobj; obj; obj = obj->nobj)
319 if (obj->olet == foodsym)
320 at(obj->ox, obj->oy, FOOD_SYM);
322 pline("Your nose tingles and you smell %s!",
323 confused ? "something" : "food");
332 pline("You identify this as an identify scroll.");
334 pline("This is an identify scroll.");
336 objects[SCR_IDENTIFY].oc_name_known = 1;
338 while (!ggetobj("identify", identify,
339 rn2(5) ? 1 : rn2(5)) && invent)
342 case SCR_MAGIC_MAPPING:
348 pline("On this scroll %s a map!",
349 confused ? "was" : "is");
350 for (zy = 0; zy < ROWNO; zy++)
351 for (zx = 0; zx < COLNO; zx++) {
352 if (confused && rn2(7))
354 lev = &(levl[zx][zy]);
355 if ((num = lev->typ) == 0)
359 lev->scrsym = CORR_SYM;
360 } else if (num == SDOOR) {
363 /* do sth in doors ? */
364 } else if (lev->seen)
370 lev->seen = lev->new = 1;
371 if (lev->scrsym == ' ' || !lev->scrsym)
384 for (zx = 0; zx < COLNO; zx++)
385 for (zy = 0; zy < ROWNO; zy++)
386 if (!confused || rn2(7))
388 levl[zx][zy].seen = 0;
390 pline("Thinking of Maud you forget everything else.");
400 pline("The scroll catches fire and you burn your hands.");
401 losehp(1, "scroll of fire");
403 pline("The scroll erupts in a tower of flame!");
405 pline("You are uninjured.");
409 losehp(num, "scroll of fire");
412 num = (2 * num + 1) / 3;
413 for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
414 if (dist(mtmp->mx, mtmp->my) < 3) {
416 if (strchr("FY", mtmp->data->mlet))
417 mtmp->mhp -= 3 * num; /* this might well kill 'F's */
420 break; /* primitive */
429 pline("You feel guilty.");
432 pline("You are being punished for your misbehaviour!");
434 pline("Your iron ball gets heavier.");
438 Punished = INTRINSIC;
439 setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
440 setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
441 uball->spe = 1; /* special ball (see save) */
444 impossible("What weird language is this written in? (%u)",
447 if (!objects[scroll->otyp].oc_name_known) {
448 if (known && !confused) {
449 objects[scroll->otyp].oc_name_known = 1;
450 more_experienced(0, 10);
451 } else if (!objects[scroll->otyp].oc_uname)
459 identify(struct obj *otmp) /* also called by newmail() */
461 objects[otmp->otyp].oc_name_known = 1;
462 otmp->known = otmp->dknown = 1;
474 /* first produce the text (provided he is not blind) */
478 if (u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||
479 !levl[u.ux][u.uy].lit) {
480 pline("It seems even darker in here than before.");
483 pline("It suddenly becomes dark in here.");
486 pline("%s's stomach is lit.", Monnam(u.ustuck));
490 pline("Nothing Happens.");
494 pline("The cave lights up around you, then fades.");
497 if (levl[u.ux][u.uy].typ == CORR) {
498 pline("The corridor lights up around you, then fades.");
500 } else if (levl[u.ux][u.uy].lit) {
501 pline("The light here seems better now.");
504 pline("The room is lit.");
512 if (levl[u.ux][u.uy].lit == on)
514 if (levl[u.ux][u.uy].typ == DOOR) {
515 if (IS_ROOM(levl[u.ux][u.uy + 1].typ))
517 else if (IS_ROOM(levl[u.ux][u.uy - 1].typ))
521 if (IS_ROOM(levl[u.ux + 1][u.uy].typ))
523 else if (IS_ROOM(levl[u.ux - 1][u.uy].typ))
531 for (seelx = u.ux; (num = levl[seelx - 1][zy].typ) != CORR && num != 0;
533 for (seehx = u.ux; (num = levl[seehx + 1][zy].typ) != CORR && num != 0;
535 for (seely = u.uy; (num = levl[zx][seely - 1].typ) != CORR && num != 0;
537 for (seehy = u.uy; (num = levl[zx][seehy + 1].typ) != CORR && num != 0;
539 for (zy = seely; zy <= seehy; zy++)
540 for (zx = seelx; zx <= seehx; zx++) {
541 levl[zx][zy].lit = on;
542 if (!Blind && dist(zx, zy) > 2) {
554 /* Test whether we may genocide all monsters with symbol ch */
556 monstersym(char ch) /* arnold@ucsfcgl */
561 * can't genocide certain monsters
563 if (strchr("12 &:", ch))
566 if (ch == pm_eel.mlet)
568 for (mp = mons; mp < &mons[CMNUM + 2]; mp++)