From 013ac7742311556022304e8b30ca170d48b3a016 Mon Sep 17 00:00:00 2001 From: "B. Watson" Date: Thu, 7 May 2015 16:32:32 -0400 Subject: initial commit --- hack/hack.read.c | 572 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 572 insertions(+) create mode 100644 hack/hack.read.c (limited to 'hack/hack.read.c') diff --git a/hack/hack.read.c b/hack/hack.read.c new file mode 100644 index 0000000..6f74d26 --- /dev/null +++ b/hack/hack.read.c @@ -0,0 +1,572 @@ +/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ +/* hack.read.c - version 1.0.3 */ +/* $FreeBSD: src/games/hack/hack.read.c,v 1.6 1999/11/16 10:26:37 marcel Exp $ */ +/* $DragonFly: src/games/hack/hack.read.c,v 1.4 2006/08/21 19:45:32 pavalos Exp $ */ + +#include "hack.h" + +static bool monstersym(char); + +int +doread(void) +{ + 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(uchain); + uball->spe = 0; + uball->owornmask &= ~W_BALL; + uchain = uball = NULL; + } + break; + } + case SCR_CREATE_MONSTER: + { + int cnt = 1; + + if (!rn2(73)) + cnt += rnd(4); + if (confused) + cnt += 12; + while (cnt--) + makemon(confused ? PM_ACID_BLOB : + NULL, 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))) + tamedog(mtmp, NULL); + 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) + ; /* nothing */ + 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(struct obj *otmp) /* also called by newmail() */ +{ + objects[otmp->otyp].oc_name_known = 1; + otmp->known = otmp->dknown = 1; + prinv(otmp); + return (1); +} + +void +litroom(bool 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 */ +static bool +monstersym(char ch) /* arnold@ucsfcgl */ +{ + 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); +} -- cgit v1.2.3