billr@saab.CNA.TEK.COM (Bill Randle) (12/19/90)
Submitted-by: routley@tle.ENET.DEC.COM (Kevin Routley)
Posting-number: Volume 11, Issue 87
Archive-name: larn/Part04
Environment: Unix, VMS, MS-DOS, termcap
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 4 (of 11)."
# Contents: monster.c object.c termcap.pc
# Wrapped by billr@saab on Tue Dec 18 10:14:18 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'monster.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'monster.c'\"
else
echo shar: Extracting \"'monster.c'\" \(21846 characters\)
sed "s/^X//" >'monster.c' <<'END_OF_FILE'
X/*
X * monster.c Larn is copyrighted 1986 by Noah Morgan.
X *
X * This file contains the following functions:
X * ----------------------------------------------------------------------------
X *
X * createmonster(monstno) Function to create a monster next to the player
X * int monstno;
X *
X * int cgood(x,y,itm,monst) Function to check location for emptiness
X * int x,y,itm,monst;
X *
X * createitem(it,arg) Routine to place an item next to the player
X * int it,arg;
X *
X * vxy(x,y) Routine to verify/fix (*x,*y) for being within bounds
X * int *x,*y;
X *
X * hitmonster(x,y) Function to hit a monster at the designated coordinates
X * int x,y;
X *
X * hitm(x,y,amt) Function to just hit a monster at a given coordinates
X * int x,y,amt;
X *
X * hitplayer(x,y) Function for the monster to hit the player from (x,y)
X * int x,y;
X *
X * dropsomething(monst) Function to create an object when a monster dies
X * int monst;
X *
X * dropgold(amount) Function to drop some gold around player
X * int amount;
X *
X * something(level) Function to create a random item around player
X * int level;
X *
X * newobject(lev,i) Routine to return a randomly selected new object
X * int lev,*i;
X *
X * spattack(atckno,xx,yy) Function to process special attacks from monsters
X * int atckno,xx,yy;
X *
X * checkloss(x) Routine to subtract hp from user and flag bottomline display
X * int x;
X *
X */
X#include "header.h"
X#include <ctype.h>
X#define min(x,y) (((x)>(y))?(y):(x))
X#define max(x,y) (((x)>(y))?(x):(y))
X
Xextern fullhit(), ifblind();
X
X/*
X * createmonster(monstno) Function to create a monster next to the player
X * int monstno;
X *
X * Enter with the monster number (1 to MAXMONST+8)
X * Returns no value.
X */
Xcreatemonster(mon)
X int mon;
X {
X register int x,y,k,i;
X if (mon<1 || mon>MAXMONST+8) /* check for monster number out of bounds */
X {
X beep(); lprintf("\ncan't createmonst(%d)\n",(long)mon); nap(3000); return;
X }
X while (monster[mon].genocided && mon<MAXMONST) mon++; /* genocided? */
X for (k=rnd(8), i= -8; i<0; i++,k++) /* choose direction, then try all */
X {
X if (k>8) k=1; /* wraparound the diroff arrays */
X x = playerx + diroffx[k]; y = playery + diroffy[k];
X if (cgood(x,y,0,1)) /* if we can create here */
X {
X mitem[x][y] = mon;
X hitp[x][y] = monster[mon].hitpoints;
X# ifdef DGK
X stealth[x][y]=0;
X know[x][y] &= ~KNOWHERE;
X# else
X stealth[x][y]=know[x][y]=0;
X# endif
X switch(mon)
X {
X case ROTHE: case POLTERGEIST: case VAMPIRE: stealth[x][y]=1;
X };
X return;
X }
X }
X }
X
X/*
X * int cgood(x,y,itm,monst) Function to check location for emptiness
X * int x,y,itm,monst;
X *
X * Routine to return TRUE if a location does not have itm or monst there
X * returns FALSE (0) otherwise
X * Enter with itm or monst TRUE or FALSE if checking it
X * Example: if itm==TRUE check for no item at this location
X * if monst==TRUE check for no monster at this location
X * This routine will return FALSE if at a wall,door or the dungeon exit
X * on level 1
X */
Xstatic int cgood(x,y,itm,monst)
X register int x,y;
X int itm,monst;
X {
X /* cannot create either monster or item if:
X - out of bounds
X - wall
X - closed door
X - dungeon entrance
X */
X if (((y < 0) || (y > MAXY-1) || (x < 0) || (x > MAXX-1)) ||
X (item[x][y] == OWALL) ||
X (item[x][y] == OCLOSEDDOOR) ||
X ((level == 1) && (x == 33) && (y == MAXY-1)))
X return( FALSE );
X
X /* if checking for an item, return False if one there already
X */
X if ( itm && item[x][y])
X return( FALSE );
X
X /* if checking for a monster, return False if one there already _or_
X there is a pit/trap there.
X */
X if (monst)
X {
X if (mitem[x][y])
X return (FALSE);
X switch(item[x][y])
X {
X /* note: not invisible traps, since monsters are not affected
X by them.
X */
X case OPIT: case OANNIHILATION:
X case OTELEPORTER: case OTRAPARROW:
X case ODARTRAP: case OTRAPDOOR:
X return(FALSE);
X break;
X default:
X break;
X }
X }
X return(TRUE);
X }
X
X/*
X * createitem(it,arg) Routine to place an item next to the player
X * int it,arg;
X *
X * Enter with the item number and its argument (iven[], ivenarg[])
X * Returns no value, thus we don't know about createitem() failures.
X */
Xcreateitem(it,arg)
X int it,arg;
X {
X register int x,y,k,i;
X if (it >= MAXOBJ) return; /* no such object */
X for (k=rnd(8), i= -8; i<0; i++,k++) /* choose direction, then try all */
X {
X if (k>8) k=1; /* wraparound the diroff arrays */
X x = playerx + diroffx[k]; y = playery + diroffy[k];
X if (cgood(x,y,1,0)) /* if we can create here */
X {
X item[x][y] = it; know[x][y]=0; iarg[x][y]=arg; return;
X }
X }
X }
X
X
X/*
X * vxy(x,y) Routine to verify/fix coordinates for being within bounds
X * int *x,*y;
X *
X * Function to verify x & y are within the bounds for a level
X * If *x or *y is not within the absolute bounds for a level, fix them so that
X * they are on the level.
X * Returns TRUE if it was out of bounds, and the *x & *y in the calling
X * routine are affected.
X */
Xvxy(x,y)
X int *x,*y;
X {
X int flag=0;
X if (*x<0) { *x=0; flag++; }
X if (*y<0) { *y=0; flag++; }
X if (*x>=MAXX) { *x=MAXX-1; flag++; }
X if (*y>=MAXY) { *y=MAXY-1; flag++; }
X return(flag);
X }
X
X/*
X * hitmonster(x,y) Function to hit a monster at the designated coordinates
X * int x,y;
X *
X * This routine is used for a bash & slash type attack on a monster
X * Enter with the coordinates of the monster in (x,y).
X * Returns no value.
X */
Xhitmonster(x,y)
X int x,y;
X {
X extern char lastmonst[] ;
X register int tmp,monst,damag,flag;
X if (c[TIMESTOP]) return; /* not if time stopped */
X vxy(&x,&y); /* verify coordinates are within range */
X if ((monst = mitem[x][y]) == 0) return;
X hit3flag=1; ifblind(x,y);
X tmp = monster[monst].armorclass + c[LEVEL] + c[DEXTERITY] + c[WCLASS]/4 - 12;
X cursors();
X if ((rnd(20) < tmp-c[HARDGAME]) || (rnd(71) < 5)) /* need at least random chance to hit */
X {
X lprcat("\nYou hit"); flag=1;
X damag = fullhit(1);
X if (damag<9999) damag=rnd(damag)+1;
X }
X else
X {
X lprcat("\nYou missed"); flag=0;
X }
X lprcat(" the "); lprcat(lastmonst);
X if (flag) /* if the monster was hit */
X if ((monst==RUSTMONSTER) || (monst==DISENCHANTRESS) || (monst==CUBE))
X if (c[WIELD]>0)
X if (ivenarg[c[WIELD]] > -10)
X {
X lprintf("\nYour weapon is dulled by the %s",lastmonst); beep();
X --ivenarg[c[WIELD]];
X
X /* fix for dulled rings of strength,cleverness, and dexterity
X bug.
X */
X switch (iven[c[WIELD]])
X {
X case ODEXRING :
X c[DEXTERITY]--;
X break;
X case OSTRRING :
X c[STREXTRA]--;
X break;
X case OCLEVERRING :
X c[INTELLIGENCE]--;
X break;
X }
X }
X if (flag) hitm(x,y,damag);
X if (monst == VAMPIRE) if (hitp[x][y]<25) { mitem[x][y]=BAT; know[x][y]=0; }
X }
X
X/*
X * hitm(x,y,amt) Function to just hit a monster at a given coordinates
X * int x,y,amt;
X *
X * Returns the number of hitpoints the monster absorbed
X * This routine is used to specifically damage a monster at a location (x,y)
X * Called by hitmonster(x,y)
X */
Xhitm(x,y,amt)
X int x,y;
X register amt;
X {
X extern char lastmonst[] ;
X register int monst;
X int hpoints,amt2;
X vxy(&x,&y); /* verify coordinates are within range */
X amt2 = amt; /* save initial damage so we can return it */
X monst = mitem[x][y];
X if (c[HALFDAM]) amt >>= 1; /* if half damage curse adjust damage points */
X if (amt<=0) amt2 = amt = 1;
X lasthx=x; lasthy=y;
X stealth[x][y]=1; /* make sure hitting monst breaks stealth condition */
X c[HOLDMONST]=0; /* hit a monster breaks hold monster spell */
X switch(monst) /* if a dragon and orb(s) of dragon slaying */
X {
X case WHITEDRAGON: case REDDRAGON: case GREENDRAGON:
X case BRONZEDRAGON: case PLATINUMDRAGON: case SILVERDRAGON:
X amt *= 1+(c[SLAYING]<<1); break;
X }
X/* invincible monster fix is here */
X if (hitp[x][y] > monster[monst].hitpoints)
X hitp[x][y] = monster[monst].hitpoints;
X if ((hpoints = hitp[x][y]) <= amt)
X {
X#ifdef EXTRA
X c[MONSTKILLED]++;
X#endif
X lprintf("\nThe %s died!",lastmonst);
X raiseexperience((long)monster[monst].experience);
X amt = monster[monst].gold; if (amt>0) dropgold(rnd(amt)+amt);
X dropsomething(monst); disappear(x,y); bottomline();
X return(hpoints);
X }
X hitp[x][y] = hpoints-amt; return(amt2);
X }
X
X/*
X * hitplayer(x,y) Function for the monster to hit the player from (x,y)
X * int x,y;
X *
X * Function for the monster to hit the player with monster at location x,y
X * Returns nothing of value.
X */
Xhitplayer(x,y)
X int x,y;
X {
X extern char lastmonst[] ;
X register int dam,tmp,mster,bias;
X vxy(&x,&y); /* verify coordinates are within range */
X lastnum = mster = mitem[x][y];
X/* spirit naga's and poltergeist's do nothing if scarab of negate spirit */
X if (c[NEGATESPIRIT] || c[SPIRITPRO]) if ((mster ==POLTERGEIST) || (mster ==SPIRITNAGA)) return;
X/* if undead and cube of undead control */
X if (c[CUBEofUNDEAD] || c[UNDEADPRO]) if ((mster ==VAMPIRE) || (mster ==WRAITH) || (mster ==ZOMBIE)) return;
X# ifdef DGK
X if ((know[x][y] & KNOWHERE) == 0)
X show1cell(x,y);
X# else
X if ((know[x][y]&1) == 0)
X {
X know[x][y]=1; show1cell(x,y);
X }
X# endif
X bias = (c[HARDGAME]) + 1;
X hitflag = hit2flag = hit3flag = 1;
X yrepcount=0;
X cursors(); ifblind(x,y);
X if (c[INVISIBILITY]) if (rnd(33)<20)
X {
X lprintf("\nThe %s misses wildly",lastmonst); return;
X }
X if (c[CHARMCOUNT]) if (rnd(30)+5*monster[mster].level-c[CHARISMA]<30)
X {
X lprintf("\nThe %s is awestruck at your magnificence!",lastmonst);
X return;
X }
X if (mster==BAT) dam=1;
X else
X {
X dam = monster[mster].damage;
X dam += rnd((int)((dam<1)?1:dam)) + monster[mster].level;
X }
X tmp = 0;
X if (monster[mster].attack>0)
X if (((dam + bias + 8) > c[AC]) || (rnd((int)((c[AC]>0)?c[AC]:1))==1))
X { if (spattack(monster[mster].attack,x,y)) { flushall(); return; }
X tmp = 1; bias -= 2; cursors(); }
X if (((dam + bias) > c[AC]) || (rnd((int)((c[AC]>0)?c[AC]:1))==1))
X {
X lprintf("\n The %s hit you ",lastmonst); tmp = 1;
X if ((dam -= c[AC]) < 0) dam=0;
X if (dam > 0) { losehp(dam); bottomhp(); flushall(); }
X }
X if (tmp == 0) lprintf("\n The %s missed ",lastmonst);
X }
X
X/*
X * dropsomething(monst) Function to create an object when a monster dies
X * int monst;
X *
X * Function to create an object near the player when certain monsters are killed
X * Enter with the monster number
X * Returns nothing of value.
X */
Xstatic dropsomething(monst)
X int monst;
X {
X switch(monst)
X {
X case ORC: case NYMPH: case ELF: case TROGLODYTE:
X case TROLL: case ROTHE: case VIOLETFUNGI:
X case PLATINUMDRAGON: case GNOMEKING: case REDDRAGON:
X something(level); return;
X
X case LEPRECHAUN: if (rnd(101)>=75) creategem();
X if (rnd(5)==1) dropsomething(LEPRECHAUN); return;
X }
X }
X
X/*
X * dropgold(amount) Function to drop some gold around player
X * int amount;
X *
X * Enter with the number of gold pieces to drop
X * Returns nothing of value.
X */
Xdropgold(amount)
X register int amount;
X {
X if (amount > 250) createitem(OMAXGOLD,amount/100); else createitem(OGOLDPILE,amount);
X }
X
X/*
X * something(level) Function to create a random item around player
X * int level;
X *
X * Function to create an item from a designed probability around player
X * Enter with the cave level on which something is to be dropped
X * Returns nothing of value.
X */
Xsomething(level)
X int level;
X {
X register int j;
X int i;
X if (level<0 || level>MAXLEVEL+MAXVLEVEL) return; /* correct level? */
X if (rnd(101)<8) something(level); /* possibly more than one item */
X j = newobject(level,&i); createitem(j,i);
X }
X
X/*
X * newobject(lev,i) Routine to return a randomly selected new object
X * int lev,*i;
X *
X * Routine to return a randomly selected object to be created
X * Returns the object number created, and sets *i for its argument
X * Enter with the cave level and a pointer to the items arg
X */
Xstatic char nobjtab[] = { 0, OSCROLL, OSCROLL, OSCROLL, OSCROLL, OPOTION,
X OPOTION, OPOTION, OPOTION, OGOLDPILE, OGOLDPILE, OGOLDPILE, OGOLDPILE,
X OBOOK, OBOOK, OBOOK, OBOOK, ODAGGER, ODAGGER, ODAGGER, OLEATHER, OLEATHER,
X OLEATHER, OREGENRING, OPROTRING, OENERGYRING, ODEXRING, OSTRRING, OSPEAR,
X OBELT, ORING, OSTUDLEATHER, OSHIELD, OFLAIL, OCHAIN, O2SWORD, OPLATE,
X OLONGSWORD };
X
Xnewobject(lev,i)
X register int lev,*i;
X {
X register int tmp=32,j;
X if (level<0 || level>MAXLEVEL+MAXVLEVEL) return(0); /* correct level? */
X if (lev>6) tmp=37; else if (lev>4) tmp=35;
X j = nobjtab[tmp=rnd(tmp)]; /* the object type */
X switch(tmp)
X {
X case 1: case 2: case 3: case 4: *i=newscroll(); break;
X case 5: case 6: case 7: case 8: *i=newpotion(); break;
X case 9: case 10: case 11: case 12: *i=rnd((lev+1)*10)+lev*10+10; break;
X case 13: case 14: case 15: case 16: *i=lev; break;
X case 17: case 18: case 19: if (!(*i=newdagger())) return(0); break;
X case 20: case 21: case 22: if (!(*i=newleather())) return(0); break;
X case 23: case 32: case 35: *i=rund(lev/3+1); break;
X case 24: case 26: *i=rnd(lev/4+1); break;
X case 25: *i=rund(lev/4+1); break;
X case 27: *i=rnd(lev/2+1); break;
X case 30: case 33: *i=rund(lev/2+1); break;
X case 28: *i=rund(lev/3+1); if (*i==0) return(0); break;
X case 29: case 31: *i=rund(lev/2+1); if (*i==0) return(0); break;
X case 34: *i=newchain(); break;
X case 36: *i=newplate(); break;
X case 37: *i=newsword(); break;
X }
X return(j);
X }
X
X/*
X * spattack(atckno,xx,yy) Function to process special attacks from monsters
X * int atckno,xx,yy;
X *
X * Enter with the special attack number, and the coordinates (xx,yy)
X * of the monster that is special attacking
X * Returns 1 if must do a show1cell(xx,yy) upon return, 0 otherwise
X *
X * atckno monster effect
X * ---------------------------------------------------
X * 0 none
X * 1 rust monster eat armor
X * 2 hell hound breathe light fire
X * 3 dragon breathe fire
X * 4 giant centipede weakening sing
X * 5 white dragon cold breath
X * 6 wraith drain level
X * 7 waterlord water gusher
X * 8 leprechaun steal gold
X * 9 disenchantress disenchant weapon or armor
X * 10 ice lizard hits with barbed tail
X * 11 umber hulk confusion
X * 12 spirit naga cast spells taken from special attacks
X * 13 platinum dragon psionics
X * 14 nymph steal objects
X * 15 bugbear bite
X * 16 osequip bite
X *
X * char rustarm[ARMORTYPES][2];
X * special array for maximum rust damage to armor from rustmonster
X * format is: { armor type , minimum attribute
X */
X#define ARMORTYPES 6
Xstatic char rustarm[ARMORTYPES][2] = { OSTUDLEATHER,-2, ORING,-4, OCHAIN,-5,
X OSPLINT,-6, OPLATE,-8, OPLATEARMOR,-9 };
Xstatic char spsel[] = { 1, 2, 3, 5, 6, 8, 9, 11, 13, 14 };
Xstatic spattack(x,xx,yy)
X int x,xx,yy;
X {
X extern char lastmonst[] ;
X register int i,j=0,k,m;
X register char *p=0;
X if (c[CANCELLATION]) return(0);
X vxy(&xx,&yy); /* verify x & y coordinates */
X switch(x)
X {
X case 1: /* rust your armor, j=1 when rusting has occurred */
X m = k = c[WEAR];
X if ((i=c[SHIELD]) != -1)
X if (--ivenarg[i] < -1) ivenarg[i]= -1; else j=1;
X if ((j==0) && (k != -1))
X {
X m = iven[k];
X for (i=0; i<ARMORTYPES; i++)
X if (m == rustarm[i][0]) /* find his armor in table */
X {
X if (--ivenarg[k]< rustarm[i][1])
X ivenarg[k]= rustarm[i][1]; else j=1;
X break;
X }
X }
X if (j==0) /* if rusting did not occur */
X switch(m)
X {
X case OLEATHER: p = "\nThe %s hit you -- Your lucky you have leather on";
X break;
X case OSSPLATE: p = "\nThe %s hit you -- Your fortunate to have stainless steel armor!";
X break;
X }
X else { beep(); p = "\nThe %s hit you -- your armor feels weaker"; }
X break;
X
X case 2: i = rnd(15)+8-c[AC];
X spout: p="\nThe %s breathes fire at you!";
X if (c[FIRERESISTANCE])
X p="\nThe %s's flame doesn't phase you!";
X else
X spout2: if (p) { lprintf(p,lastmonst); beep(); }
X checkloss(i);
X return(0);
X
X case 3: i = rnd(20)+25-c[AC]; goto spout;
X
X case 4: if (c[STRENGTH]>3)
X {
X p="\nThe %s stung you! You feel weaker"; beep();
X --c[STRENGTH];
X }
X else p="\nThe %s stung you!";
X break;
X
X case 5: p="\nThe %s blasts you with his cold breath";
X i = rnd(15)+18-c[AC]; goto spout2;
X
X case 6: lprintf("\nThe %s drains you of your life energy!",lastmonst);
X loselevel(); beep(); return(0);
X
X case 7: p="\nThe %s got you with a gusher!";
X i = rnd(15)+25-c[AC]; goto spout2;
X
X case 8: if (c[NOTHEFT]) return(0); /* he has a device of no theft */
X if (c[GOLD])
X {
X p="\nThe %s hit you -- Your purse feels lighter";
X if (c[GOLD]>32767) c[GOLD]>>=1;
X else c[GOLD] -= rnd((int)(1+(c[GOLD]>>1)));
X if (c[GOLD] < 0) c[GOLD]=0;
X }
X else p="\nThe %s couldn't find any gold to steal";
X lprintf(p,lastmonst); disappear(xx,yy); beep();
X bottomgold(); return(1);
X
X case 9: for(j=50; ; ) /* disenchant */
X {
X i=rund(26); m=iven[i]; /* randomly select item */
X if (m>0 && ivenarg[i]>0 && m!=OSCROLL && m!=OPOTION)
X {
X if ((ivenarg[i] -= 3)<0) ivenarg[i]=0;
X lprintf("\nThe %s hits you -- you feel a sense of loss",lastmonst);
X srcount=0; beep(); show3(i); bottomline(); return(0);
X }
X if (--j<=0)
X {
X p="\nThe %s nearly misses"; break;
X }
X break;
X }
X break;
X
X case 10: p="\nThe %s hit you with his barbed tail";
X i = rnd(25)-c[AC]; goto spout2;
X
X case 11: p="\nThe %s has confused you"; beep();
X c[CONFUSE]+= 10+rnd(10); break;
X
X case 12: /* performs any number of other special attacks */
X return(spattack(spsel[rund(10)],xx,yy));
X
X case 13: p="\nThe %s flattens you with his psionics!";
X i = rnd(15)+30-c[AC]; goto spout2;
X
X case 14: if (c[NOTHEFT]) return(0); /* he has device of no theft */
X if (emptyhanded()==1)
X {
X p="\nThe %s couldn't find anything to steal";
X break;
X }
X lprintf("\nThe %s picks your pocket and takes:",lastmonst);
X beep();
X if (stealsomething()==0) lprcat(" nothing"); disappear(xx,yy);
X bottomline(); return(1);
X
X case 15: i= rnd(10)+ 5-c[AC];
X spout3: p="\nThe %s bit you!";
X goto spout2;
X
X case 16: i= rnd(15)+10-c[AC]; goto spout3;
X };
X if (p) { lprintf(p,lastmonst); bottomline(); }
X return(0);
X }
X
X/*
X * checkloss(x) Routine to subtract hp from user and flag bottomline display
X * int x;
X *
X * Routine to subtract hitpoints from the user and flag the bottomline display
X * Enter with the number of hit points to lose
X * Note: if x > c[HP] this routine could kill the player!
X */
Xcheckloss(x)
X int x;
X {
X if (x>0) { losehp(x); bottomhp(); }
X }
END_OF_FILE
if test 21846 -ne `wc -c <'monster.c'`; then
echo shar: \"'monster.c'\" unpacked with wrong size!
fi
# end of 'monster.c'
fi
if test -f 'object.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'object.c'\"
else
echo shar: Extracting \"'object.c'\" \(28660 characters\)
sed "s/^X//" >'object.c' <<'END_OF_FILE'
X/* object.c Larn is copyrighted 1986 by Noah Morgan. */
X#include "header.h"
X#define min(x,y) (((x)>(y))?(y):(x))
X#define max(x,y) (((x)>(y))?(x):(y))
X
X/*
X ***************
X LOOK_FOR_OBJECT
X ***************
X
X subroutine to look for an object and give the player his options
X if an object was found.
X */
Xlookforobject(do_ident, do_pickup, do_action)
X char do_ident; /* identify item: T/F */
X char do_pickup; /* pickup item: T/F */
X char do_action; /* prompt for actions on object: T/F */
X {
X register int i,j;
X
X /* can't find objects if time is stopped */
X if (c[TIMESTOP])
X return;
X i=item[playerx][playery]; if (i==0) return;
X j=iarg[playerx][playery];
X showcell(playerx,playery); cursors(); yrepcount=0;
X switch(i)
X {
X case OGOLDPILE: case OMAXGOLD:
X case OKGOLD: case ODGOLD:
X lprcat("\n\nYou have found some gold!");
X ogold(i);
X break;
X
X case OPOTION:
X if (do_ident)
X {
X lprcat("\n\nYou have found a magic potion");
X if (potionname[j][0])
X lprintf(" of %s",&potionname[j][1]);
X }
X if (do_pickup)
X if (take(OPOTION, j) == 0)
X forget();
X if (do_action)
X opotion(j);
X break;
X
X case OSCROLL:
X if (do_ident)
X {
X lprcat("\n\nYou have found a magic scroll");
X if (scrollname[j][0])
X lprintf(" of %s",&scrollname[j][1]);
X }
X if (do_pickup)
X if (take(OSCROLL, j) == 0)
X forget();
X if (do_action)
X oscroll(j);
X break;
X
X case OALTAR:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nThere is a Holy Altar here!");
X if (do_action)
X oaltar();
X break;
X
X case OBOOK:
X if (do_ident)
X lprcat("\n\nYou have found a book.");
X if (do_pickup)
X if (take(OBOOK, j) == 0)
X forget();
X if (do_action)
X obook();
X break;
X
X case OCOOKIE:
X if (do_ident)
X lprcat("\n\nYou have found a fortune cookie.");
X if (do_pickup)
X if (take(OCOOKIE, 0)==0)
X forget();
X if (do_action)
X ocookie();
X break;
X
X case OTHRONE:
X if (nearbymonst())
X return;
X if (do_ident)
X lprintf("\n\nThere is %s here!",objectname[i]);
X if (do_action)
X othrone(0);
X break;
X
X case OTHRONE2:
X if (nearbymonst())
X return;
X if (do_ident)
X lprintf("\n\nThere is %s here!",objectname[i]);
X if (do_action)
X othrone(1);
X break;
X
X case ODEADTHRONE:
X if (do_ident)
X lprintf("\n\nThere is %s here!",objectname[i]);
X if (do_action)
X odeadthrone();
X break;
X
X case OORB:
X lprcat("\n\nYou have found the Orb!!!!!");
X oorb();
X break;
X
X case OPIT:
X /* always perform these actions. */
X lprcat("\n\nYou're standing at the top of a pit.");
X opit();
X break;
X
X case OSTAIRSUP: /* up */
X if (do_ident)
X lprcat("\n\nThere is a circular staircase here");
X if (do_action)
X ostairs(1);
X break;
X
X case OELEVATORUP:
X lprcat("\n\nYou feel heavy for a moment, but the feeling disappears");
X oelevator(1); /* up */
X break;
X
X case OFOUNTAIN:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nThere is a fountain here");
X if (do_action)
X ofountain();
X break;
X
X case OSTATUE:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nYou are standing in front of a statue");
X if (do_action)
X ostatue();
X break;
X
X case OCHEST:
X if (do_ident)
X lprcat("\n\nThere is a chest here");
X if (do_pickup)
X if (take(OCHEST,j)==0)
X forget();
X if (do_action)
X ochest();
X break;
X
X case OSCHOOL:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nYou have found the College of Larn.");
X if (do_action)
X prompt_enter();
X break;
X
X case OMIRROR:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nThere is a mirror here");
X if (do_action)
X omirror();
X break;
X
X case OBANK2:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nYou have found a branch office of the bank of Larn.");
X if (do_action)
X prompt_enter();
X break ;
X
X case OBANK:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nYou have found the bank of Larn.");
X if (do_action)
X prompt_enter();
X break;
X
X case ODEADFOUNTAIN:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nThere is a dead fountain here");
X break;
X
X case ODNDSTORE:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nThere is a DND store here.");
X if (do_action)
X prompt_enter();
X break;
X
X case OSTAIRSDOWN: /* down */
X if (do_ident)
X lprcat("\n\nThere is a circular staircase here");
X if (do_action)
X ostairs(-1);
X break;
X
X case OELEVATORDOWN:
X lprcat("\n\nYou feel light for a moment, but the feeling disappears");
X oelevator(-1); /* down */
X break;
X
X case OOPENDOOR:
X if (do_ident)
X lprintf("\n\nYou have found %s",objectname[i]);
X if (do_action)
X o_open_door();
X break;
X
X case OCLOSEDDOOR:
X if (do_ident)
X lprintf("\n\nYou have found %s",objectname[i]);
X if (do_action)
X o_closed_door();
X break;
X
X case OENTRANCE:
X if (do_ident)
X lprcat("\nYou have found "); lprcat(objectname[i]);
X if (do_action)
X prompt_enter();
X break;
X
X case OVOLDOWN:
X if (do_ident)
X lprcat("\nYou have found "); lprcat(objectname[i]);
X if (do_action)
X prompt_volshaft(-1);
X break;
X
X case OVOLUP:
X if (do_ident)
X lprcat("\nYou have found "); lprcat(objectname[i]);
X if (do_action)
X prompt_volshaft(1);
X break;
X
X case OIVTELETRAP:
X if (rnd(11)<6)
X return;
X item[playerx][playery] = OTELEPORTER;
X know[playerx][playery] = KNOWALL;
X /* fall through to OTELEPORTER case below!!!*/
X
X case OTELEPORTER:
X lprcat("\nZaaaappp! You've been teleported!\n");
X beep(); nap(3000); oteleport(0);
X break;
X
X case OTRAPARROWIV: /* for an arrow trap */
X if (rnd(17)<13)
X return;
X item[playerx][playery] = OTRAPARROW;
X know[playerx][playery] = 0;
X /* fall through to OTRAPARROW case below!!!*/
X
X case OTRAPARROW:
X lprcat("\nYou are hit by an arrow"); beep();
X lastnum=259; losehp(rnd(10)+level);
X bottomhp(); return;
X
X case OIVDARTRAP: /* for a dart trap */
X if (rnd(17)<13)
X return;
X item[playerx][playery] = ODARTRAP;
X know[playerx][playery] = 0;
X /* fall through to ODARTTRAP case below!!!*/
X
X case ODARTRAP:
X lprcat("\nYou are hit by a dart"); beep(); /* for a dart trap */
X lastnum=260; losehp(rnd(5));
X if ((--c[STRENGTH]) < 3) c[STRENGTH] = 3;
X bottomline(); return;
X
X case OIVTRAPDOOR: /* for a trap door */
X if (rnd(17)<13)
X return;
X item[playerx][playery] = OTRAPDOOR;
X know[playerx][playery] = KNOWALL;
X /* fall through to OTRAPDOOR case below!!!*/
X
X case OTRAPDOOR:
X lastnum = 272; /* a trap door */
X if ((level==MAXLEVEL-1) || (level==MAXLEVEL+MAXVLEVEL-1))
X {
X lprcat("\nYou fell through a bottomless trap door!");
X beep();
X nap(3000);
X died(271);
X }
X i = rnd( 5 + level );
X lprintf("\nYou fall through a trap door! You lose %d hit points.", (long)i);
X beep(); losehp(i); nap(2000);
X newcavelevel(level+1); draws(0,MAXX,0,MAXY); bot_linex();
X return;
X
X case OTRADEPOST:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\nYou have found the Larn trading Post.");
X if (do_action)
X prompt_enter();
X return;
X
X case OHOME:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\nYou have found your way home.");
X if (do_action)
X prompt_enter();
X return;
X
X case OWALL:
X break;
X
X case OANNIHILATION:
X died(283); /* annihilated by sphere of annihilation */
X return;
X
X case OLRS:
X if (nearbymonst())
X return;
X if (do_ident)
X lprcat("\n\nThere is an LRS office here.");
X if (do_action)
X prompt_enter();
X break;
X
X default:
X if (do_ident)
X {
X lprintf("\n\nYou have found %s ",objectname[i]);
X switch(i)
X {
X case ODIAMOND: case ORUBY: case OEMERALD:
X case OSAPPHIRE: case OSPIRITSCARAB: case OORBOFDRAGON:
X case OCUBEofUNDEAD: case ONOTHEFT:
X break;
X
X default:
X if (j>0)
X lprintf("+ %d",(long)j);
X else if (j<0)
X lprintf(" %d",(long)j);
X break;
X }
X }
X if (do_pickup)
X if (take(i,j) == 0)
X forget();
X if (do_action)
X {
X char tempc = 0;
X
X lprcat("\nDo you want to (t) take it"); iopts();
X while (tempc!='t' && tempc!='i' && tempc!='\33')
X tempc=ttgetch();
X if (tempc == 't')
X {
X lprcat("take"); if (take(i,j)==0) forget();
X return;
X }
X ignore();
X }
X break;
X };
X }
X
X/*
X subroutine to process the stair cases
X if dir > 0 the up else down
X*/
Xostairs(dir)
X int dir;
X {
X register int k;
X lprcat("\nDo you (s) stay here ");
X if (dir > 0) lprcat("(u) go up "); else lprcat("(d) go down ");
X lprcat("or (f) kick stairs? ");
X
X while (1) switch(ttgetch())
X {
X case '\33':
X case 's': case 'i': lprcat("stay here"); return;
X
X case 'f':
X lprcat("kick stairs");
X act_kick_stairs();
X return;
X
X case 'u':
X lprcat("go up");
X act_up_stairs();
X return;
X
X case 'd':
X lprcat("go down");
X act_down_stairs();
X return;
X };
X }
X
X
X/*
X subroutine to handle a teleport trap +/- 1 level maximum
X*/
Xoteleport(err)
X int err;
X {
X register int tmp;
X if (err) if (rnd(151)<3) died(264); /* stuck in a rock */
X c[TELEFLAG]=1; /* show ?? on bottomline if been teleported */
X if (level==0) tmp=0;
X else if (level < MAXLEVEL)
X { tmp=rnd(5)+level-3; if (tmp>=MAXLEVEL) tmp=MAXLEVEL-1;
X if (tmp<1) tmp=1; }
X else
X { tmp=rnd(3)+level-2; if (tmp>=MAXLEVEL+MAXVLEVEL) tmp=MAXLEVEL+MAXVLEVEL-1;
X if (tmp<MAXLEVEL) tmp=MAXLEVEL; }
X playerx = rnd(MAXX-2); playery = rnd(MAXY-2);
X if (level != tmp) newcavelevel(tmp); positionplayer();
X draws(0,MAXX,0,MAXY); bot_linex();
X }
X
X/*
X function to process a potion
X*/
Xopotion(pot)
X int pot;
X {
X lprcat("\nDo you (d) drink it, (t) take it"); iopts();
X while (1) switch(ttgetch())
X {
X case '\33':
X case 'i': ignore(); return;
X
X case 'd': lprcat("drink\n"); forget(); /* destroy potion */
X quaffpotion(pot,TRUE); return;
X
X case 't': lprcat("take\n"); if (take(OPOTION,pot)==0) forget();
X return;
X };
X }
X
X/*
X function to drink a potion
X
X Also used to perform the action of a potion without quaffing a potion
X (see invisible capability when drinking from a fountain).
X*/
Xquaffpotion(pot,set_known)
X int pot;
X int set_known;
X {
X register int i,j,k;
X
X /* check for within bounds */
X if (pot<0 || pot>=MAXPOTION)
X return;
X
X /* if player is to know this potion (really quaffing one), make it known */
X if (set_known)
X potionname[pot][0] = ' ';
X
X switch(pot)
X {
X case 9: lprcat("\nYou feel greedy . . ."); nap(1000);
X if (c[BLINDCOUNT])
X return;
X for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++)
X if ((item[j][i]==OGOLDPILE) || (item[j][i]==OMAXGOLD))
X {
X know[j][i]=1; show1cell(j,i);
X }
X showplayer(); return;
X
X case 19: lprcat("\nYou feel greedy . . ."); nap(1000);
X if (c[BLINDCOUNT])
X return;
X for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++)
X {
X k=item[j][i];
X if ((k==ODIAMOND) || (k==ORUBY) || (k==OEMERALD) || (k==OMAXGOLD)
X || (k==OSAPPHIRE) || (k==OLARNEYE) || (k==OGOLDPILE))
X {
X know[j][i]=1; show1cell(j,i);
X }
X }
X showplayer(); return;
X
X case 20: c[HP] = c[HPMAX]; break; /* instant healing */
X
X case 1: lprcat("\nYou feel better");
X if (c[HP] == c[HPMAX]) raisemhp(1);
X else if ((c[HP] += rnd(20)+20+c[LEVEL]) > c[HPMAX]) c[HP]=c[HPMAX]; break;
X
X case 2: lprcat("\nSuddenly, you feel much more skillful!");
X raiselevel(); raisemhp(1); return;
X
X case 3: lprcat("\nYou feel strange for a moment");
X c[rund(6)]++; break;
X
X case 4: lprcat("\nYou feel more self confident!");
X c[WISDOM] += rnd(2); break;
X
X case 5: lprcat("\nWow! You feel great!");
X if (c[STRENGTH]<12) c[STRENGTH]=12; else c[STRENGTH]++; break;
X
X case 6: lprcat("\nYour charm went up by one!"); c[CHARISMA]++; break;
X
X case 8: lprcat("\nYour intelligence went up by one!");
X c[INTELLIGENCE]++; break;
X
X case 10: /* monster detection */
X lprcat("\nYou detect the presence of monsters!");
X nap(1000);
X if (c[BLINDCOUNT])
X return;
X for (i=0; i<MAXY; i++)
X for (j=0; j<MAXX; j++)
X if (mitem[j][i] && (monstnamelist[mitem[j][i]] != floorc))
X {
X know[j][i]=1;
X show1cell(j,i);
X }
X return;
X
X case 12: lprcat("\nThis potion has no taste to it"); return;
X
X case 15: lprcat("\nWOW!!! You feel Super-fantastic!!!");
X if (c[HERO]==0) for (i=0; i<6; i++) c[i] += 11;
X c[HERO] += 250; break;
X
X case 16: lprcat("\nYou have a greater intestinal constitude!");
X c[CONSTITUTION]++; break;
X
X case 17: lprcat("\nYou now have incredibly bulging muscles!!!");
X if (c[GIANTSTR]==0) c[STREXTRA] += 21;
X c[GIANTSTR] += 700; break;
X
X case 18: lprcat("\nYou feel a chill run up your spine!");
X c[FIRERESISTANCE] += 1000; break;
X
X case 0: lprcat("\nYou fall asleep. . .");
X i=rnd(11)-(c[CONSTITUTION]>>2)+2; while(--i>0) { parse2(); nap(1000); }
X cursors(); lprcat("\nYou woke up!"); return;
X
X case 7: lprcat("\nYou become dizzy!");
X if (--c[STRENGTH] < 3) c[STRENGTH]=3; break;
X
X case 11: lprcat("\nYou stagger for a moment . .");
X for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++)
X know[j][i]=0;
X nap(2000); draws(0,MAXX,0,MAXY); /* potion of forgetfulness */ return;
X
X case 13: lprcat("\nYou can't see anything!"); /* blindness */
X c[BLINDCOUNT]+=500; return;
X
X case 14: lprcat("\nYou feel confused"); c[CONFUSE]+= 20+rnd(9); return;
X
X case 21: lprcat("\nYou don't seem to be affected"); return; /* cure dianthroritis */
X
X case 22: lprcat("\nYou feel a sickness engulf you"); /* poison */
X c[HALFDAM] += 200 + rnd(200); return;
X
X case 23: lprcat("\nYou feel your vision sharpen"); /* see invisible */
X c[SEEINVISIBLE] += rnd(1000)+400;
X monstnamelist[INVISIBLESTALKER] = 'I'; return;
X };
X bottomline(); /* show new stats */ return;
X }
X
X/*
X function to process a magic scroll
X*/
Xoscroll(typ)
X int typ;
X {
X lprcat("\nDo you ");
X if (c[BLINDCOUNT]==0) lprcat("(r) read it, "); lprcat("(t) take it"); iopts();
X while (1) switch(ttgetch())
X {
X case '\33':
X case 'i': ignore(); return;
X
X case 'r': if (c[BLINDCOUNT]) break;
X lprcat("read"); forget();
X if (typ==2 || typ==15) { show1cell(playerx,playery); cursors(); }
X /* destroy it */ read_scroll(typ); return;
X
X case 't': lprcat("take"); if (take(OSCROLL,typ)==0) forget(); /* destroy it */
X return;
X };
X }
X
X/*
X data for the function to read a scroll
X*/
Xstatic int xh,yh,yl,xl;
Xstatic char curse[] = { BLINDCOUNT, CONFUSE, AGGRAVATE, HASTEMONST, ITCHING,
X LAUGHING, DRAINSTRENGTH, CLUMSINESS, INFEEBLEMENT, HALFDAM };
Xstatic char exten[] = { PROTECTIONTIME, DEXCOUNT, STRCOUNT, CHARMCOUNT,
X INVISIBILITY, CANCELLATION, HASTESELF, GLOBE, SCAREMONST, HOLDMONST, TIMESTOP };
Xchar time_change[] = { HASTESELF,HERO,ALTPRO,PROTECTIONTIME,DEXCOUNT,
X STRCOUNT,GIANTSTR,CHARMCOUNT,INVISIBILITY,CANCELLATION,
X HASTESELF,AGGRAVATE,SCAREMONST,STEALTH,AWARENESS,HOLDMONST,HASTEMONST,
X FIRERESISTANCE,GLOBE,SPIRITPRO,UNDEADPRO,HALFDAM,SEEINVISIBLE,
X ITCHING,CLUMSINESS, WTW };
X/*
X function to adjust time when time warping and taking courses in school
X*/
Xadjtime(tim)
X register long tim;
X {
X register int j;
X for (j=0; j<26; j++) /* adjust time related parameters */
X if (c[time_change[j]])
X if ((c[time_change[j]] -= tim) < 1) c[time_change[j]]=1;
X regen();
X }
X
X/*
X function to read a scroll
X*/
Xread_scroll(typ)
X int typ;
X {
X register int i,j;
X if (typ<0 || typ>=MAXSCROLL) return; /* be sure we are within bounds */
X scrollname[typ][0] = ' ';
X switch(typ)
X {
X case 0: lprcat("\nYour armor glows for a moment"); enchantarmor(); return;
X
X case 1: lprcat("\nYour weapon glows for a moment"); enchweapon(); return; /* enchant weapon */
X
X case 2: lprcat("\nYou have been granted enlightenment!");
X yh = min(playery+7,MAXY); xh = min(playerx+25,MAXX);
X yl = max(playery-7,0); xl = max(playerx-25,0);
X for (i=yl; i<yh; i++)
X for (j=xl; j<xh; j++)
X know[j][i]=KNOWALL;
X nap(2000); draws(xl,xh,yl,yh); return;
X
X case 3: lprcat("\nThis scroll seems to be blank"); return;
X
X case 4: createmonster(makemonst(level+1)); return; /* this one creates a monster */
X
X case 5: something(level); /* create artifact */ return;
X
X case 6: c[AGGRAVATE]+=800; return; /* aggravate monsters */
X
X case 7: gtime += (i = rnd(1000) - 850); /* time warp */
X if (i>=0) lprintf("\nYou went forward in time by %d mobuls",(long)((i+99)/100));
X else lprintf("\nYou went backward in time by %d mobuls",(long)(-(i+99)/100));
X adjtime((long)i); /* adjust time for time warping */
X return;
X
X case 8: oteleport(0); return; /* teleportation */
X
X case 9: c[AWARENESS] += 1800; return; /* expanded awareness */
X
X case 10: c[HASTEMONST] += rnd(55)+12; return; /* haste monster */
X
X case 11: for (i=0; i<MAXY; i++) for (j=0; j<MAXX; j++)
X if (mitem[j][i])
X hitp[j][i] = monster[mitem[j][i]].hitpoints;
X return; /* monster healing */
X case 12: c[SPIRITPRO] += 300 + rnd(200); bottomline(); return; /* spirit protection */
X
X case 13: c[UNDEADPRO] += 300 + rnd(200); bottomline(); return; /* undead protection */
X
X case 14: c[STEALTH] += 250 + rnd(250); bottomline(); return; /* stealth */
X
X case 15: lprcat("\nYou have been granted enlightenment!"); /* magic mapping */
X for (i=0; i<MAXY; i++)
X for (j=0; j<MAXX; j++)
X know[j][i]=KNOWALL;
X nap(2000); draws(0,MAXX,0,MAXY); return;
X
X case 16: c[HOLDMONST] += 30; bottomline(); return; /* hold monster */
X
X case 17: for (i=0; i<26; i++) /* gem perfection */
X switch(iven[i])
X {
X case ODIAMOND: case ORUBY:
X case OEMERALD: case OSAPPHIRE:
X j = ivenarg[i]; j &= 255; j <<= 1;
X if (j > 255) j=255; /* double value */
X ivenarg[i] = j; break;
X }
X break;
X
X case 18: for (i=0; i<11; i++) c[exten[i]] <<= 1; /* spell extension */
X break;
X
X case 19: for (i=0; i<26; i++) /* identify */
X {
X if (iven[i]==OPOTION) potionname[ivenarg[i]][0] = ' ';
X if (iven[i]==OSCROLL) scrollname[ivenarg[i]][0] = ' ';
X }
X break;
X
X case 20: for (i=0; i<10; i++) /* remove curse */
X if (c[curse[i]]) c[curse[i]] = 1;
X break;
X
X case 21: annihilate(); break; /* scroll of annihilation */
X
X case 22: godirect(22,150,"The ray hits the %s",0,' '); /* pulverization */
X break;
X case 23: c[LIFEPROT]++; break; /* life protection */
X };
X }
X
X
Xoorb()
X {
X }
X
Xopit()
X {
X register int i;
X if (rnd(101)<81)
X if (rnd(70) > 9*c[DEXTERITY]-packweight() || rnd(101)<5)
X if (level==MAXLEVEL-1) obottomless(); else
X if (level==MAXLEVEL+MAXVLEVEL-1) obottomless(); else
X {
X if (rnd(101)<20)
X {
X i=0; lprcat("\nYou fell into a pit! Your fall is cushioned by an unknown force\n");
X }
X else
X {
X i = rnd(level*3+3);
X lprintf("\nYou fell into a pit! You suffer %d hit points damage",(long)i);
X lastnum=261; /* if he dies scoreboard will say so */
X }
X losehp(i); nap(2000); newcavelevel(level+1); draws(0,MAXX,0,MAXY);
X }
X }
X
Xobottomless()
X {
X lprcat("\nYou fell into a bottomless pit!"); beep(); nap(3000); died(262);
X }
Xoelevator(dir)
X int dir;
X {
X#ifdef lint
X int x;
X x=dir;
X dir=x;
X#endif lint
X }
X
Xostatue()
X {
X }
X
Xomirror()
X {
X }
X
Xobook()
X {
X lprcat("\nDo you ");
X if (c[BLINDCOUNT]==0) lprcat("(r) read it, "); lprcat("(t) take it"); iopts();
X while (1) switch(ttgetch())
X {
X case '\33':
X case 'i': ignore(); return;
X
X case 'r': if (c[BLINDCOUNT]) break;
X lprcat("read");
X /* no more book */ readbook(iarg[playerx][playery]); forget(); return;
X
X case 't': lprcat("take"); if (take(OBOOK,iarg[playerx][playery])==0) forget(); /* no more book */
X return;
X };
X }
X
X/*
X function to read a book
X*/
Xreadbook(lev)
X register int lev;
X {
X register int i,tmp;
X if (lev<=3) i = rund((tmp=splev[lev])?tmp:1); else
X i = rnd((tmp=splev[lev]-9)?tmp:1) + 9;
X spelknow[i]=1;
X lprintf("\nSpell \"%s\": %s\n%s",spelcode[i],spelname[i],speldescript[i]);
X if (rnd(10)==4)
X { lprcat("\nYour int went up by one!"); c[INTELLIGENCE]++; bottomline(); }
X }
X
Xocookie()
X {
X char *p;
X lprcat("\nDo you (e) eat it, (t) take it"); iopts();
X while (1) switch(ttgetch())
X {
X case '\33':
X case 'i': ignore(); return;
X
X case 'e': lprcat("eat\nThe cookie tasted good.");
X forget(); /* no more cookie */
X if (c[BLINDCOUNT]) return;
X# ifdef MSDOS
X outfortune();
X# else
X if (!(p=fortune(fortfile))) return;
X lprcat(" A message inside the cookie reads:\n"); lprcat(p);
X# endif
X return;
X
X case 't': lprcat("take"); if (take(OCOOKIE,0)==0) forget(); /* no more book */
X return;
X };
X }
X
X
X/*
X routine to pick up some gold -- if arg==OMAXGOLD then the pile is worth
X 100* the argument
X*/
Xogold(arg)
X int arg;
X {
X register long i;
X i = iarg[playerx][playery];
X if (arg==OMAXGOLD) i *= 100;
X else if (arg==OKGOLD) i *= 1000;
X else if (arg==ODGOLD) i *= 10;
X lprintf("\nIt is worth %d!",(long)i); c[GOLD] += i; bottomgold();
X item[playerx][playery] = know[playerx][playery] = 0; /* destroy gold */
X }
X
Xohome()
X {
X register int i;
X nosignal = 1; /* disable signals */
X for (i=0; i<26; i++) if (iven[i]==OPOTION) if (ivenarg[i]==21)
X {
X iven[i]=0; /* remove the potion of cure dianthroritis from inventory */
X clear(); lprcat("Congratulations. You found a potion of cure dianthroritis.\n");
X lprcat("\nFrankly, No one thought you could do it. Boy! Did you surprise them!\n");
X if (gtime>TIMELIMIT)
X {
X# ifdef MSDOS
X /* The original is a little too morbid for my taste.
X */
X lprcat("\nThe doctor has the sad duty to inform you that your daughter died");
X lprcat("\nbefore your return. There was nothing he could do without the potion.\n");
X# else
X lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
X lprcat("You didn't make it in time. In your agony, you kill the doctor,\nyour wife, and yourself! Too bad!\n");
X# endif
X nap(5000); died(269);
X }
X else
X {
X lprcat("\nThe doctor is now administering the potion, and in a few moments\n");
X lprcat("your daughter should be well on her way to recovery.\n");
X nap(6000);
X lprcat("\nThe potion is"); nap(3000); lprcat(" working! The doctor thinks that\n");
X lprcat("your daughter will recover in a few days. Congratulations!\n");
X beep(); nap(5000); died(263);
X }
X }
X
X while (1)
X {
X clear(); lprintf("Welcome home %s. Latest word from the doctor is not good.\n",logname);
X
X if (gtime>TIMELIMIT)
X {
X lprcat("\nThe doctor has the sad duty to inform you that your daughter died!\n");
X lprcat("You didn't make it in time. In your agony, you kill the doctor,\nyour wife, and yourself! Too bad!\n");
X nap(5000); died(269);
X }
X
X lprcat("\nThe diagnosis is confirmed as dianthroritis. He guesses that\n");
X lprintf("your daughter has only %d mobuls left in this world. It's up to you,\n",(long)((TIMELIMIT-gtime+99)/100));
X lprintf("%s, to find the only hope for your daughter, the very rare\n",logname);
X lprcat("potion of cure dianthroritis. It is rumored that only deep in the\n");
X lprcat("depths of the caves can this potion be found.\n\n\n");
X lprcat("\n ----- press "); standout("return");
X lprcat(" to continue, "); standout("escape");
X lprcat(" to leave ----- ");
X i=ttgetch(); while (i!='\33' && i!='\n') i=ttgetch();
X if (i=='\33') { drawscreen(); nosignal = 0; /* enable signals */ return; }
X }
X }
X
X/* routine to save program space */
Xiopts()
X { lprcat(", or (i) ignore it? "); }
Xignore()
X { lprcat("ignore\n"); }
X
X/*
X For prompt mode, prompt for entering a building.
X*/
Xprompt_enter()
X {
X char i ;
X
X lprcat("\nDo you (g) go inside, or (i) stay here? ");
X i=0;
X while ((i!='g') && (i!='i') && (i!='\33'))
X i=ttgetch();
X if (i == 'g')
X enter();
X else
X lprcat(" stay here");
X }
X
X/*
X For prompt mode, prompt for climbing up/down the volcanic shaft.
X
X Takes one parameter: if it is negative, going down the shaft,
X otherwise, going up the shaft.
X*/
Xprompt_volshaft(dir)
Xint dir;
X {
X char i ;
X
X lprcat("\nDo you (c) climb ");
X if (dir > 0)
X lprcat("up");
X else
X lprcat("down");
X iopts();
X
X i=0;
X while ((i!='c') && (i!='i') && (i!='\33'))
X i=ttgetch();
X
X if ((i=='\33') || (i=='i'))
X {
X ignore();
X return;
X }
X
X if (dir > 0)
X act_up_shaft();
X else
X act_down_shaft();
X }
X
Xo_open_door()
X {
X char i;
X lprcat("\nDo you (c) close it"); iopts();
X i=0; while ((i!='c') && (i!='i') && (i!='\33')) i=ttgetch();
X if ((i=='\33') || (i=='i'))
X {
X ignore();
X return;
X }
X lprcat("close"); forget();
X item[playerx][playery]=OCLOSEDDOOR;
X iarg[playerx][playery]=0;
X playerx = lastpx; playery = lastpy;
X }
X
Xo_closed_door()
X {
X char i;
X lprcat("\nDo you (o) try to open it"); iopts();
X i=0; while ((i!='o') && (i!='i') && (i!='\33')) i=ttgetch();
X if ((i=='\33') || (i=='i'))
X { ignore(); playerx = lastpx;
X playery = lastpy; return; }
X else
X {
X lprcat("open");
X /* if he failed to open the door ...
X */
X if ( !act_open_door( playerx, playery ) )
X {
X playerx = lastpx ;
X playery = lastpy ;
X }
X }
X }
END_OF_FILE
if test 28660 -ne `wc -c <'object.c'`; then
echo shar: \"'object.c'\" unpacked with wrong size!
fi
# end of 'object.c'
fi
if test -f 'termcap.pc' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'termcap.pc'\"
else
echo shar: Extracting \"'termcap.pc'\" \(439 characters\)
sed "s/^X//" >'termcap.pc' <<'END_OF_FILE'
X#
X# Monochrome IBMPC.
X# This is a termcap for the NANSI.SYS device driver.
X# It is the same as the ANSI termcap, except NANSI supports
X# line insert (al) and delete (dl) while ANSI does not.
X#
Xibmpc-mono:\
X :co#80:\
X :li#24:\
X :cl=\E[;H\E[2J:\
X :bs:\
X :ho=\E[H:\
X :cm=\E[%i%2;%2H:\
X :up=\E[A:\
X :xd=\E[B:\
X :nd=\E[C:\
X :bc=\E[D:\
X :ce=\E[K:\
X :ti=\E[m:\
X :te=\E[m:\
X :so=\E[1m:\
X :se=\E[m:\
X :us=\E[4m:\
X :ue=\E[m:\
X :al=\E[L:\
X :dl=\E[M:
END_OF_FILE
if test 439 -ne `wc -c <'termcap.pc'`; then
echo shar: \"'termcap.pc'\" unpacked with wrong size!
fi
# end of 'termcap.pc'
fi
echo shar: End of archive 4 \(of 11\).
cp /dev/null ark4isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 11 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0