diff options
author | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
---|---|---|
committer | Theo de Raadt <deraadt@cvs.openbsd.org> | 1995-10-18 08:53:40 +0000 |
commit | d6583bb2a13f329cf0332ef2570eb8bb8fc0e39c (patch) | |
tree | ece253b876159b39c620e62b6c9b1174642e070e /games/hack/hack.read.c |
initial import of NetBSD tree
Diffstat (limited to 'games/hack/hack.read.c')
-rw-r--r-- | games/hack/hack.read.c | 544 |
1 files changed, 544 insertions, 0 deletions
diff --git a/games/hack/hack.read.c b/games/hack/hack.read.c new file mode 100644 index 00000000000..7fbbf8a7e33 --- /dev/null +++ b/games/hack/hack.read.c @@ -0,0 +1,544 @@ +/* + * Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. + */ + +#ifndef lint +static char rcsid[] = "$NetBSD: hack.read.c,v 1.3 1995/03/23 08:31:22 cgd Exp $"; +#endif /* not lint */ + +#include "hack.h" + +extern struct monst *makemon(); +extern struct obj *mkobj_at(); +int identify(); + +doread() { + register struct obj *scroll; + register boolean confused = (Confusion != 0); + register boolean known = FALSE; + extern struct obj *some_armor(); + + 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: + { register 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) { + register 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: + { register int ct = 0; + register 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: + { register 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: + { register 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: + { register int i,j; + register int bd = confused ? 5 : 1; + register 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)) + (void) tamedog(mtmp, (struct obj *) 0); + break; + } + case SCR_GENOCIDE: + { extern char genocided[], fut_geno[]; + char buf[BUFSZ]; + register 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(!index(fut_geno, *buf)) + charcat(fut_geno, *buf); + if(!index(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 + register int oux = u.ux, ouy = u.uy; + tele(); + if(dist(oux, ouy) > 100) known = TRUE; +#else QUEST + register 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) { + register 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 { + register 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: + { register ct = 0, ctu = 0; + register struct obj *obj; + register 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: + { register struct rm *lev; + register 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: + { register 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: + { register int num; + register 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(index("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); +} + +identify(otmp) /* also called by newmail() */ +register struct obj *otmp; +{ + objects[otmp->otyp].oc_name_known = 1; + otmp->known = otmp->dknown = 1; + prinv(otmp); + return(1); +} + +litroom(on) +register boolean on; +{ + register num,zx,zy; + + /* 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 */ +monstersym(ch) /* arnold@ucsfcgl */ +register char ch; +{ + register struct permonst *mp; + extern struct permonst pm_eel; + + /* + * can't genocide certain monsters + */ + if (index("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; +} |