123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648 |
- /* $NetBSD: hack.read.c,v 1.8 2003/04/02 18:36:39 jsm Exp $ */
- /*
- * Copyright (c) 1985, Stichting Centrum voor Wiskunde en Informatica,
- * Amsterdam
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of the Stichting Centrum voor Wiskunde en
- * Informatica, nor the names of its contributors may be used to endorse or
- * promote products derived from this software without specific prior
- * written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
- * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /*
- * Copyright (c) 1982 Jay Fenlason <hack@gnu.org>
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- * derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
- * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
- * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include <sys/cdefs.h>
- #ifndef lint
- __RCSID("$NetBSD: hack.read.c,v 1.8 2003/04/02 18:36:39 jsm Exp $");
- #endif /* not lint */
- #include <stdlib.h>
- #include "hack.h"
- #include "extern.h"
- int
- doread()
- {
- struct obj *scroll;
- boolean confused = (Confusion != 0);
- boolean known = FALSE;
- scroll = getobj("?", "read");
- if (!scroll)
- return (0);
- if (!scroll->dknown && Blind) {
- pline("Being blind, you cannot read the formula on the scroll.");
- return (0);
- }
- if (Blind)
- pline("As you pronounce the formula on it, the scroll disappears.");
- else
- pline("As you read the scroll, it disappears.");
- if (confused)
- pline("Being confused, you mispronounce the magic words ... ");
- switch (scroll->otyp) {
- #ifdef MAIL
- case SCR_MAIL:
- readmail( /* scroll */ );
- break;
- #endif /* MAIL */
- case SCR_ENCHANT_ARMOR:
- {
- struct obj *otmp = some_armor();
- if (!otmp) {
- strange_feeling(scroll, "Your skin glows then fades.");
- return (1);
- }
- if (confused) {
- pline("Your %s glows silver for a moment.",
- objects[otmp->otyp].oc_name);
- otmp->rustfree = 1;
- break;
- }
- if (otmp->spe > 3 && rn2(otmp->spe)) {
- pline("Your %s glows violently green for a while, then evaporates.",
- objects[otmp->otyp].oc_name);
- useup(otmp);
- break;
- }
- pline("Your %s glows green for a moment.",
- objects[otmp->otyp].oc_name);
- otmp->cursed = 0;
- otmp->spe++;
- break;
- }
- case SCR_DESTROY_ARMOR:
- if (confused) {
- struct obj *otmp = some_armor();
- if (!otmp) {
- strange_feeling(scroll, "Your bones itch.");
- return (1);
- }
- pline("Your %s glows purple for a moment.",
- objects[otmp->otyp].oc_name);
- otmp->rustfree = 0;
- break;
- }
- if (uarm) {
- pline("Your armor turns to dust and falls to the floor!");
- useup(uarm);
- } else if (uarmh) {
- pline("Your helmet turns to dust and is blown away!");
- useup(uarmh);
- } else if (uarmg) {
- pline("Your gloves vanish!");
- useup(uarmg);
- selftouch("You");
- } else {
- strange_feeling(scroll, "Your skin itches.");
- return (1);
- }
- break;
- case SCR_CONFUSE_MONSTER:
- if (confused) {
- pline("Your hands begin to glow purple.");
- Confusion += rnd(100);
- } else {
- pline("Your hands begin to glow blue.");
- u.umconf = 1;
- }
- break;
- case SCR_SCARE_MONSTER:
- {
- int ct = 0;
- struct monst *mtmp;
- for (mtmp = fmon; mtmp; mtmp = mtmp->nmon)
- if (cansee(mtmp->mx, mtmp->my)) {
- if (confused)
- mtmp->mflee = mtmp->mfroz =
- mtmp->msleep = 0;
- else
- mtmp->mflee = 1;
- ct++;
- }
- if (!ct) {
- if (confused)
- pline("You hear sad wailing in the distance.");
- else
- pline("You hear maniacal laughter in the distance.");
- }
- break;
- }
- case SCR_BLANK_PAPER:
- if (confused)
- pline("You see strange patterns on this scroll.");
- else
- pline("This scroll seems to be blank.");
- break;
- case SCR_REMOVE_CURSE:
- {
- struct obj *obj;
- if (confused)
- pline("You feel like you need some help.");
- else
- pline("You feel like someone is helping you.");
- for (obj = invent; obj; obj = obj->nobj)
- if (obj->owornmask)
- obj->cursed = confused;
- if (Punished && !confused) {
- Punished = 0;
- freeobj(uchain);
- unpobj(uchain);
- free((char *) uchain);
- uball->spe = 0;
- uball->owornmask &= ~W_BALL;
- uchain = uball = (struct obj *) 0;
- }
- break;
- }
- case SCR_CREATE_MONSTER:
- {
- int cnt = 1;
- if (!rn2(73))
- cnt += rnd(4);
- if (confused)
- cnt += 12;
- while (cnt--)
- (void) makemon(confused ? PM_ACID_BLOB :
- (struct permonst *) 0, u.ux, u.uy);
- break;
- }
- case SCR_ENCHANT_WEAPON:
- if (uwep && confused) {
- pline("Your %s glows silver for a moment.",
- objects[uwep->otyp].oc_name);
- uwep->rustfree = 1;
- } else if (!chwepon(scroll, 1)) /* tests for !uwep */
- return (1);
- break;
- case SCR_DAMAGE_WEAPON:
- if (uwep && confused) {
- pline("Your %s glows purple for a moment.",
- objects[uwep->otyp].oc_name);
- uwep->rustfree = 0;
- } else if (!chwepon(scroll, -1)) /* tests for !uwep */
- return (1);
- break;
- case SCR_TAMING:
- {
- int i, j;
- int bd = confused ? 5 : 1;
- struct monst *mtmp;
- for (i = -bd; i <= bd; i++)
- for (j = -bd; j <= bd; j++)
- if ((mtmp = m_at(u.ux + i, u.uy + j)) != NULL)
- (void) tamedog(mtmp, (struct obj *) 0);
- break;
- }
- case SCR_GENOCIDE:
- {
- char buf[BUFSZ];
- struct monst *mtmp, *mtmp2;
- pline("You have found a scroll of genocide!");
- known = TRUE;
- if (confused)
- *buf = u.usym;
- else
- do {
- pline("What monster do you want to genocide (Type the letter)? ");
- getlin(buf);
- } while (strlen(buf) != 1 || !monstersym(*buf));
- if (!strchr(fut_geno, *buf))
- charcat(fut_geno, *buf);
- if (!strchr(genocided, *buf))
- charcat(genocided, *buf);
- else {
- pline("Such monsters do not exist in this world.");
- break;
- }
- for (mtmp = fmon; mtmp; mtmp = mtmp2) {
- mtmp2 = mtmp->nmon;
- if (mtmp->data->mlet == *buf)
- mondead(mtmp);
- }
- pline("Wiped out all %c's.", *buf);
- if (*buf == u.usym) {
- killer = "scroll of genocide";
- u.uhp = -1;
- }
- break;
- }
- case SCR_LIGHT:
- if (!Blind)
- known = TRUE;
- litroom(!confused);
- break;
- case SCR_TELEPORTATION:
- if (confused)
- level_tele();
- else {
- #ifdef QUEST
- int oux = u.ux, ouy = u.uy;
- tele();
- if (dist(oux, ouy) > 100)
- known = TRUE;
- #else /* QUEST */
- int uroom = inroom(u.ux, u.uy);
- tele();
- if (uroom != inroom(u.ux, u.uy))
- known = TRUE;
- #endif /* QUEST */
- }
- break;
- case SCR_GOLD_DETECTION:
- /*
- * Unfortunately this code has become slightly less elegant,
- * now that gold and traps no longer are of the same type.
- */
- if (confused) {
- struct trap *ttmp;
- if (!ftrap) {
- strange_feeling(scroll, "Your toes stop itching.");
- return (1);
- } else {
- for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
- if (ttmp->tx != u.ux || ttmp->ty != u.uy)
- goto outtrapmap;
- /*
- * only under me - no separate display
- * required
- */
- pline("Your toes itch!");
- break;
- outtrapmap:
- cls();
- for (ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
- at(ttmp->tx, ttmp->ty, '$');
- prme();
- pline("You feel very greedy!");
- }
- } else {
- struct gold *gtmp;
- if (!fgold) {
- strange_feeling(scroll, "You feel materially poor.");
- return (1);
- } else {
- known = TRUE;
- for (gtmp = fgold; gtmp; gtmp = gtmp->ngold)
- if (gtmp->gx != u.ux || gtmp->gy != u.uy)
- goto outgoldmap;
- /*
- * only under me - no separate display
- * required
- */
- pline("You notice some gold between your feet.");
- break;
- outgoldmap:
- cls();
- for (gtmp = fgold; gtmp; gtmp = gtmp->ngold)
- at(gtmp->gx, gtmp->gy, '$');
- prme();
- pline("You feel very greedy, and sense gold!");
- }
- }
- /* common sequel */
- more();
- docrt();
- break;
- case SCR_FOOD_DETECTION:
- {
- int ct = 0, ctu = 0;
- struct obj *obj;
- char foodsym = confused ? POTION_SYM : FOOD_SYM;
- for (obj = fobj; obj; obj = obj->nobj)
- if (obj->olet == FOOD_SYM) {
- if (obj->ox == u.ux && obj->oy == u.uy)
- ctu++;
- else
- ct++;
- }
- if (!ct && !ctu) {
- strange_feeling(scroll, "Your nose twitches.");
- return (1);
- } else if (!ct) {
- known = TRUE;
- pline("You smell %s close nearby.",
- confused ? "something" : "food");
- } else {
- known = TRUE;
- cls();
- for (obj = fobj; obj; obj = obj->nobj)
- if (obj->olet == foodsym)
- at(obj->ox, obj->oy, FOOD_SYM);
- prme();
- pline("Your nose tingles and you smell %s!",
- confused ? "something" : "food");
- more();
- docrt();
- }
- break;
- }
- case SCR_IDENTIFY:
- /* known = TRUE; */
- if (confused)
- pline("You identify this as an identify scroll.");
- else
- pline("This is an identify scroll.");
- useup(scroll);
- objects[SCR_IDENTIFY].oc_name_known = 1;
- if (!confused)
- while (
- !ggetobj("identify", identify, rn2(5) ? 1 : rn2(5))
- && invent
- );
- return (1);
- case SCR_MAGIC_MAPPING:
- {
- struct rm *lev;
- int num, zx, zy;
- known = TRUE;
- pline("On this scroll %s a map!",
- confused ? "was" : "is");
- for (zy = 0; zy < ROWNO; zy++)
- for (zx = 0; zx < COLNO; zx++) {
- if (confused && rn2(7))
- continue;
- lev = &(levl[zx][zy]);
- if ((num = lev->typ) == 0)
- continue;
- if (num == SCORR) {
- lev->typ = CORR;
- lev->scrsym = CORR_SYM;
- } else if (num == SDOOR) {
- lev->typ = DOOR;
- lev->scrsym = '+';
- /* do sth in doors ? */
- } else if (lev->seen)
- continue;
- #ifndef QUEST
- if (num != ROOM)
- #endif /* QUEST */
- {
- lev->seen = lev->new = 1;
- if (lev->scrsym == ' ' || !lev->scrsym)
- newsym(zx, zy);
- else
- on_scr(zx, zy);
- }
- }
- break;
- }
- case SCR_AMNESIA:
- {
- int zx, zy;
- known = TRUE;
- for (zx = 0; zx < COLNO; zx++)
- for (zy = 0; zy < ROWNO; zy++)
- if (!confused || rn2(7))
- if (!cansee(zx, zy))
- levl[zx][zy].seen = 0;
- docrt();
- pline("Thinking of Maud you forget everything else.");
- break;
- }
- case SCR_FIRE:
- {
- int num = 0;
- struct monst *mtmp;
- known = TRUE;
- if (confused) {
- pline("The scroll catches fire and you burn your hands.");
- losehp(1, "scroll of fire");
- } else {
- pline("The scroll erupts in a tower of flame!");
- if (Fire_resistance)
- pline("You are uninjured.");
- else {
- num = rnd(6);
- u.uhpmax -= num;
- losehp(num, "scroll of fire");
- }
- }
- num = (2 * num + 1) / 3;
- for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
- if (dist(mtmp->mx, mtmp->my) < 3) {
- mtmp->mhp -= num;
- if (strchr("FY", mtmp->data->mlet))
- mtmp->mhp -= 3 * num; /* this might well kill
- * 'F's */
- if (mtmp->mhp < 1) {
- killed(mtmp);
- break; /* primitive */
- }
- }
- }
- break;
- }
- case SCR_PUNISHMENT:
- known = TRUE;
- if (confused) {
- pline("You feel guilty.");
- break;
- }
- pline("You are being punished for your misbehaviour!");
- if (Punished) {
- pline("Your iron ball gets heavier.");
- uball->owt += 15;
- break;
- }
- Punished = INTRINSIC;
- setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
- setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
- uball->spe = 1; /* special ball (see save) */
- break;
- default:
- impossible("What weird language is this written in? (%u)",
- scroll->otyp);
- }
- if (!objects[scroll->otyp].oc_name_known) {
- if (known && !confused) {
- objects[scroll->otyp].oc_name_known = 1;
- more_experienced(0, 10);
- } else if (!objects[scroll->otyp].oc_uname)
- docall(scroll);
- }
- useup(scroll);
- return (1);
- }
- int
- identify(otmp) /* also called by newmail() */
- struct obj *otmp;
- {
- objects[otmp->otyp].oc_name_known = 1;
- otmp->known = otmp->dknown = 1;
- prinv(otmp);
- return (1);
- }
- void
- litroom(on)
- boolean on;
- {
- #ifndef QUEST
- int num, zx, zy;
- #endif
- /* first produce the text (provided he is not blind) */
- if (Blind)
- goto do_it;
- if (!on) {
- if (u.uswallow || !xdnstair || levl[u.ux][u.uy].typ == CORR ||
- !levl[u.ux][u.uy].lit) {
- pline("It seems even darker in here than before.");
- return;
- } else
- pline("It suddenly becomes dark in here.");
- } else {
- if (u.uswallow) {
- pline("%s's stomach is lit.", Monnam(u.ustuck));
- return;
- }
- if (!xdnstair) {
- pline("Nothing Happens.");
- return;
- }
- #ifdef QUEST
- pline("The cave lights up around you, then fades.");
- return;
- #else /* QUEST */
- if (levl[u.ux][u.uy].typ == CORR) {
- pline("The corridor lights up around you, then fades.");
- return;
- } else if (levl[u.ux][u.uy].lit) {
- pline("The light here seems better now.");
- return;
- } else
- pline("The room is lit.");
- #endif /* QUEST */
- }
- do_it:
- #ifdef QUEST
- return;
- #else /* QUEST */
- if (levl[u.ux][u.uy].lit == on)
- return;
- if (levl[u.ux][u.uy].typ == DOOR) {
- if (IS_ROOM(levl[u.ux][u.uy + 1].typ))
- zy = u.uy + 1;
- else if (IS_ROOM(levl[u.ux][u.uy - 1].typ))
- zy = u.uy - 1;
- else
- zy = u.uy;
- if (IS_ROOM(levl[u.ux + 1][u.uy].typ))
- zx = u.ux + 1;
- else if (IS_ROOM(levl[u.ux - 1][u.uy].typ))
- zx = u.ux - 1;
- else
- zx = u.ux;
- } else {
- zx = u.ux;
- zy = u.uy;
- }
- for (seelx = u.ux; (num = levl[seelx - 1][zy].typ) != CORR && num != 0;
- seelx--);
- for (seehx = u.ux; (num = levl[seehx + 1][zy].typ) != CORR && num != 0;
- seehx++);
- for (seely = u.uy; (num = levl[zx][seely - 1].typ) != CORR && num != 0;
- seely--);
- for (seehy = u.uy; (num = levl[zx][seehy + 1].typ) != CORR && num != 0;
- seehy++);
- for (zy = seely; zy <= seehy; zy++)
- for (zx = seelx; zx <= seehx; zx++) {
- levl[zx][zy].lit = on;
- if (!Blind && dist(zx, zy) > 2) {
- if (on)
- prl(zx, zy);
- else
- nosee(zx, zy);
- }
- }
- if (!on)
- seehx = 0;
- #endif /* QUEST */
- }
- /* Test whether we may genocide all monsters with symbol ch */
- int
- monstersym(ch) /* arnold@ucsfcgl */
- char ch;
- {
- const struct permonst *mp;
- /*
- * can't genocide certain monsters
- */
- if (strchr("12 &:", ch))
- return FALSE;
- if (ch == pm_eel.mlet)
- return TRUE;
- for (mp = mons; mp < &mons[CMNUM + 2]; mp++)
- if (mp->mlet == ch)
- return TRUE;
- return FALSE;
- }
|